Totally new to C++, so please forgive me...

I'm trying to have a user input a filename and then check the file for all string literals.

The output should return the string literal (not the whole line, which is what I am getting).

Also, I have to ensure it ignores comments that include quotations.

I've tried doing a: line.find("\""); to get the string literals but pulling my hair out over here!

HELP! Your expert guidance please!!

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main( int argc, char* argv[] ) {

	//Prompt to open file, loop until proper file is input...
	ifstream infile; 
	string filename;
	
	do {
		cout << "Enter file name:";
		cin >> filename;
		infile.open(filename.c_str());
			if (!infile) { 
				cerr << "Cannot open file: " << filename << "\n" << endl;
			}
			
	} while (!infile);

	
	string line;
	int counter = 0;


	
	while( getline(infile,line) ){  
		
		// Counter for line number(s)...
		++counter;
		

	

		// Check for string literal(s)... 
		std::string::size_type pos = line.find("\"");                 
		if(pos != std::string::npos){                         
			std::string sentence = line.substr(pos);                         
			
			// Print out filename, line number(s), and "string literal"
			cout << filename << " line # " << counter << ", "  << sentence << "\n";	
		}
	}


	infile.close();
    system("pause");
	return 0;

Recommended Answers

All 12 Replies

Can you give a typical line from the file?

Can you give a typical line from the file?

Yes, thanks for your help...


here is the sample input file (hello.cpp)

#include <iostream>

int main() {
	std::cout << "Hello world!\n" << std::endl;
	
	// "Have window stay open on viewing"
	char cChar;
	std::cin.get(cChar);
	/* "THIS IS A TEST COMMENT" */
	return 0;
}

You will need to either tokenize the lines and get rid of anything after // or between /* */
(You may be able to base what you do off of something like this: http://www.daniweb.com/code/snippet217441.html)

-or-
You can write a finite state machine similar to the ones that a compiler would use to detect and strip comments from a file (or even run your source file you are testing through the C++ preprocessor -- command varies from compiler to compiler -- to strip the comments before you run this program. I am not sure if that will preserve line numbers).

-or-
You can use a regex library (e.g. Boost Regex )and do something like this. Perhaps a bit of overkill but it's the same issue.

I wish I could have been of more help to you with an algorithm. I tried writing a bit of a finite state machine with just if statements but it got a bit cumbersome and I'm sure there are more efficient/faster ways of doing it.

Oh, c'mon, jonsca

You will need to either tokenize the lines and get rid of anything after // or between /* */

-or-
You can write a finite state machine similar to the ones that a compiler would use...

-or-
You can use a regex library...

He said

Totally new to C++, so please forgive me...

He can't even find a double quote in the line he's read, how is he going to add a regex library, or even know what a state machine is? I myself never heard of a state machine until my girlfriend was getting her masters.

Know your audience...

Sheesh! :icon_wink:

Oh, c'mon, jonsca

Know your audience..

Noted. I didn't come up with anything earth shatteringly simple, so sometimes you need an elephant gun as a fly swatter. ;)
Personally, I think the preprocessor idea is the least difficult of all but I didn't try it to see if the line numbers are preserved. That way you don't have to worry about the comments because they are gone.

All you have to do is find the ", and if found, find the next ". Copy the stuff in between. It's simple.

Tokenize... sheesh! :icon_wink:

This looks at lot like a template code that someone is asking you to modify without you having understood the parts.

I am not quite sure why you would want to output a double quote in real life as it is not a useful piece of information

but you want to show something

std::string str = "tetron";
cout << str;

This will output the word tetron
but you really want to add in an extra line and tell it to print at the
same time so you should use a special cout variable called endl;

There are a couple of points with the original code I am surprised
by there is a c-style main declaration reading in argv[] when you
don't need parameters and if you use endl; you can get rid of system.(pause);

#include <string> //words and sentences
#include <iosmtream> //cout & cin

void main()
{
//set the value of line as you initialise it
std::string line("I answered, \"no.\"  Now the nest sentence.");
char to_find = '"';
//we want a special int to avoid awarning but just like int pos;
std::string::size_type number_of_letter_in_line(0), pos(0); 

//you can cout a " by using << with to find
std::cout << to_find << std::endl;

//find() starts looking at a letter_number you give it 
line.find(to_find, pos); //starts looking at I
std::cout << "found " << to_find << " at " << pos << std::endl;
 //this will give you 0 if found which is wrong
pos = line.find(to_find, pos);
std::cout << "found " << to_find << " at " << pos << std::endl;
//now we have a new pos that is the location in the string
char quote = line[pos];
//to find the next quote you would need to advance pos

}

you should be able to use the rest of your code with this
the std:: are in place of using namespace std;

All you have to do is find the ", and if found, find the next ". Copy the stuff in between. It's simple.

Tokenize... sheesh! :icon_wink:

It's the fact that there may be string literals within the comments that he wants to ignore. /* "So if I"m parsing for quotes I'm gonna get this one" */ So you could just look for // and /* and lop off the rest of the line, but you'd miss something like "correctone" in function(/* "nevermind" */"correctone"), hence having to have some idea where your comments begin and end (enter the tokenizer).

If you were guaranteed there to be no string literals within the comments (my preprocessor idea) then it would be as simple as you propose!

1) check the file for all string literals

Can string literals include embedded quotations? If so, then the project becomes harder.

2) Also, I have to ensure it ignores comments that include quotations.

Again, you can use a brute force method or use find() on an STL string to find either the \\ or the \* and then see if there are quotation marks between there and the end of the line or the */, depending on which type of comment is found.

Of course it's harder. If you can find all the strings irregardless of the comments, it's a simple matter to modify that code to find the comments and remove them first. This ain't rocket science. If you can do one, you do the other with a minor code change. Then put them together. Again -- sheesh! I don't mind telling noobs they have to think to program, but having to tell seasoned programmers the same thing is just annoying...

And what the heck does tetron's first post have to do with anything in this thread?

And what the heck does tetron's first post have to do with anything in this thread?

I think is was one of those tests where you are watching the team is passing around the basketball so intently that when a guy in a costume walks through the court you don't notice it at all? Yeah, I guess maybe he copied and pasted his post into the wrong one...

@WaltP -- you're right. I made some assumptions and I should have kept it simple.

O
And what the heck does tetron's first post have to do with anything in this thread?

Sorry, I did misread the question a bit as regards "string literal" :$

But looking at the original code I don't think the asker has figured out find() so the question of parsing lines to find the string
/* " */ std::string("hello//world\n\tgoodbye");
is not the point of the exercise I think there are a lot of parts of the
code that are pasted in without understanding.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.