1

I have a problem when comparing two of the same strings in C. Using the method strcmp(), there seems to be a problem when comparing a line from a text file to the user input. Why does strcmp() return -1 even if user input is identical to the text file.

#include <stdio.h>
#include <stdlib.h>  
#include <string.h>

struct Person{
    char fName[10];
    char lName[10];
};

char inputUser[10]; 

int main()
{   
   FILE *file;
   int ret;
   char data[20];

   file = fopen("file.txt", "r");
   struct Person *p1 =  malloc(sizeof(struct Person));
   gets(inputUser);

   strcpy(p1->fName , inputUser);
   struct Person *p2 =  malloc(sizeof(struct Person));

   while (fgets(data , 20 , file) != NULL){
      strcpy(p2->fName , data);
      ret = strcmp(p1->fName, p2->fName);
      printf("\t%d\t%s\t%s\n", ret , p1->fName, p2->fName);
   }
   fclose(file);
   file = fopen("file.txt","a"); 
   fprintf(file, "%s\n", p1->fName);  
   fclose(file);

}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
craexus
  • 39
  • 2
  • 8
  • 2
    Have you considered the *newline* issue ? with `gets` and `fgets` ? why not use `fgets(inputUser,20,stdin)` instead of `gets(inputUser)` ? – dvhh Sep 26 '16 at 01:25
  • 3
    Your question requires sample input, expected output, and actual output before it is a [mcve]. – John Bollinger Sep 26 '16 at 01:27
  • 1
    note that input of the fgets the result will include a trailing newline. remove the newline if newline is exist. – BLUEPIXY Sep 26 '16 at 01:29
  • Note that [you should never use the `gets()` function](http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) — it is too dangerous. It removes the newline from what it reads; `fgets()` does not. Comparing a string with a newline and a string without a newline will always yield a difference. – Jonathan Leffler Sep 26 '16 at 05:36
  • Hey @craexus, if my answer (or another) has helped you, would you consider accepting it? Accepting an answer shows the community that it has solved your problem, and helps future readers with theirs. If you don't know how to accept an answer, there's a useful [faq meta post](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) about it. Thanks. – MD XF Dec 06 '16 at 06:34

2 Answers2

0

Add this after your gets(inputUser):

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

That will remove the last character of the string. gets() records the newline (Enter key) the user inputs. That's why strcmp() doesn't think they're the same thing, because of the newline.

Also, to avoid a Segmentation Fault, you should change gets(inputUser) to:

fgets(inputUser, sizeof(inputUser), stdin);

This does the same thing except the second argument limits the length of the data that can be read. With gets(), if you enter over 10 characters to be stored in a 10-character string it will seg-fault.

MD XF
  • 7,860
  • 7
  • 40
  • 71
  • 2
    `inputUser[strlen(inputUser)-1] = '\0';` is sufficient for learning programs, but allows a hacker exploit of a user entering a null character as the first character of input. That results in `inputUser[(size_t)-1] = '\0';` which is UB and likely an exception. Suggest http://stackoverflow.com/a/28462221/2410359 – chux - Reinstate Monica Sep 26 '16 at 03:04
  • 2
    `fgets(inputUser, sizeof inputUser, stdin);` is not a problem. `fgets()` does not need a `-1` to avoid seg fault. – chux - Reinstate Monica Sep 26 '16 at 03:17
0

Just replace

  strcpy(p2->fName , data);
  ret = strcmp(p1->fName, p2->fName);

by

  strcpy(p2->fName , strtok(data, "\n"));
  ret = !strcmp(p1->fName, p2->fName);
  • !strcmp(A, B) returns true (1) if A equals B. Otherwise returns false (0);
  • strtok(A, B) returns A without the substring B.
Marcel
  • 2,810
  • 2
  • 26
  • 46