2012-06-21 10 views
8

tôi có một chương trình cơ bản mà so sánh hai chuỗi:Tại sao strcmp không biết kêu vang?

#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; 
} 

nó biên dịch với gcc nhưng không phải với kêu vang:

> 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. 

Tại sao nó không biên dịch với kêu vang?

CHỈNH SỬA: Mọi người đang nhận được khắc nghiệt trên tràn ngăn xếp, đến mức tôi đang do dự để đăng câu hỏi. Câu hỏi trên có một câu trả lời đơn giản, tốt, nhưng có bình thường với các câu hỏi bỏ phiếu xuống (hai lần trong phút đầu tiên!) Bởi vì họ có câu trả lời đơn giản, nhưng không rõ ràng?

+0

Tôi không biết tại sao mọi người lại bỏ phiếu này. Nó được tuyên bố rõ ràng và một câu hỏi hợp lệ. – aschepler

+0

"Câu hỏi này không hiển thị bất kỳ nỗ lực nghiên cứu nào". Lần truy cập đầu tiên trong Google cho "strcmp" có ví dụ mã với '#include ' (cũng là một giải pháp hợp lệ). Nghiên cứu tối thiểu sẽ trả lời câu hỏi này. Đó là lý do tại sao tôi downvoted nó. Các câu hỏi nhỏ nhặt làm giảm giá trị của trang web này. –

+2

Làm một ví dụ tối thiểu và so sánh kết quả trên hai trình biên dịch là nỗ lực nghiên cứu. – aschepler

Trả lời

10

Sử dụng

#include <string.h> 

hoặc

#include <cstring> 

thay vì

#include <string> 

Các chuỗi tiêu đề là cho std :: string từ C++. string.h dành cho C zero terminated char * strings. cstring giống như string.h nhưng đối với C++.

Lý do hoạt động với gcc có thể là các cài đặt mức cảnh báo/lỗi khác nhau. Có thể biên dịch mã mà không có # bao gồm tiêu đề và có khai báo strcmp. Trình biên dịch sẽ không thể thực hiện kiểm tra kiểu nhưng biểu tượng vẫn được giải quyết bởi trình liên kết.

Bạn cũng có thể tránh sử dụng strcmp hoàn toàn và viết

#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; 
} 

Sử dụng một std :: string ở một bên của sự so sánh sẽ gây ra "./test" chuỗi được chuyển đổi thành một std :: string và việc so sánh sẽ được thực hiện bởi toán tử == của lớp std :: string.

+1

'string.h' là tiêu đề C; tiêu đề C++ thích hợp là 'cstring', vì nó giữ mọi thứ trong' namespace std'. – Griwes

+0

@Griwes OK, rất hữu ích. Có vẻ như không có bất lợi của việc sử dụng string.h ngay cả trong C + + mặc dù. –

+0

Tôi lấy câu trả lời này như được chấp nhận vì nó đưa ra giải thích tôi thấy thú vị – Barth

10

Bạn sẽ không bao gồm đúng file header

#include <cstring> 
3

Bạn phải bao gồm <cstring>. <string> là tiêu đề cho chuỗi C++.

5

Bạn cần phải #include <cstring> (hoặc có thể #include <string.h>.)

Nhiều trình biên dịch bao gồm các tiêu chuẩn thêm khi bạn bao gồm khác. Tiêu chuẩn cho phép điều này; bạn có trách nhiệm sử dụng các tiêu đề đảm bảo khai báo cho những gì bạn sử dụng, không chỉ các tiêu đề xảy ra để có các khai báo cho trình biên dịch của bạn.

+0

'string.h' là C header; chỉ tiêu đề C++ thích hợp là 'cstring', vì nó giữ mọi thứ trong' namespace std'. – Griwes

+0

@DaveS, bất kỳ bằng chứng nào? Tôi không thể tìm thấy bất cứ điều gì về họ bị phản đối trong tiêu chuẩn. – Griwes

+0

@Griwes: Rất tiếc. Tôi hoàn toàn hiểu sai phần. Tôi đã xóa nhận xét. –