Testing string against array of char[]

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

30 Replies - 1400 Views - Last Post: 16 April 2014 - 06:45 AM Rate Topic: -----

#16 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 03 April 2013 - 02:57 PM

View Postjimblumberg, on 03 April 2013 - 03:42 PM, said:

The following is probably not doing what you think it is. Remember strcmp() can return one of three values.
            if(!strcmp(stateTable[x],testState))


Also why the negation??


Jim


I did the negation because I thought strcmp returned a 0 if the strings matched?
So it would be strcmp == false if they were the same?
Was This Post Helpful? 0
  • +
  • -

#17 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 03 April 2013 - 03:09 PM

Okay whatever happened to my program screwed up the loading of my state array. My train of thought is derailed right now..

Here is the code for my load function. I verified that the text file is still in the format it should be.. the printf loop at the bottom is for testing.

/*********************************
* Load State Table *
*********************************/
void loadStates()
{
	FILE *stateFile;
	char buffer[40];

	stateFile = fopen("STATES.DAT", "r");

	if(!stateFile)
	{
		printf("Can't open file!");
		system("pause");
		exit(1);
	}
	else
	{
		fgets(buffer, 40, stateFile);
		fgets(buffer, 4, stateFile);
		strcpy(stateTable[0], buffer);

		for(int x = 1; x < 50; x++)
			{
				
				fgets(buffer, 40, stateFile);
				fgets(buffer, 4, stateFile);
				strcpy(stateTable[x], buffer);
			}
	}//ENDIF

	for(int x = 0; x < 50; x++)
				{
					printf("Array%s", stateTable[x]);
				}
	fclose(stateFile);
}//ENDLOAD

Was This Post Helpful? 0
  • +
  • -

#18 jimblumberg  Icon User is online

  • member icon


Reputation: 4025
  • View blog
  • Posts: 12,426
  • Joined: 25-December 09

Re: Testing string against array of char[]

Posted 03 April 2013 - 03:17 PM

Did you look at any documentation for strcmp()? This function can return one of three values.

Quote

Returns an integral value indicating the relationship between the strings:
A zero value indicates that both strings are equal.
A value greater than zero indicates that the first character that does not match has a greater value in str1 than in str2; And a value less than zero indicates the opposite.


You should be testing to see if strcmp() is equal to zero or not, not to a boolean value.


if(strcmp(stateTable[x],testState) == 0) // If they're the same execute the if!
if(strcmp(stateTable[x],testState) != 0) // If they're not the same execute the if!



And sometimes you really want to know which one is "larger" or "smaller" then you would compare with greater or less than zero.

Jim
Was This Post Helpful? 0
  • +
  • -

#19 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 03 April 2013 - 04:01 PM

Okay. SO.. when I load the array, it populates correctly inside the load function.
The array is declared above main.

static char stateTable[50][3];


I call the load function in main also, as soon as the program starts.

Then I get the state code as input, this is correct.

void getState()
{
	char state[10];
	getString("Please enter the state as a 2 char abbreviation:",state,10);
	state[0] = toupper(state[0]);
	state[1] = toupper(state[1]);

	validState(state);

}//END GETSTATE


and it calls validState
/*********************************
* Validate state  *
*********************************/

bool validState(char testState[])
{
	bool validState = false;

	printf("teststring:%i", strlen(testState));
	printf("ArrayString:%i", strlen(stateTable[0]));
	for(int x = 0; x < 50; x++)
	{
		printf("ArrayString:%i\n", strlen(stateTable[x]));
	}
	

	while(!validState)
	{
		for(int x = 0; x < 50; x++)
		{
			if(strcmp(stateTable[x],testState))
			{
				validState = true;
				break;
			}
		}	
	}//END WHILE

	return validState;
}//END VALIDSTATE


Here is my load function, just in case:
/*********************************
* Load State Table *
*********************************/
void loadStates()
{
	FILE *stateFile;
	char buffer[40];

	stateFile = fopen("STATES.DAT", "r");

	if(!stateFile)
	{
		printf("Can't open file!");
		system("pause");
		exit(1);
	}
	else
		fgets(buffer, 40, stateFile);
			fgets(buffer, 4, stateFile);
			strcpy(stateTable[0], buffer);

			for(int x = 1; x < 50; x++)
			{
				fgets(buffer, 40, stateFile);
				fgets(buffer, 4, stateFile);
				strcpy(stateTable[x], buffer);
				printf("Array%s", stateTable[x]);
			}

	fclose(stateFile);
}//ENDLOAD



