Search code examples
cstringstructurestrcmp

strcmp function not working properly


I have a delete function on array of structures books. I'm passing it an array of records, author of book and name of book and size of the list.

Now here given that list[0].author and list[5].author and author all are equal to "Dan Brown" (same string)

void delete(struct books *list,char author[],char name[],int n)
{
    int i,a;
    a=strcmp(list[0].author,list[5].author);
    printf("%d\n",a);              // prints 0
    a=strcmp(list[0].author,author);
    printf("%d\n",a);              // prints other than 0
}    

Why is it happening? What's wrong here?


Solution

  • From the documentation of fgets:

    Reading stops when a newline character is found, at end-of-file or error. The newline, if any, is retained.

    This means that fgets will not remove the final '\n' from the end of the read string. Thus, your strings are:

    1. "Dan Brown"
    2. "Dan Brown"
    3. "Dan Brown\n"

    They're not equal.

    This is a very common issue when using fgets. That's why I usually prefer scanf, like this:

    char buffer[BUF_LEN];
    char format[16];
    int scanf_result;
    
    sprintf(format, "%%%u[^\n]", BUF_LEN);
    //....
    do
    {
      //TODO: Ask for input
      scanf_result = scanf(format, buffer);
      switch (scanf_result)
      {
        case -1: //TODO: Print error message and exit
        case 0: //TODO: Print error mesage and break
      }
      //Discard remainings of buffered input line
      while (getchar() != '\n') {;}
    } while (1); //Ugly, but plain
    

    Otherwise, you can use fgets with something like this:

    int buf_len;
    
    //TODO: Ask for input
    while (fgets(buffer, BUF_LEN, stdin) == NULL)
    {
      //TODO: Check and handle error
    }
    buf_len = strlen(buffer);
    //Remove trailing '\n', if present
    if (buffer[buf_len - 1] == '\n')
    {
      buffer[--buf_len] = '\0';
    }
    

    Even though it's easier, I don't like this second method, because strlen scans the string another time to determine its length. In most cases, this is not a performance issue, I avoid it because I have my own mental issues.