2012-06-21 11 views
8

Mam podstawowy program, który porównuje dwa ciągi:Dlaczego strcmp jest nieznany?

#include <string> 
#include <iostream> 

using namespace std; 

int main (int argc, char *argv[]) { 
    if(strcmp (argv[0],"./test") != 0) { 
    cout << "not equal" << endl; 
    } else { 
    cout << "equal" << endl; 
    } 
    return 0; 
} 

kompiluje z gcc ale nie z brzękiem:

> clang -o test test_clang.cpp 
test_clang.cpp:7:6: error: use of undeclared identifier 'strcmp' 
    if(strcmp (argv[0],"./test") != 0) { 
    ^
1 error generated. 

Dlaczego nie skompilować z brzękiem?

EDYCJA: Ludzie stają się coraz trudniejsi na skutek przepełnienia stosu, do tego stopnia, że ​​waham się napisać pytanie. Powyższe pytanie ma prostą odpowiedź, w porządku, ale czy jest to normalne w przypadku głosowania w dół (dwukrotnie w pierwszej minucie!), Ponieważ mają prostą, ale nieoczywistą odpowiedź?

+0

Nie mam pojęcia, dlaczego ludzie go za to zabrali. Jest jasno określone i ważne pytanie. – aschepler

+0

"To pytanie nie wykazuje żadnych wysiłków badawczych". Pierwsze trafienie w Google dla "strcmp" ma przykład kodu z '#include ' (który jest również poprawnym rozwiązaniem). Minimalne badania mogłyby odpowiedzieć na to pytanie. Dlatego go obniżyłem. Nieznaczne pytania pomniejszają wartość tej strony. –

+2

Tworzenie minimalnego przykładu i porównywanie wyników dwóch kompilatorów to wysiłek badawczy. – aschepler

Odpowiedz

10

Zastosowanie

#include <string.h> 

lub

#include <cstring> 

zamiast

#include <string> 

ciąg nagłówek jest dla std :: string z C++. string.h jest dla C zero zakończone znakami char *. cstring jest jak string.h, ale dla C++.

Przyczyną działania gcc jest prawdopodobnie inny poziom ostrzeżenia/poziom błędu. Możliwe jest skompilowanie kodu bez #include nagłówka i deklaracji strcmp. Kompilator nie będzie mógł wykonać sprawdzenia typu, ale symbol nadal zostanie rozwiązany przez linker.

Można również unikać strcmp całkowicie i napisać

#include <string> 
#include <iostream> 

int main (int argc, char *argv[]) { 
    std::string command = argv[0]; 

    if(command != "./test") { 
    std::cout << "not equal" << endl; 
    } else { 
    std::cout << "equal" << endl; 
    } 
    return 0; 
} 

Korzystanie z std :: string na jednej stronie porównania spowoduje „./test” ciąg zostać przekształcony w std :: string oraz porównanie zostanie wykonane przez operatora == klasy std :: string.

+1

'string.h' jest nagłówkiem C; właściwym nagłówkiem C++ jest 'cstring', ponieważ zachowuje wszystko w' namespace std'. – Griwes

+0

@ Griwes OK, dobrze wiedzieć. Wydaje się, że nie ma żadnej wady użycia string.h, nawet w C++. –

+0

Przyjmuję tę odpowiedź jako zaakceptowaną, ponieważ daje wyjaśnienia, które znalazłem interesujące – Barth

10

Nie jesteś w tym poprawny plik nagłówek

#include <cstring> 
3

Trzeba to <cstring>. <string> jest nagłówkiem dla ciągów C++.

5

Trzeba #include <cstring> (lub ewentualnie #include <string.h>.)

Wiele kompilatorów zawierać dodatkowe nagłówki standardowe kiedy to drugie. Standard pozwala na to; Twoim obowiązkiem jest używanie nagłówków, które gwarantują deklaracje do użycia, a nie tylko nagłówków, które mają deklaracje kompilatora.

+0

'string.h' jest nagłówkiem C; tylko poprawny nagłówek C++ to 'cstring', ponieważ zachowuje wszystko w' namespace std'. – Griwes

+0

@DaveS, jakikolwiek dowód? Nie mogę znaleźć niczego, co byłoby przestarzałe w standardach. – Griwes

+0

@Griwes: Ooops. Całkowicie błędnie przeczytałem sekcję. Usunąłem komentarz. –