So, when I test it on load, it's correct. When I test it inside valid state, the array is populated with number ranging from 147 to 8, if I remember correctly. The numbers count down.

What could be causing this?

This post has been edited by jimblumberg: 03 April 2013 - 05:18 PM
Reason for edit:: Fixed Code Tags.

Was This Post Helpful? 0
  • +
  • -

#20 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 04 April 2013 - 04:43 AM

View Postjimblumberg, on 03 April 2013 - 05:17 PM, said:

Did you look at any documentation for strcmp()? This function can return one of three values.

Quote

Returns an integral value indicating the relationship between the strings:
A zero value indicates that both strings are equal.
A value greater than zero indicates that the first character that does not match has a greater value in str1 than in str2; And a value less than zero indicates the opposite.


You should be testing to see if strcmp() is equal to zero or not, not to a boolean value.


if(strcmp(stateTable[x],testState) == 0) // If they're the same execute the if!
if(strcmp(stateTable[x],testState) != 0) // If they're not the same execute the if!



And sometimes you really want to know which one is "larger" or "smaller" then you would compare with greater or less than zero.

Jim


Okay, so in previous programs I have done
if(!strcmp(str1, str2))
and it worked.. so this is confusing to me..

I would need to do
if(strcmp == 0)
?

I can;t use it yet though, since my array is still not working properly. I am stumped.. since it's declared at the global level, and tests correct inside the load function, why would it go all crazy when I test it in another function?
Was This Post Helpful? 0
  • +
  • -

#21 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5805
  • View blog
  • Posts: 12,644
  • Joined: 16-October 07

Re: Testing string against array of char[]

Posted 04 April 2013 - 06:03 AM

fgets... remember what fgets does? You have a buffer of 3. You have a string of {'N','J','\n','\0'} which doesn't look like it will fit in 3...

You know you have only two chars in a valid state abbreviation. Use it!

e.g.

// magic numbers, bad!
const int STATE_TABLE_SIZE = 50;
const int STATE_SIZE = 3;

// globals also bad...
static char stateTable[STATE_TABLE_SIZE][STATE_SIZE];

bool getState() {
	char state[10];
	getString("Please enter the state as a 2 char abbreviation:",state,10);
	return validState(state);

}

bool testState(char *s1, char *s2) { return (s1[0]==s2[0]) && (s1[1]==s2[1]) && (s1[2]==s2[2]); }

bool validState(const char *state) {
	char stateCmp[STATE_SIZE] = { toupper(state[0]), toupper(state[1]), 0 };

	// ...
	while(!validState) {
		for(int i=0; i<STATE_TABLE_SIZE; i++) {
			if(testState(stateTable[i],stateCmp)) {
				validState = true;
				break;
				// ok, you only break the for
			}
		}
		// if the state is not valid, how do you get out of here?

	}

	return validState;
}



Get rid of the while.
Was This Post Helpful? 0
  • +
  • -

#22 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 04 April 2013 - 06:17 AM

Okay.. so I need to take this in baby steps apparently. I'm exhausted by these 15 hour days.

Prof told us that we need to use a large buffer. He suggested at least 40 characters for everything.

I have learned that this is horrible programming practice. So, I changed my fgets buffer to a 4.

Now.. as for the state.. I know it has 2 valid characters.. what do you mean by use it? Doesn't it have to have at least 4 char like it does in my fgets? To accommodate the carriage return and the delimiter?

ETA - I did get rid of the while a bit ago :)

I should have come back and updated my code, apologies.

This post has been edited by synlight: 04 April 2013 - 06:17 AM

Was This Post Helpful? 0
  • +
  • -

#23 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 04 April 2013 - 06:28 AM

View Postbaavgai, on 04 April 2013 - 08:03 AM, said:

