strcmp на строке, читаемой с помощью fgets

Я пытаюсь сравнить две строки. Один хранится в файле, другой извлекается из пользователя (stdin).

вот пример программы:

int main()
{
    char targetName[50];
    fgets(targetName,50,stdin);

    char aName[] = "bob";
    printf("%d",strcmp(aName,targetName));

    return 0;
}

В этой программе, strcmp возвращает значение -1, когда вход "bob". Почему так? Я думал, они должны быть равны. Как я могу сделать так, чтобы они были?

6 ответов


strcmp является одной из немногих функций, которая имеет обратные результаты true и false...если строки равны, результат равен 0, а не 1, Как вы думаете....

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

говоря о fgets, существует вероятность того, что к концу строки прикреплена новая строка...вам нужно избавиться от него...

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

чтобы избавиться от newline сделать это. Предостережения: не используйте "strlen (aName) - 1", поскольку строка, возвращаемая fgets, может начинаться с символа NUL - таким образом, индекс в буфере становится 1:

aName[strcspn(aName, "\n")] = '';

+-+-+-+--+
|b|o|b||
+-+-+-+--+

теперь strcmp должна возвращать 0...


fgets читает, пока не увидит новую строку, затем возвращается, поэтому при вводе bob в консоли targetName содержит "bob\n", который не соответствует"bob". Из документации fgets: (выделено жирным шрифтом)

считывает символы из потока и сохраняет их в виде строки C в str, пока (num-1) символы не будут прочитаны или либо новая строка, либо конец файла не будет достигнут, в зависимости от того, что наступит раньше. символ новой строки останавливает чтение fgets, но считается допустимым символ, и поэтому он включен в строку, скопированную в str. Нулевой символ автоматически добавляется в str после того, как символы считываются, чтобы сигнализировать конец строки C.

перед сравнением необходимо удалить новую строку из конца targetName.

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

или добавьте новую строку в тестовую строку.

char targetName[50];
fgets(targetName,50,stdin);

char aName[] = "bob\n";
printf("%d",strcmp(aName,targetName));

потому что fgets-это embededing символ новой строки в переменную targetName. Это отбрасывает сравнение.


fgets добавляет \n к строке, которую вы вытаскиваете из пользователя, когда они нажимают Enter. Вы можете обойти это, используя strcspn или просто добавить \n на конец строки, которую вы пытаетесь сравнить.

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

это просто заменяет \n С , а если вы хотите быть ленивым, вы можете просто сделать это:

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)

но это не так элегантно.


fgets добавляет новую строку в строку, поэтому вы получите bob\n что не то же самое, что bob.


в основном из-за конца строки char на входе "\n" в unix-подобной системе.