Hi people, my first post here, hope its a good one.
I am trying to develop a program which will simulate a very simple name server, using the client-server frame.
My problem appears after the server receives the data (in form of a string) from the client and tries to compare this to strings within a file. The server should see if the data already exists, leaving file unchanged or enter into the file if it doesnt. I have used the functions strcmp(which always says that the data isnt in the file, even when it is) and strstr(which says that the data is in the file, even if the file is blank!).

Could someone please tell me what am I doing wrong?!
Thanks

while(fgets(charin, BUFFER, fp) != NULL)
{
if(strcmp(charin, buffer) == 0)
printf("already exists\n");
else
fprintf(fp, buffer);
}
Comments
Good work using code tags the first time :)

strcmp() is case sensitive, meaning that the word "Hello" is not the same as the word "hello". Maybe that is what is going on with that program. Try using a case in-sensitive comparison, such as stricmp(). The same function might be called something else on g++ compiler, such as comparenocase(), or something like that.

If that doesn't fix the problem then you need to post an example of the file. If its a large file just post the first two or three lines.

what is the value of BUFFER, that determines how many characters fgets pulls in at a time ?

the target string could be hitting the fgets boundary right where the searched pattern is occuring.

it might seem unlikely, but the fewer number of characters in the string being read by"fgets" at one time, the higher chance that this can occur.


.

Edited 6 Years Ago by jephthah: n/a

Thanks for the replies so far!
To answer the questions, I do not believe it is case sensitive issue, as everything is in lower case. BUFFER was defined as 1024 in size.
As a side note, when I used the function strlen to compare the size of each string, for some reason the string read in from the file was smaller than the string received from the client. However when both are printed out to the screen, they are identical.

E.g. of string from file

1|bob|123

Can anyone suggest why two identical strings would be different sizes?

Trailing spaces, which you will not see when you print them out unless you enclose the text with some special character, such as quotes, like printf("\"%s\"", charin);

Following your advise Dragon, I enclosed the text on both the string being read in from file and string received from the client. When printed to screen the string from the file looks like:
"temp
"
and the string from the client:
"1|bob|123"

I agree that these strings would not match any and that the client should be written to file, however the "temp" is that the only data in the file, yet it seems to be the only thing read in!

What else am I missing?

fgets() adds the line terminator to the end of the string if there is one in the input stream, which is why you saw the " character on another line. You need to remove it before calling strcmp(). Put this inside the loop, before the strcmp() line.

if( charin[strlen(charin)-1] == '\0' )
    charin[strlen(charin)-1] = 0;

As for the value of the string being "temp", I can't answer that question because I would need to see the file's contents and the new code that you used to read it.

Ok, my code so far:

while(fgets(charin, BUFFER, fp) != NULL)
{
printf("Checking...\n");
printf("\"%s\"\n", charin);
printf("\"%s\"\n", buffer);
if(charin[strlen(charin)-1] == '\0')
charin[strlen(charin) -1] = 0;
if(strcmp(charin, buffer) == 0)
{
printf("Already exists\n");
}
else
{
printf("Writing\n");
fprintf(fp, buffer);
}
}

If the file being read is empty the following will be printed to screen:

"
"
so writes the string from the client to the file. If the program is run again with data in the file, I still get:

"
"

which the first line in the file is empty space, as the data written to file before is on the next line down.

Isn't the fgets() function supposed to go through the whole file though? Or at least (in this case) until it comes to a NULL? It doesn't seem to be going past that first line and is still being read as:
"
"
What could be causing this?

fgets() will read up to BUFFER-1 characters or up to and including the '\n' in a line, whichever is smaller. So if your file contains ABCDEFG and BUFFER is 6 you will have in your input ABCDE\0 or ABCDEFG and BUFFER is 10 you will have in your input ABCDEFG\n\0 Remember the \n on input (file or keyboard) is a real character, not a vacuous indicator that does stuff.

Sorry Walt didn't see your comment at first. The BUFFER needs to be large enough to hold a client and IP address, both of which are of an unknown length, so the BUFFER will need to be large enough to hold them. Saying that the string held in the BUFFER, received from the client program prints fine!!!
It is with the string read in from the file where I am having problems! Even though the string from file prints as:
"1|bob|123
"
and the string from the client prints as:
"1|bob|123"
strcmp returns the value that the string from the file is smaller, than the string from the client. Why is this? How can I solve it? Is there a better method to use to achieve this?

Edited 6 Years Ago by HeavySoul: n/a

Ok, something new, this code works but only if the file has 1 entry. If there is more than 1, same problem again, even if I try to compare the first entry in file!

