Равные строки в strcmp () return 10 [duplicate]

Я получил подтвержденный ответ от STL от MSFT :

В отличие от VC, GCC не реализовал random_device недетерминированно в Windows. Boost, поэтому вы можете использовать Boost.Random.

6
задан Gilles 26 September 2012 в 10:35
поделиться

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|\0|
+-+-+-+--+--+

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

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

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

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

8
ответ дан Community 19 August 2018 в 12:12
поделиться
  • 1
    Спасибо, другие ответы были хорошими, но у вас было решение (я думал, что проблема может быть\n, но думала, что это могло бы быть и что-то еще), потому что вы включаете решение (и красивое изображение массива lol), я отмечены как лучшие. И да, теперь работает strcmp. – Blackbinary 8 March 2010 в 22:27
  • 2
    strcmp не отменяет результаты true и false. strcmp не возвращает логическое значение, оно возвращает целочисленное значение, основанное на том, как две строки связаны друг с другом. & quot; if (strcmp (a, b)) & quot; работает, но скрывает этот факт, поскольку, когда речь идет о интегральных значениях, "если" оператор будет рассматривать его как «if (n! = 0)». Более понятный способ записи этого будет «if (strcmp (a, b)! = 0)» которые прямо указывают на то, что тестируется. – Torlack 8 March 2010 в 22:35
  • 3
    @Torlack: или if (! Strcmp (a, b)) .... независимо от того, что вы говорите, все, что отличное от нуля, истинно, а ноль - false, поэтому мой акцент на него ... – t0mm13b 8 March 2010 в 22:57
  • 4
    yea, strcmp на самом деле возвращает 0, если они совпадают, в противном случае это будет некоторое отрицательное число, если оно меньше другого, или какое-то положительное, если одно больше другого (оно делает какую-то странную математику, ха-ха). Но оно инвертируется в путь, 0 - «истина» и 1 или любое другое число = ложь. Если вы просто думаете о возвращаемом значении как о «величине разницы», это имеет больше смысла. – Blackbinary 8 March 2010 в 23:25
  • 5
    Но ваше утверждение по-прежнему неверно, поскольку оно является обратным. Если то, что вы сказали, истинно, тогда «if (strcmp (a, b)! = True)» также будет правильным, но это не так (предполагая, что мы говорим о версии C или C ++ с правильной реализацией логического состояния, которое может иметь только состояние true и false). blogs.msdn.com/ericlippert/archive/2004/07/15/184431.aspx – Torlack 9 March 2010 в 16:24

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

0
ответ дан Blindy 19 August 2018 в 12:12
поделиться

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")] = '\0';
if(strcmp(temp, "ls") == 0 || strcmp(temp, "exit") == 0)

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

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)

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

1
ответ дан Gilles 19 August 2018 в 12:12
поделиться

Поскольку fgets вставляет символ новой строки в переменную targetName. Это отбрасывает сравнение.

1
ответ дан JaredPar 19 August 2018 в 12:12
поделиться

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

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

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

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

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

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

char aName[] = "bob\n";
printf("%d",strcmp(aName,targetName));
5
ответ дан John Knoeller 19 August 2018 в 12:12
поделиться
  • 1
    Я бы предложил использовать sizeof(targetName), не перекодировал его в fgets(). – mctylr 8 March 2010 в 22:27

В основном из-за конца строки char на входе «\n» в системе unix.

0
ответ дан user 19 August 2018 в 12:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: