Язык программирования C: поведение strcmp (str1, str2) - PullRequest
0 голосов
/ 19 апреля 2010

В C у меня есть массив символов:

d[20] 

Которому присваивается значение if с нулевым символом завершения:

d[0]='i'
d[1]='f'
d[2]='\0'

Должно ли значение strcmp(d,"if") быть 0? Зачем?

Я ожидаю, что strcmp вернет значение 0. Когда я запускаю его, я получаю значение -1

Ответы [ 6 ]

6 голосов
/ 19 апреля 2010

Если вы имеете в виду d[0] = 'i'; d[1] = 'f'; d[2] = '\0';, то да, это должно вернуть 0. d[2] = '/0' назначит что-то совершенно другое, и ваша строка не будет завершена нулем. По крайней мере, не там, где вы ожидаете - strcmp, вероятно, уйдет в сорняки и начнет сосать грязь.

2 голосов
/ 19 апреля 2010

@ всем: опечатка '/ 0' была введена @Mark, когда он редактировал оригинальный вопрос. Оригинал имел правильное значение \ 0. Большинство ваших ответов (и предположений об ОП) неверно направлены.

@ mekasperasky Следующий код правильно выдает значение 0. Если вы можете сравнить его с вашим личным кодом и найти разницу, возможно, вы решили свою проблему.

int main(int argc, char* argv[])
{
   char d[20] = {0};
   d[0] = 'i';
   d[1] = 'f';
   d[2] = '\0';

   int value = strcmp(d,"if");
   cout << value << endl;
   return 0;
}
1 голос
/ 19 апреля 2010

Это работает на каждом компиляторе C, который у меня есть. Я не ожидал иначе. Он также работает на Codepad .

Это работает на вашем компиляторе C?

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

char d[20];

int main(void) {
   d[0]='i';
   d[1]='f';
   d[2]='\0';

   printf("Value of strcmp=%i\n\n",strcmp(d,"if"));  /* will print 0 */

   return 0;
}
1 голос
/ 19 апреля 2010

Как уже упоминалось в других ответах, '/0' не является нулевым символом завершения, '\0' - это.

Можно ожидать, что указание более одного символа в символьном литерале может привести к ошибке; к сожалению (по крайней мере, в этом случае) C допускает использование «многосимвольных» литеральных символов, но точное поведение многосимвольных литералов определяется реализацией (6.4.4.4/2 «Символьные константы»):

Целочисленная символьная константа имеет тип int. Значение целочисленной символьной константы, содержащей один символ, который отображается на однобайтовый исполнительный символ, является числовым значением представления сопоставленного символа, интерпретируемого как целое число. Значение целочисленной символьной константы, содержащей более одного символа (например, 'ab'), или содержащей символ или escape-последовательность, которая не отображается на однобайтовый символ выполнения, определяется реализацией.

Таким образом, ваш '/0' 'символ' в конечном итоге становится неким значением int, определяемым реализацией, которое усекается при сохранении в d[2]. Ваш компилятор может сгенерировать предупреждение для многосимвольных литералов, но это, вероятно, также будет зависеть от конкретных параметров, которые вы предоставляете компилятору.

Например, я получаю следующее предупреждение от GCC (у меня установлена ​​опция -Wall):

C:\temp\test.cpp:6:14: warning: multi-character character constant

В моих тестах с MSVC и MinGW значение '/0' равно 0x00002f30, поэтому d[2] = '/0' в итоге эквивалентно d[2] = '0'.

1 голос
/ 19 апреля 2010

Нулевое значение обозначается как:

d[2]='\0'

а не / 0, как вы написали.

1 голос
/ 19 апреля 2010

d[2] должно быть '\0', а не '/0'.

...