strcmp function not working properly

半城伤御伤魂 提交于 2019-12-10 21:14:45

问题


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?


回答1:


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.




回答2:


You should verify your inputs. Sometimes by more than one method is necessary. Here, I am using strlen(), and strstr(), because if the length is ==, and a substring exists, then the strings ARE equal. So, try something like this to verify the input strings are what you thing they are before making a conclusion:

Note: the enum is of course not necessary, but included here to add clarity to example of output.

enum    {
    SAME,     //0
    NOT_SAME  //1
}

void delete(struct books *list,char author[],char name[],int n)
{
    int i,a, len1, len2;
    A = NOT_SAME;
    len1 = strlen(list[0].author);
    len2 = (list[5].author);
    if(strstr(list[0].author,list[5].author) && (len1==len2)) a = SAME;
    printf("%d\n",a);              


    a = NOT_SAME;
    len1 = strlen(list[0].author);
    len2 = (author);
    if(strstr(list[0].author,author) && (len1==len2)) a = SAME;
    printf("%d\n",a);              

}    



回答3:


check second strings by printing character by character.

Especially author string.

for(i=0; i < strlen(list[0].author);i++)
{
   if(list[0].author[i]!=author[i])
   {
     printf("this is position is not matching\n",i+1);
     //try to print characters and also print ascii characters.
     break; 
   }

}
//or simply try to use strncpy() 


来源:https://stackoverflow.com/questions/19609328/strcmp-function-not-working-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!