• Some users have recently had their accounts hijacked. It seems that the now defunct EVGA forums might have compromised your password there and seems many are using the same PW here. We would suggest you UPDATE YOUR PASSWORD and TURN ON 2FA for your account here to further secure it. None of the compromised accounts had 2FA turned on.
    Once you have enabled 2FA, your account will be updated soon to show a badge, letting other members know that you use 2FA to protect your account. This should be beneficial for everyone that uses FSFT.

Issue with comparing strings in C++

tino

n00b
Joined
Jun 9, 2008
Messages
30
Hi all,

This is probably quite a simple problem but when I run the following code (shown below) to compare two files, File.txt and dic.txt. I get the following output:

If they are the same I get

They are the same
They are the same

If the files are different I get

They are not the same
They are the same

I can't work out why the "They are the same" is getting printed twice tho. Any help would be appreciated.

Oh im running Debian and using the following command to compile.

g++ -Wall -W -pedantic compare.cpp -o compare

Code:
#include <fstream> 
#include <iostream> 
#include <string>

using namespace std; 

int main( )

{ 
	ifstream in("File.txt"); 		//open input file File.txt
	ifstream in2("dic.txt");		//open input file dic.txt
		
	while (!in.eof())			//continue until you get to the of in
	while (!in2.eof()) 			//continue until you get til the end of in2

	{
		string (line);
		string (line2);

		getline(in,line); 		//get lines
		getline(in2,line2); 		//get lines

		{
			if(line == line2) 	//are the strings equal?
			cout << " They are the same " << endl;

			else			//the strings are not equal
			cout << " They are not the same " << endl;
		}
	
	}
		in.close();			//close the input file in
		in2.close(); 			//close the input file in2 
	
	return (0); 				//finish program
}
 
Your loops are wrong; nesting the while loops as you have can't possibly be your desired behaviour. If one file is longer than the other, your program will hang.

Also, you're going to print one line of output per each line of input -- is that your desired behaviour?

I'm surprised your string declarations are accepted by the compiler. Those should be fixed.
 
Not that I know of.

Each file just has a series of numbers across one line in it. Ive tried it with just the number 1, hello and a, and it still gets the same output error.
 
Your loops are wrong; nesting the while loops as you have can't possibly be your desired behaviour. If one file is longer than the other, your program will hang.

Also, you're going to print one line of output per each line of input -- is that your desired behaviour?

I'm surprised your string declarations are accepted by the compiler. Those should be fixed.

I want to print one line of output at the end. Im getting the problem that two lines are being printed.

I guess your saying its down to how ive wrote the while loop?
 
What mikeblas said. The structure of your loops and the declaration of your strings definitely need to be changed. As well, you're currently printing out "the same" or "not the same" for each line in the file, not the file. If you want to do the whole file, you'll need to have a boolean variable outside of the loop to compare against, as well as some checks to set that variable to false if one file is longer than the other.
 
Not that I know of.

Each file just has a series of numbers across one line in it. Ive tried it with just the number 1, hello and a, and it still gets the same output error.

then it has to do with the nest while loops might want to change it something like

Code:
while (!in.eof || !in2.eof)

I'm not sure that would be the right way to do it though. My C++ experience is quite limited.
 
The extra line is due to how eof() works - eof() won't be true until it's attempted a read and reached the end of the file, at which point it's inside the loop and will run the display code again. This can be fixed as follows:
Code:
getline(in, line);
// ...
while (loopConditionInvolvingEOF) {
  // do stuff
  getline(in, line);
}
Also, ryan, you'd want !in.eof && !in2.eof since as soon as one file is empty there's no point comparing further.
 
Ryan - I did have the code as

Code:
 while ((!in.eof()) && (!in2.eof()))

But changed it to two while's for some unknown reason, i'll change it back again.
 
The extra line is due to how eof() works - eof() won't be true until it's attempted a read and reached the end of the file, at which point it's inside the loop and will run the display code again. This can be fixed as follows:
Code:
getline(in, line);
// ...
while (loopConditionInvolvingEOF) {
  // do stuff
  getline(in, line);
}
Also, ryan, you'd want !in.eof && !in2.eof since as soon as one file is empty there's no point comparing further.

oops, yeah. Both have to be NOT at the end of the file.
 
So your saying something like this...

Code:
               {

		getline(in,line); 		//get lines
		getline(in2,line2); 		//get lines
		while ((!in.eof()) && (!in2.eof()))		//continue until you get to the two files
				
			if(line == line2) 	//are the strings equal?
			cout << " They are the same " << endl;

			else			//the strings are not equal
			cout << " They are not the same " << endl;

		getline(in,line); 		
		getline(in2,line2); 		

		}

I don't quite understand why
getline(in,line);
getline(in2,line2)
is included in there at the end tho.

Also ive got to add the error output if the files are off a different length as you mentioned, but for now I would like to understand how to use eof correctly. Unless of course there is a better function to use...

Ok I messed around a bit since then an ive got to
Code:
#include <fstream> 
#include <iostream> 
#include <string>

using namespace std; 

int main( )

{ 
	ifstream in("File.txt"); 		//open input file File.txt
	ifstream in2("dic.txt");		//open input file dic.txt
		
	{
		string (line);
		string (line2);

		getline(in,line); 		//get lines
		getline(in2,line2); 		//get lines
		while ((!in.eof()) && (!in2.eof()))		//continue until you get to the two files
		{		
			if(line == line2) 	//are the strings equal?
			cout << " They are the same " << endl;

			else			//the strings are not equal
			cout << " They are not the same " << endl;
		break;

		getline(in,line); 		//get lines
		getline(in2,line2); 		//get lines
		}
	
	}
	
	return (0); 				//finish program
}

Which seems to work ok.
 
First of all, use brackets around all loops and if statements. They make the code easier to read and debug and ensure you know what's happening where. With that, your code becomes
Code:
getline(in,line); 		//get lines
getline(in2,line2); 		//get lines

while ((!in.eof()) && (!in2.eof()))		//continue until you get to the two files
{
	if(line == line2) 	//are the strings equal?
	{
		cout << " They are the same " << endl;
	}
	else			//the strings are not equal
	{
		cout << " They are not the same " << endl;
	}

	getline(in,line); 		
	getline(in2,line2); 		
}
The ones at the end are because you need to keep getting another line inside the loop.

This will now display one "The files match" or "The files do not match" for each line (up to the number of lines in the shorter file). To display that exactly once at the end, you need to have a variable outside the loop for storing whether all lines that have been seen match, and you need to move the display code outside the loop.
 
I'm looking through a page about the c++ string object, and i don't see a == operator... which tells me you are comparing the living locations of the objects, not the values of the objects.

is this page not showing me something or is the OP wrong?

Unlike in Java where '==' does comparison of the references for String objects, C++ basic_string has an overloaded '==' operator which std::string uses.

The ==, <, >, !=, <=, and >= operators are provided for basic_strings, but are not member functions, which is why they don't show up in the class docs you linked.

But they are in <string>
http://msdn.microsoft.com/en-us/library/xabz5s9c(VS.80).aspx
 
Back
Top