int i = 0, j = 0, k = 0, pos = 0;

	printf("Opening database...\n");

	fp = fopen("clients1.txt", "a+");
	fseek(fp, 0, SEEK_END);
	pos = ftell(fp);
	fseek(fp, 0, SEEK_SET);

	char charin[pos];

	if(fp == NULL)
	{
		printf("Error:	Failed to open database\n");
		return 0;
	}

	while(fgets(charin, pos, fp) != NULL)
	{
		printf("Checking...\n");
		printf("\"%s\"\n", charin);
		printf("\"%s\"\n", buffer);
		if(charin[strlen(charin)-1] == '\0')
			charin[strlen(charin)-1] = 0;
		j = strcmp(charin, buffer);
		if(j == 0)
		{
			printf("Client is already registered\n");
			k = 1;
		}
	}

	printf("Closing database...\n");
	fclose(fp);

Please, please help me finish this of!

Edited 6 Years Ago by HeavySoul: n/a

This isn't what you want:

printf("\"%s\"\n", buffer);
if(charin[strlen(charin)-1] == '\0')

charin[strlen(charin)-1] = 0;

j = strcmp(charin, buffer);

What you want is to get rid of the newline, not the end of string char, and you don't want to add a zero, either. The end of string marker char, IS a zero, but for char's - so your code is doing nothing but replacing one thing, with it's identical twin. ;)

What you want is this:

printf("\"%s\"\n", buffer);
if(charin[strlen(charin)-1] == '\n')  //if the string has a newline

charin[strlen(charin)-1] = '\0'; //replace it and shorten the string
// by one char. Now do the string comparison.                         
j = strcmp(charin, buffer);
//etc.

In C code, a group of letters without an end of string marker char, will compare the same as a proper string which has an end of string marker.

someLetters == someLetters\0

to strcmp().

Not so if one of the above has a newline char, however! :cool:

Edited 6 Years Ago by Adak: n/a

It's little things like this that make me really hate coding sometimes!!
That works great!!
If I was going to nit pick though I would say that when I print out the string from file it still comes out like:
"1|bob|123
"
but at this point I really dont care bout that! The comparision works and with multiple entries.

Thanks to everyone that replied!!

Showing that the data still has a newline in it.

Want it gone, also?

for(i = 0; i < strlen(YourString); i++) {
  if(YourString[i] == '\n') {
   for(j = i; j < strlen(YourString)-1; j++)  //shift down all char's above i
     Yourstring[j] = Yourstring[j+1];
}

That should do it.

Edited 6 Years Ago by Adak: n/a

Showing that the data still has a newline in it.

Want it gone, also?

for(i = 0; i < strlen(YourString); i++) {
  if(YourString[i] == '\n') {
   for(j = i; j < strlen(YourString)-1; j++)  //shift down all char's above i
     Yourstring[j] = Yourstring[j+1];
}

That should do it.

Wouldn't it be simpler to use:

ln = strlen(Yourstring) - 1;
if (Yourstring[ln] == '\n') Yourstring[ln--] = '\0';

since the '\n' is at the end of the string? Saves two loops.

This isn't what you want:

printf("\"%s\"\n", buffer);
if(charin[strlen(charin)-1] == '\0')

charin[strlen(charin)-1] = 0;

j = strcmp(charin, buffer);

What you want is to get rid of the newline, not the end of string char, and you don't want to add a zero, either. The end of string marker char, IS a zero, but for char's - so your code is doing nothing but replacing one thing, with it's identical twin. ;)

What you want is this:

printf("\"%s\"\n", buffer);
if(charin[strlen(charin)-1] == '\n')  //if the string has a newline

charin[strlen(charin)-1] = '\0'; //replace it and shorten the string
// by one char. Now do the string comparison.                         
j = strcmp(charin, buffer);
//etc.

In C code, a group of letters without an end of string marker char, will compare the same as a proper string which has an end of string marker.

someLetters == someLetters\0

to strcmp().

Not so if one of the above has a newline char, however! :cool:

0 and '\0' are the exact same thing, so your solution is exactly the same as the one I posted earlier. When the compiler sees '\0' it replaces it with 0. You must be thinking it is '0', which is the character 0 not the decimal 0. In that case you would have been correct.

I tried that in my old turbo C 1.01 and it failed with 0, but succeeded with '\0', as the end of string marker.

/* file should be opened in append mode*/

int found=0; 

while(fgets(charin, BUFFER, fp) != NULL)
{
  if(strcmp(charin, buffer) == 0)
  {
     printf("already exists\n");
     found = 1;
     break;
  }
}
if(found == 0)
{
   fscanf(fp,"%s",buffer);
}

Edited 6 Years Ago by WaltP: Added CODE Tags -- and don't use the TITLE as text for your post.

This article has been dead for over six months. Start a new discussion instead.