string (array) compare == false positives

is there a problem using == with string array?

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 5592 Views - Last Post: 10 November 2008 - 07:43 AM Rate Topic: -----

#1 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

string (array) compare == false positives

Post icon  Posted 09 November 2008 - 06:11 PM

[edit: found the problem guys, and it was more with my brain than the code or data files, zoom to last few posts to be entertained]

I'm running in to problems comparing strings of name1[counter] == name2[counter2] in that any matching character in either name drops out as a match and strcmp fails with a function not declared in my c++ compiler every way I can think to write it.

I had a program complete which takes a file of boys and girls names for a given years consensus report and lets you search two loaded arrays for popularity of girls and boys names.

I thought that was boringly simple so I put in the last 4 years of consensus info. Running one search through at a time was ugly so I added a switch and loop that allows you to enter an a,b,c, or d to search any of the last four years of consensus info for the names until an escape character is entered.

Then a thought hit me, with somewhat ambiguous names like river or forest, what if names showed up in boys and girls names in the same year and my program dropped out after finding only one?

Rather than duplicate code and search functions to continue through all 2000 names after one is found I thought it would be fun to grind through and compare all occurrences of the 2000 names in the chosen year and print any matches that were found.

Here is my code which appears to be finding a matching name when any two characters match up and commented out I will include the strcmp attempt which fails at compile time even though I have included string.h. The !matchflag at the end might be a problem also but it's not getting that far so I haven't had to fix it yet.
// this is in header btw #include <string.h>
//check for duplicate boys and girls names in a given year	   
				int boycount, girlcount;
				char matchflag;
				for (boycount = 0; boycount < 1000; boycount++)
				{
					for (girlcount = 0; girlcount < 1000; girlcount++)
					{
						   
					  if (boysnames[boycount] == girlsnames[girlcount])
					   {
						   cout << "\nMatching name found, boys name postion: " << boycount+1 <<
						   " and girls name position: " << girlcount++ << " in " <<
						   Search_Year << " for name: " << boysnames[boycount] << 
						   " and " << girlsnames[girlcount] << "\n";
						   matchflag = 'y';
						   system ("PAUSE");  
					   }
					   
					  /* if (strcmp (boysnames[boycount],girlsnames[girlcount]) != 0)
						 cout << "Match found!"; //have tried == and != to test strcmp boolean
												 //return but not getting that far, compiler
												 //fail on strcmp every attempt */
					}
					
				}
				
				if (!matchflag)
				   cout << "\nNo duplicate names found.\n" << "Continuing to name search...\n";


This post has been edited by badjava: 10 November 2008 - 04:08 AM


Is This A Good Question/Topic? 0
  • +

Replies To: string (array) compare == false positives

#2 n8wxs  Icon User is offline

  • --... ...-- -.. . -. ---.. .-- -..- ...
  • member icon

Reputation: 972
  • View blog
  • Posts: 3,878
  • Joined: 07-January 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 06:31 PM

How are the name arrays declared?
Was This Post Helpful? 0
  • +
  • -

#3 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 06:37 PM

View Postn8wxs, on 9 Nov, 2008 - 05:31 PM, said:

How are the name arrays declared?


They are the string class so I can see why my strcmp attempt won't work.
	const int namecount = 1000;
   string boysnames[namecount], girlsnames[namecount];


and loaded by
				while (! in_stream.eof()) //load array with new - year choice
				{

					  int counter;
					  for(counter = 0; counter < 1000; counter++)
					  {
					   in_stream >> placeholder;
					   in_stream >> boysnames[counter];
					   in_stream >> girlsnames[counter];
					   // cout << counter << endl;
					  }

				}


everything else in program works great, just not the name[int1] == name2[int2], so frustrating since everything i read seems to indicate two string class variables should just work with == with no problems...

Do i need to compare pointers to the array elements? Not sure how to do that correctly, I tried sneaking in an & or a * and couldn't get that to work...

This post has been edited by badjava: 09 November 2008 - 06:39 PM

Was This Post Helpful? 0
  • +
  • -

#4 n8wxs  Icon User is offline

  • --... ...-- -.. . -. ---.. .-- -..- ...
  • member icon

Reputation: 972
  • View blog
  • Posts: 3,878
  • Joined: 07-January 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 06:43 PM

if(boysnames[boycount].compare(girlsnames[girlcount]) == 0)
do_match_processing();


See http://www.velocityr...of-strings.html

This post has been edited by n8wxs: 09 November 2008 - 07:07 PM