fgets... remember what fgets does? You have a buffer of 3. You have a string of {'N','J','\n','\0'} which doesn't look like it will fit in 3...

You know you have only two chars in a valid state abbreviation. Use it!

e.g.



bool testState(char *s1, char *s2) { return (s1[0]==s2[0]) && (s1[1]==s2[1]) && (s1[2]==s2[2]); }






Okay.. I'm trying to understand this code. I've never written anything like this..
So you pass it a pointer to the state and the input you're testing.

I don't understand the return at the beginning.. is it like an if statement kind of? It returns true if all those conditions are true, and false if they are not? Conditions being that each char in each string are the same.
Was This Post Helpful? 0
  • +
  • -

#24 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 04 April 2013 - 06:37 AM

 char stateCmp[STATE_SIZE] = { toupper(state[0]), toupper(state[1]), 0 };


Why did you put a 0 in the last character of the array?
Was This Post Helpful? 0
  • +
  • -

#25 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 04 April 2013 - 09:00 AM

anyone? Buehler?
Was This Post Helpful? 0
  • +
  • -

#26 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5805
  • View blog
  • Posts: 12,644
  • Joined: 16-October 07

Re: Testing string against array of char[]

Posted 04 April 2013 - 09:43 AM

View Postsynlight, on 04 April 2013 - 09:28 AM, said:

Okay.. I'm trying to understand this code. I've never written anything like this..


Of course you have! Expressed another way:
// bool testState(char *s1, char *s2) { return (s1[0]==s2[0]) && (s1[1]==s2[1]) && (s1[2]==s2[2]); }
// return true if the two letter strings match
bool testState(char s1[], char s2[]) { 
	if (s1[0]!=s2[0]) { return false; } // test the first letter
	if (s1[1]!=s2[1]) { return false; } // test the second letter
	if (s1[2]!=s2[2]) { return false; } // last "letter" is '\0', they should both have it
	// you made it this far, they match
	return true;
}




View Postsynlight, on 04 April 2013 - 09:37 AM, said:

Why did you put a 0 in the last character of the array?


Perhaps:
 
//char stateCmp[STATE_SIZE] = { toupper(state[0]), toupper(state[1]), 0 };
char stateCmp[STATE_SIZE];
stateCmp[0] = toupper(state[0]);
stateCmp[1] = toupper(state[1]);
stateCmp[2] = '\0'; // all c-strings gotta end


Was This Post Helpful? 1
  • +
  • -

#27 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Testing string against array of char[]

Posted 04 April 2013 - 11:29 AM

Got it working! With the help of a friend..
I was having problems because of the buffer.. I needed to add a delimiter after each state..

Like Baavgai was showing me. I just didn't understand at the time.
Was This Post Helpful? 0
  • +
  • -

#28 jon.kiparsky  Icon User is online

  • Pancakes!
  • member icon


Reputation: 7650
  • View blog
  • Posts: 12,905
  • Joined: 19-March 11

Re: Testing string against array of char[]

Posted 04 April 2013 - 11:41 AM

View Postsynlight, on 04 April 2013 - 01:29 PM, said:

Like Baavgai was showing me. I just didn't understand at the time.


This happens - you can have five good explanations, and none of them clicks, and then number six works, and you understand the first five all at once.
Was This Post Helpful? 0
  • +
  • -

#29 djoonya  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 15-April 14

Re: Testing string against array of char[]

Posted 15 April 2014 - 02:03 PM

syn,

Would it be at all possible to expand on what you meant with the buffer issue? I am taking the same class and have run into a bit of a roadblock in reference to validating the State abbreviation. Did you mean that you had to insert a delimiter in the value to use for comparison or whenever you load the list in? Any help or guidance is appreciated!

V/R
Was This Post Helpful? 0
  • +
  • -

#30 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1335
  • View blog
  • Posts: 4,575
  • Joined: 19-February 09

Re: Testing string against array of char[]

Posted 15 April 2014 - 03:06 PM

Hi, it looks like synlight is copying 4 characters, at a time, to the state table array, when the array is set to hold 3. The null character at the end will then be overwritten. The fgets function will get 4 characters :- 2 letters, a newline character and a null character.

If you need more help perhaps you want your own topic.
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3