Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c - strcmp not returning 0 for equal strings

Tags:

c

strcmp

So I've tried searching for a solution to this extensively but can only really find posts where the new line or null byte is missing from one of the strings. I'm fairly sure that's not the case here.

I am using the following function to compare a word to a file containing a list of words with one word on each line (dictionary in the function). Here is the code:

int isWord(char * word,char * dictionary){
  FILE *fp;
  fp = fopen(dictionary,"r");
  if(fp == NULL){
    printf("error: dictionary cannot be opened\n");
    return 0;
  }
  if(strlen(word)>17){
    printf("error: word cannot be >16 characters\n");
    return 0;
  }
  char longWord[18];
  strcpy(longWord,word);
  strcat(longWord,"\n");
  char readValue[50] = "a\n";
  while (fgets(readValue,50,fp) != NULL && strcmp(readValue,longWord) != 0){
    printf("r:%sw:%s%d\n",readValue,longWord,strcmp(longWord,readValue));//this line is in for debugging
  }
  if(strcmp(readValue,longWord) == 0){
    return 1;
  }
  else{
    return 0;
  }
}

The code compiles with no errors and the function reads the dictionary file fine and will print the list of words as they appear in there. The issue I am having is that even when the two strings are identical, strcmp is not returning 0 and so the function will return false for any input.

eg I get:

r:zymoscope
w:zymoscope
-3

Any ideas? I feel like I must be missing something obvious but have been unable to find anything in my searches.

like image 778
Xephz Avatar asked Jul 27 '15 18:07

Xephz


People also ask

Why is strcmp not returning 0?

If the s1 char is larger than the s2 char, strcmp will return a number > 0. strcmp() stops comparing after the first unmatched chars. It's kind of like functions that return true or false. Functions that return false always return 0 for false.

How do I force my strcmp to return 0?

The return value from strcmp is 0 if the two strings are equal, less than 0 if str1 compares less than str2 , and greater than 0 if str1 compares greater than str2 . No other assumptions should be made about the value returned by strcmp .

How do you use strcmp to test if two strings are equal?

We take the user input as strings. We compare the strings by using the strcmp() function, i.e., strcmp(str1,str2). This function will compare both the strings str1 and str2. If the function returns 0 value means that both the strings are same, otherwise the strings are not equal.

What does strcmp return if failed?

strcmp returns -1 (less than 0), 0 (equal) or 1 (greather than 0). One way to find this out is to google man strcmp .


2 Answers

I see you are appending a newline to your test strings to try to deal with the problem of fgets() retaining the line endings. Much better to fix this at source. You can strip all trailing stuff like this, immediately after reading from file.

readValue [ strcspn(readValue, "\r\n") ] = '\0';   // remove trailing newline etc
like image 137
Weather Vane Avatar answered Nov 10 '22 11:11

Weather Vane


The string you are reading contains trailing character(s), and hence is not the same as the string you are comparing it against.

Remove the trailing newline (and CR if that is there); then you do not need to add any newline or carriage return to the string being compared:

int isWord(char *word, char *dictionary){
  FILE *fp;
  fp = fopen(dictionary, "r");
  if (fp == NULL){
    fprintf(stderr, "error: dictionary cannot be opened\n");
    return 0;
  }
  if (strlen(word) > 16){
    fprintf(stderr, "error: word cannot be >16 characters\n");
    return 0;
  }
  char readValue[50];
  while (fgets(readValue, 50, fp) != NULL){
    char *ep = &readValue[strlen(readValue)-1];

    while (*ep == '\n' || *ep == '\r'){
      *ep-- = '\0';
    }
    if (strcmp(readValue, word) == 0){
      return 1;
    }
  }
  return 0;
}
like image 45
Nick Stoughton Avatar answered Nov 10 '22 11:11

Nick Stoughton