Was This Post Helpful? 0
  • +
  • -

#5 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 07:08 PM

View Postn8wxs, on 9 Nov, 2008 - 05:43 PM, said:

if(boysnames[boycount].compare(girlsnames[girlcount]) == 0)
do_match_processing();


This is still finding matching names on line after line when it looks like the match is just from a single matching character and not the entire variable.

I attatched one of the name data files so u can run it through and see what you get if you want. The first match I get is between Ryan and Cristina...

If u only choose choice 'a' at run time this code and data file will go without errors.

Pasting in my entire code and attaching data file, here goes:
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <string.h>


using namespace std;

void Validate_Files1(ifstream&,char*, string&); 

int main( )
{
	ifstream in_stream;		   

	const int namecount = 1000;

	string Condition_Flag = "y";
	string Found_Flag = "y";

	string placeholder = "";
	string searchname = "";

	string boysnames[namecount], girlsnames[namecount];

		 char Input_File [16], Output_File [16];
		 string Search_Year = "";

		  while ( (Condition_Flag != "x") && (Condition_Flag != "X") ) 
		  {

				system ("cls");
				ifstream in_stream;	
				Validate_Files1(in_stream,Input_File,Search_Year);

				while (! in_stream.eof()) //load array with new - year choice
				{

					  int counter;
					  for(counter = 0; counter < 1000; counter++)
					  {
					   in_stream >> placeholder;
					   in_stream >> boysnames[counter];
					   in_stream >> girlsnames[counter];
					   cout << counter << endl;
					  }

				}

				//check for matching boys and girls names in a given year	   
				int boycount, girlcount;
				char matchflag;
				for (boycount = 0; boycount < 1000; boycount++)
				{
					for (girlcount = 0; girlcount < 1000; girlcount++)
					{
						   
					  //if (boysnames[boycount] == girlsnames[girlcount])
					  if(boysnames[boycount].compare(girlsnames[girlcount]) == 0) 
					   {
						   cout << "\nMatching name found, boys name postion: " << boycount+1 <<
						   " and girls name position: " << girlcount++ << " in " <<
						   Search_Year << " for name: " << boysnames[boycount] << 
						   " and " << girlsnames[girlcount] << "\n";
						   matchflag = 'y';
						   system ("PAUSE");  
					   }
					   
					}
					
				}
				

				cout << "\n\nEnter the boy or girls name to search for (case sensitive): \n";
				cin >> searchname;

				int counter;
				for(counter = 0; counter < 1000; counter++)
				{
					if (searchname == boysnames[counter])
					{
					   cout << "\n" << boysnames[counter] << " was " << counter+1 << 
					   " in popularity for boys names in " << Search_Year << ".\n";
					   Found_Flag = "y";
					   break;
					}
					else
						if (searchname == girlsnames[counter])
						{
						 cout << "\n" << girlsnames[counter] << " was " << counter+1 << 
						 " in popularity for girls names in " << Search_Year << ".\n";
						 Found_Flag = "y";
						 break;
					   }
					else
						Found_Flag="n";

				}

		  if (Found_Flag == "n")
			 cout << "\n The name: " << searchname << ", was not found.";

		  getchar ();

		  cout << "\nEnter 'x' to exit or any other key to search more names: ";
		  cin >> Condition_Flag;

	}

	in_stream.close();

	return 0;					

}

 void Validate_Files1(ifstream& Name_File, char* Input_File, string& Search_Year)
 {
	  #include <cstdlib>
	  
	  char searchyear = 'z'; //in case some value left in buffer getting grabbed by cin
							 //this didn't solve anything unfortunately

	  cout << "\nEnter year to search for popular boys and girls names (A,B,C,D):\n";
	  cout << "a. 2004\n";
	  cout << "b. 2005\n";
	  cout << "c. 2006\n";
	  cout << "d. 2007\n";
	  cout << "Choice: ";
	  cin >> searchyear;

	  switch (searchyear)
	  {
			 case 'a':
				  cout << "\nSearching 2004...\n";
				  Input_File = "2004_names.txt";
				  Name_File.open (Input_File);  
				  Search_Year = "2004";
				  break;
			 case 'b':
				  cout << "\nSearching 2005...\n";
				  Input_File = "2005_names.txt";
				  Name_File.open (Input_File);
				  Search_Year = "2005";
				  break;
			 case 'c':
				  cout << "\nSearching 2006...\n";
				  Input_File = "2006_names.txt";
				  Name_File.open (Input_File);
				  Search_Year = "2006";
				  break;
			 case 'd':
				  cout << "\nSearching 2007...\n";
				  Input_File = "2007_names.txt";
				  Name_File.open (Input_File);
				  Search_Year = "2007";
				  break;
			 default:
				  cout << "\nValid choices are A-D\n";
				  Input_File = "invalid_year";
				  Name_File.open (Input_File);				  
				  }

	  if (Name_File.fail()) //exit program if input file unable to be opened  
	  {
		 cout << "\nFailed opening input file: " << Input_File << ", exiting program:\n";  
		 system ("PAUSE");  
		 exit(1);  
	  }

 return;
 }

