cstringuser-inputstrcmp

User input comparing in C, unexpected symbols in user input array


Im trying to compare user input string with the example inside function, using gets() and strcmp to do this.

I've tried this code:

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

int main() {
    // example string
    char userName[30] = "Alice Jane";
    // string for storing user input
    char userInput[30];
    
    printf("Enter your text:\n");
    fgets(userInput, 30, stdin);
    printf("Your text is: %s\n", userInput);
    printf("Real text is: %s\n", userName);
    
    int strComparing = strcmp(userName, userInput);
    if (strComparing == 0) {
        printf("Strings are equal\n");
    } else {
        printf("Strings are not equal, difference is %d\n", strComparing);
    }
    
    printf("Username size is %lu\n", sizeof(userName));
    printf("Inputed username size is %lu\n", sizeof(userInput));
    
    int i, j;
        // printing example string
        for (i = 0; i < 30; i++) {
            printf("%d ", userName[i]);
        }

        printf("\nBreak between arrays\n");
        // printing user inputted string, here happens something wierd
        for (j=0; j < 30; j++) {
            printf("%d ", userInput[j]);
        }
}

Result:

Enter your text:
Alice Jane 
Your text is: Alice Jane 
Real text is: Alice Jane
Strings are not equal, difference is -32
Username size is 30
Inputed username size is 30
65 108 105 99 101 32 74 97 110 101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
Break between arrays
65 108 105 99 101 32 74 97 110 101 32 0 0 0 16 89 94 2 1 0 0 0 24 93 94 2 1 0 0 0 

Everything goes fine, but when comparing, then strings are not equal. And when trying to print arrays, I see something weird in user input array:

65 108 105 99 101 32 74 97 110 101 32 10 0 0 16 -103 84 0 1 0 0 0 24 -99 84 0 1 0 0 0

but example array is fine, ascii encoded "Alice Jane" phrase:

65 108 105 99 101 32 74 97 110 101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

What is wrong here and how to deal with it? Why does user input array is filled with unexpected symbols?


Solution

  • fgets(userInput, 30, stdin);
    

    The problem is that fgets() adds the newline in the buffer, assuming there was space for it. You have to strip it before trying to compare it. The simplest way is:

    #include <string.h>
    
    userInput[strcspn(userInput, "\n")] = '\0';
    

    If you see look at the 12th number here:

    65 108 105 99 101 32 74 97 110 101 32 10 0 0 16 -103 84 0 1 0 0 0 24 -99 84 0 1 0 0 0
                                           |
    

    you'll see the number 10, which is the ASCII code for a newline/linefeed.

    It seems that you also entered a space before the newline, seeing that there is the number 32 before 10, and 32 is the ASCII code for a space.

    If you're wondering why there are a mix of positive and negative numbers following the linefeed, then it is because variables with automatic storage duration are not automatically initialized to zero in C and C++, and hold indeterminate values.

    As of why userName doesn't have indeterminate values:

    C99 [$6.7.8/21]

    If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

    which means that they are zero-initialized.