strcmp on a line read with fgets

后端 未结 6 1083
你的背包
你的背包 2020-11-22 11:56

I\'m trying to compare two strings. One stored in a file, the other retrieved from the user (stdin).

Here is a sample program:

int main()
{
    char          


        
相关标签:
6条回答
  • 2020-11-22 12:06

    Because fgets is embededing the newline character into the variable targetName. This is throwing off the comparison.

    0 讨论(0)
  • 2020-11-22 12:08

    fgets reads until it sees a newline then returns, so when you type bob, in the console, targetName contains "bob\n" which doesn't match "bob". From the fgets documenation: (bolding added)

    Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first. A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str. A null character is automatically appended in str after the characters read to signal the end of the C string.

    You need to remove the newline from the end of targetName before you compare.

    int cch = strlen(targetName);
    if (cch > 1 && targetName[cch-1] == '\n')
       targetName[cch-1] = '\0';
    

    or add the newline to your test string.

    char targetName[50];
    fgets(targetName,50,stdin);
    
    char aName[] = "bob\n";
    printf("%d",strcmp(aName,targetName));
    
    0 讨论(0)
  • 2020-11-22 12:11

    Mostly because of the end of line char in the input "\n" under unix like system.

    0 讨论(0)
  • 2020-11-22 12:15

    The fgets is appending a \n to the string that you are pulling in from the user when they hit Enter. You can get around this by using strcspn or just adding \n onto the end of your string you're trying to compare.

    printf("Please enter put FILE_NAME (foo1, 2, or 3), ls, or exit: \n");
    fgets(temp, 8, stdin);
    temp[strcspn(temp, "\n")] = '\0';
    if(strcmp(temp, "ls") == 0 || strcmp(temp, "exit") == 0)
    

    This just replaces the \n with a \0, but if you want to be lazy you can just do this:

    printf("Please enter put FILE_NAME (foo1, 2, or 3), ls, or exit: \n");
    fgets(temp, 8, stdin);
    if(strcmp(temp, "ls\n") == 0 || strcmp(temp, "exit\n") == 0)
    

    But it's not as elegant.

    0 讨论(0)
  • 2020-11-22 12:21

    strcmp is one of the few functions that has the reverse results of true and false...if the strings are equal, the result is 0, not 1 as you would think....

    if (strcmp(a, b)) {
        /* Do something here as the strings are not equal */
    } else {
        /* Strings are equal */
    }
    

    Speaking of fgets, there is a likelihood that there is a newline attached to the end of the string...you need to get rid of it...

    +-+-+-+--+--+
    |b|o|b|\n|\0|
    +-+-+-+--+--+
    

    To get rid of the newline do this. CAVEATS: Do not use "strlen(aName) - 1", because a line returned by fgets may start with the NUL character - thus the index into the buffer becomes -1:

    aName[strcspn(aName, "\n")] = '\0';
    
    +-+-+-+--+
    |b|o|b|\0|
    +-+-+-+--+
    

    Now, strcmp should return 0...

    0 讨论(0)
  • 2020-11-22 12:23

    fgets appends the newline to the string, so you'll end up with bob\n\0 which isn't the same as bob\0.

    0 讨论(0)
提交回复
热议问题