2013-03-03 4 views
0

Я имею понимание странное поведение strcmp функции, которая будет проиллюстрировано следующим кодом:STRCMP не ведет себя так, как и ожидалось, возвращает 0 при сравнении двух неравных строк

#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 означает, что две строки равны, что явно не так. Что мне здесь не хватает?

P.S. Я извиняюсь за escape-символы в заголовках, но я не смог отобразить iostream, если я удалю его. Хотя я публикую это, я выясню, как правильно это сделать в следующий раз. :)

+2

'cin >> p;' - Здесь мы идем снова. – chris

+0

Кстати, есть это действительно полезное предупреждение, доступное в GCC: 'warning: debrecated conversion from string constant to 'char *' [-Wwrite-stringings]' – chris

+0

@chris, если OP компилирует это с помощью gcc – Slava

ответ

6

Проблема заключается в том, что p указывает на строковый литерал, поэтому ваша попытка изменить строковый литерал с помощью cin >> p; ведет непосредственно к неопределенному поведению.

Скорее всего, происходит то, что компилятор обрабатывает строковый литерал как постоянный (поскольку вы не должны его модифицировать), и поэтому (во время компиляции) определяете, что должен быть результатом от strcmp, и , Тот факт, что вы изменяете его во время выполнения, игнорируется, потому что вы все равно не должны этого делать.

1

p указывает на первый элемент массива const char. Попытка изменить эти значения (как вы делаете в cin >> p) вызывает неопределенное поведение.

3

К сожалению, для совместимости многие компиляторы поддерживают это:

char *p = "no"; 

Который должен не компилировать и правильным является:

const char *p = "no"; 

Если вы исправить это (и вы должны получить, по крайней мере, предупреждение), вы увидите, что является проблемой при следующих ошибках компиляции.