Attached File(s)


This post has been edited by badjava: 09 November 2008 - 07:09 PM

Was This Post Helpful? 0
  • +
  • -

#6 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 08:35 PM

the complete code and 1 data file is included, anyone have a minute to run the code and see why they think it is getting 100's of false positive matches?
Was This Post Helpful? 0
  • +
  • -

#7 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6075
  • View blog
  • Posts: 23,543
  • Joined: 23-August 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 09:02 PM

Should be #include <string>, not #include <string.h>.

Try this:
cout << "\nMatching name found, boys name position: " << boycount - 1 <<
	" and girls name position: " << girlcount - 1 << " in " <<
	Search_Year << " for name: " << boysnames[boycount] <<
	" and " << girlsnames[girlcount] << "\n";

Was This Post Helpful? 0
  • +
  • -

#8 n8wxs  Icon User is offline

  • --... ...-- -.. . -. ---.. .-- -..- ...
  • member icon

Reputation: 972
  • View blog
  • Posts: 3,878
  • Joined: 07-January 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 09:26 PM

This correctly finds the name matches. I did not fix the find the counts
routine.

Attached File(s)


Was This Post Helpful? 1
  • +
  • -

#9 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 10:10 PM

View PostJackOfAllTrades, on 9 Nov, 2008 - 08:02 PM, said:

Should be #include <string>, not #include <string.h>.

Try this:
cout << "\nMatching name found, boys name position: " << boycount - 1 <<
	" and girls name position: " << girlcount - 1 << " in " <<
	Search_Year << " for name: " << boysnames[boycount] <<
	" and " << girlsnames[girlcount] << "\n";



ok that will modify the line count (the -1 thing) being output but with no modification to the array element reference or the type of compare being done I don't see how this can fix the problem....


View Postn8wxs, on 9 Nov, 2008 - 08:26 PM, said:

This correctly finds the name matches. I did not fix the find the counts
routine.


cool, dl'ing to check out now!
Was This Post Helpful? 0
  • +
  • -

#10 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

Re: string (array) compare == false positives

Posted 09 November 2008 - 10:26 PM

View Postn8wxs, on 9 Nov, 2008 - 08:26 PM, said:

This correctly finds the name matches. I did not fix the find the counts
routine.

I had to comment out the #include "stdafx.h" as my compiler didn't recognize it. After that it compiles and runs without any errors except it starts finding every name as a match as soon as the name 'Ryan' hits on line 12 of the boys names.

This is bizarre, its like my computer is possessed.

I might have to give up on string compares and find a way to do everything as cstring with the strcmp function... ugh and i just learned how to do everything else as strings *cry*

This post has been edited by badjava: 09 November 2008 - 10:28 PM

Was This Post Helpful? 0
  • +
  • -

#11 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

Re: string (array) compare == false positives

Posted 10 November 2008 - 01:13 AM

View Postbadjava, on 9 Nov, 2008 - 09:26 PM, said:

View Postn8wxs, on 9 Nov, 2008 - 08:26 PM, said:

This correctly finds the name matches. I did not fix the find the counts
routine.

I had to comment out the #include "stdafx.h" as my compiler didn't recognize it. After that it compiles and runs without any errors except it starts finding every name as a match as soon as the name 'Ryan' hits on line 12 of the boys names.

This is bizarre, its like my computer is possessed.

I might have to give up on string compares and find a way to do everything as cstring with the strcmp function... ugh and i just learned how to do everything else as strings *cry*


Could there be something in my data file that is screwing up the program after line 12? It gets to line 12 every time before it goes in the tank.
Was This Post Helpful? 0
  • +
  • -

#12 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

Re: string (array) compare == false positives

Posted 10 November 2008 - 03:20 AM

View Postn8wxs, on 9 Nov, 2008 - 08:26 PM, said:

This correctly finds the name matches. I did not fix the find the counts
routine.


Want to hear something funny?

I went back and started hand checking the data file against my original program run and guess what.....there really were that many duplicate names, they were real duplicates that were getting found accurately, not false positives. I'm not sure for which reason I should feel more dumb but I'm considering a few... :crazy: omg
Was This Post Helpful? 0
  • +
  • -

#13 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5880
  • View blog
  • Posts: 12,757
  • Joined: 16-October 07

Re: string (array) compare == false positives

Posted 10 November 2008 - 03:37 AM

A big error I saw, and you repeated it, was this little gotcha
" and girls name position: " << girlcount++ << " in " <<


You're moving the counter inside a loop?

Other than that, and a severe need for some functions, the logic looked fine for the check. I wrote a test case and from what I could tell it was functioning as expected.

#include <fstream>
#include <iostream>
#include <cstdlib>
#include <string.h>

using namespace std;

void loadNames(const char *fileName, string boysnames[], string girlsnames[], const int namecount) {
	string placeholder;

	ifstream in_stream;
	in_stream.open(fileName);  
	for(int counter = 0; counter < namecount; counter++) {
		in_stream >> placeholder;
		in_stream >> boysnames[counter];
		in_stream >> girlsnames[counter];
	}
	in_stream.close();
}

void showNames(string boysnames[], string girlsnames[], const int namecount) {
	for(int counter = 0; counter < namecount; counter++) {
		cout << counter << "\t" << boysnames[counter] << "\t" << girlsnames[counter] << endl;
	}
}

void showMatchingNames(string boysnames[], string girlsnames[], const int namecount) {
	int found = 0;
	for (int boycount = 0; boycount < namecount; boycount++) {
		for (int girlcount = 0; girlcount < namecount; girlcount++) {
		  if (boysnames[boycount] == girlsnames[girlcount]) {
				cout << "\nMatching name found, boys name postion: " << boycount
					<< " and girls name position: " << girlcount 
					// << " in " << Search_Year 
					<< " for name: " 
					<< boysnames[boycount]
					<< " and " << girlsnames[girlcount]
					<< endl;
				found++;
			}
		}
	}
	cout << endl << found << " duplicate names found." << endl;
}

int main() {
	const int namecount = 1000;
	
	string boysnames[namecount], girlsnames[namecount];
	
	loadNames("2004_names.txt", boysnames, girlsnames, namecount);
	//showNames(boysnames, girlsnames, namecount);
	showMatchingNames(boysnames, girlsnames, namecount);
	return 0;
}



Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#14 badjava  Icon User is offline

  • Lux Ex Tenebris
  • member icon

Reputation: 14
  • View blog
  • Posts: 540
  • Joined: 30-October 08

Re: string (array) compare == false positives

Posted 10 November 2008 - 04:04 AM

View Postbaavgai, on 10 Nov, 2008 - 02:37 AM, said:

A big error I saw, and you repeated it, was this little gotcha
" and girls name position: " << girlcount++ << " in " <<


You're moving the counter inside a loop?

Other than that, and a severe need for some functions, the logic looked fine for the check. I wrote a test case and from what I could tell it was functioning as expected.


I must have posted my confession just before your post, there were really that many duplicate names in my data file and it was really finding them! I only figured it out after hand checking the data file against all of my results, very very embarrassing.

On the ++ in side the cout loop you really spooked me on that one, I went back and checked and I think what you were seeing was my compensating for the array starting at zero and being one off on the actual line number being compared. So I just added one to the variable in the print statement (not a referenced var so it didn't really increment) and dumped that to the print out as the working line number, wallah! If the user hand checks their hard copy against the screen output the line numbers will match.

For the original/full confession of my umm... insert negative term towards my intelligence here, go back one post before yours. *sigh* So embarrassing...
Was This Post Helpful? 0
  • +
  • -

#15 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5880
  • View blog
  • Posts: 12,757
  • Joined: 16-October 07

Re: string (array) compare == false positives

Posted 10 November 2008 - 04:23 AM

View Postbadjava, on 10 Nov, 2008 - 05:04 AM, said:

On the ++ in side the cout loop you really spooked me on that one...


You obviously wanted show +1. Be aware, you are skipping values. Why do you think the ++ notation works in the for loop?

Anyway, a check is simple enough. e.g.
 for(int i=0; i<9; i++) { cout << i++ << " "; }
 cout << endl;
/* results: 0 2 4 6 8 */


Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2