Я понимаю странное поведение strcmp
функция, которая будет проиллюстрирована следующим кодом:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char *p = "no";
cout << p << endl; //Output: no
cout << &p << endl; //Output: 0x28ac64
cout << strlen(p) << endl; //Output: 2
cout << strcmp(p, "no") << endl; //Output: 0
cin >> p; //Input: bo
cout << p << endl; //Output: bo
cout << &p << endl; //Output: 0x28ac64
cout << strlen(p) << endl; //Output: 2
cout << strcmp(p, "no") << endl; //Output: 0
return 0;
}
Я не понимаю, почему в строке 15 выводится 0. 0 означает, что две строки равны, что явно не так. Что мне здесь не хватает?
Постскриптум Я прошу прощения за escape-символы в заголовках, но не смог отобразить iostream, если убрал его. Хотя я публикую это, я пойму, как сделать это правильно в следующий раз. 🙂
Проблема в том, что p
указывает на строковый литерал, поэтому ваша попытка изменить строковый литерал с помощью cin >> p;
ведет непосредственно к неопределенному поведению.
Скорее всего, происходит то, что компилятор обрабатывает строковый литерал как константу (поскольку вы не должны его изменять) и, следовательно, (во время компиляции) определяете, какой результат получается strcmp
должно быть, и производит это. Тот факт, что вы изменяете его во время выполнения, игнорируется, потому что вы все равно не должны этого делать.
К сожалению для совместимости многие компиляторы поддерживают это:
char *p = "no";
Что не должно компилироваться и исправляться:
const char *p = "no";
Если вы исправите это (и по крайней мере получите предупреждение), вы увидите, в чем заключается проблема со следующими ошибками компиляции.
p
указывает на первый элемент массива const char
, Попытка изменить эти значения (как вы делаете в cin >> p
) вызывает неопределенное поведение.