2009-08-25 118 views
28

Tôi đang cố gắng để so sánh một mảng nhân vật chống lại một chuỗi như vậy:C++ Hãy so sánh mảng char với chuỗi

const char *var1 = " "; 
var1 = getenv("myEnvVar"); 

if(var1 == "dev") 
{ 
    // do stuff 
} 

này nếu tuyên bố không bao giờ xác nhận là đúng ... khi tôi var1 đầu ra nó là "dev" , Tôi đã suy nghĩ có lẽ nó có cái gì để làm với một chuỗi chấm dứt null, nhưng strlen của "dev" và var1 bằng nhau ... Tôi cũng nghĩ có lẽ var1 == "dev" đã so sánh "dev" với vị trí bộ nhớ của var1 thay vì giá trị. * var1 == "dev" kết quả trong một lỗi .... đã thử nhiều thứ, có lẽ là một giải pháp đơn giản cho nhà phát triển davy d ++ (tôi havent được mã hóa C++ trong một thời gian dài).

chỉnh sửa: chúng tôi đã cố gắng

if(strcmp(var1, "dev") == 0) 

if(strncmp(var1, "dev", 3) == 0) 

Cảm ơn

chỉnh sửa: Sau khi thử nghiệm ở nhà tôi chỉ cần đi để đề nghị thay đổi đồng nghiệp của tôi datatype vào một chuỗi. Tôi tin rằng ông đã so sánh một mảng char có kích thước lớn với một chuỗi. Tôi đặt cùng một chương trình mà kết quả đầu ra sizeof, strlen, vv để giúp chúng tôi làm việc thông qua nó. Xin cảm ơn tất cả mọi người vì đã giúp đỡ.

+1

Hình như bạn đang sử dụng chuỗi C thô và không phải là lớp C++ String. – tchen

+2

thử sử dụng trình gỡ lỗi để xem liệu var1 có thực sự được điền bằng "dev1" hay không. Ngoài ra, nếu var1 thực sự là một chuỗi kiểu C++, hãy sử dụng hàm c_str() để lấy chuỗi kiểu c có thể được so sánh với char * của bạn bằng strcmp(); – NomeN

+0

Bạn đã thử strcmp; tuyệt vời - kết quả là gì?(Vì đó là một cách tốt để đi) – xtofl

Trả lời

56

Sử dụng strcmp() để so sánh nội dung của chuỗi:

if (strcmp(var1, "dev") == 0) { 
} 

Giải thích: trong C, một chuỗi là một con trỏ đến một vị trí bộ nhớ chứa byte. So sánh char* với số char* bằng toán tử bình đẳng sẽ không hoạt động như mong đợi, bởi vì bạn đang so sánh các vị trí bộ nhớ của các chuỗi thay vì nội dung byte của chúng. Một hàm như strcmp() sẽ lặp qua cả hai chuỗi, kiểm tra các byte của chúng để xem chúng có bằng nhau hay không. strcmp() sẽ trả về 0 nếu chúng bằng nhau và giá trị khác 0 nếu chúng khác nhau. Để biết thêm chi tiết, hãy xem manpage.

+0

Chúng tôi cũng đã thử điều đó và nó không hoạt động không may –

+3

@Chris: bạn có thể đăng một ví dụ về cách bạn đang sử dụng 'strcmp()' không? Nếu không, chúng tôi sẽ không biết làm thế nào nó "không hoạt động". –

+0

Bạn có chắc chắn bạn không làm gì nếu (strcmp (var1, "dev"))? Một cái bẫy dễ dàng để rơi vào với strcmp ... –

1

Trong mã này bạn không so sánh các giá trị chuỗi, bạn đang so sánh giá trị con trỏ. Nếu bạn muốn so sánh các giá trị chuỗi, bạn cần sử dụng hàm so sánh chuỗi như strcmp.

if (0 == strcmp(var1, "dev")) { 
    .. 
} 
+3

Ohhh. Tôi ghét đặt 0 ở bên trái (ý kiến ​​cá nhân rõ ràng). Tôi nghĩ rằng nó là trực giác hơn ở bên phải và kể từ khi bạn đang thử nghiệm kết quả chống lại một chức năng không có cơ hội phân công. –

+5

Tôi gọi đây là "Mã hóa Yoda" (ngược lại là biểu thức, hmmm?). Tôi muốn sử dụng các tùy chọn biên dịch để bắt các bài tập ngẫu nhiên. –

+0

@Fred đồng ý với bạn tôi thì không. :) – JaredPar

0

"dev" không phải là một string nó là một const char * như var1. Vì vậy, bạn đang thực sự so sánh các địa chỉ bộ nhớ. Là var1 là một con trỏ char, *var1 là một char đơn (ký tự đầu tiên của chuỗi ký tự được trỏ đến chính xác). Bạn không thể so sánh một char với con trỏ char, đó là lý do tại sao nó không hoạt động.

Vì điều này được gắn thẻ là C++, nên sử dụng std::string thay vì con trỏ char, điều này sẽ làm cho == hoạt động như mong đợi. (Bạn sẽ chỉ cần làm const std::string var1 thay vì const char *var1.

16

Bạn đang không làm việc với chuỗi. Bạn đang làm việc với con trỏ. var1 là một con trỏ char (const char*). Nó không phải là một chuỗi. Nếu đó là null-chấm dứt, sau đó một số chức năng C sẽ điều trị nó như là một chuỗi, nhưng về cơ bản nó chỉ là một con trỏ. trình biên dịch sau đó cố gắng tìm một số operator == (const char*, const char*).

Toán tử như vậy không tồn tại. Phải mất hai con trỏ và trả về true nếu chúng trỏ đến cùng một địa chỉ. Vì vậy, trình biên dịch gọi đó, và mã của bạn bị hỏng.

Nếu bạn muốn so sánh chuỗi, bạn phải thông báo cho trình biên dịch rằng bạn muốn xử lý các chuỗi , không phải con trỏ.

C cách để làm điều này là sử dụng các chức năng strcmp:

strcmp(var1, "dev"); 

này sẽ trả lại bằng không nếu hai chuỗi là bằng. (Nó sẽ trả về một giá trị lớn hơn 0 nếu phía bên tay trái là lớn hơn từ bên tay phải, và giá trị nhỏ hơn 0.)

Vì vậy, để so sánh sự bình đẳng, bạn cần thực hiện một trong các cách sau:

if (!strcmp(var1, "dev")){...} 
if (strcmp(var1, "dev") == 0) {...} 

Tuy nhiên, C++ có lớp học rất hữu ích string. Nếu chúng ta sử dụng mã của bạn trở nên đơn giản hơn một chút. Dĩ nhiên chúng ta có thể tạo ra chuỗi từ cả hai lập luận, nhưng chúng ta chỉ cần làm điều đó với một trong số họ:

std::string var1 = getenv("myEnvVar"); 

if(var1 == "dev") 
{ 
    // do stuff 
} 

Bây giờ trình biên dịch gặp một so sánh giữa chuỗi và con trỏ char. Nó có thể xử lý điều đó, bởi vì một con trỏ char có thể được chuyển đổi hoàn toàn thành một chuỗi, sinh ra một chuỗi so sánh chuỗi. Và những hành vi chính xác như bạn mong đợi.

+1

Đá giải thích này, _and_ khuyên std :: string là tốt! Tôi đọc nó lần đầu tiên :) – xtofl

+0

Một cái bẫy thú vị với điều này là chuỗi gấp, trong thử nghiệm xây dựng bản phát hành với "foo" == "foo" có thể sẽ đúng khi chúng trở thành con trỏ tới cùng một chuỗi, nhưng gỡ lỗi có chuỗi gấp lại và nó sẽ thất bại – paulm

0

Có chức năng ổn định hơn, đồng thời loại bỏ chuỗi gấp.

// Add to C++ source 
bool string_equal (const char* arg0, const char* arg1) 
{ 
    /* 
    * This function wraps string comparison with string pointers 
    * (and also works around 'string folding', as I said). 
    * Converts pointers to std::string 
    * for make use of string equality operator (==). 
    * Parameters use 'const' for prevent possible object corruption. 
    */ 
    std::string var0 = (std::string) arg0; 
    std::string var1 = (std::string) arg1; 
    if (var0 == var1) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

Và thêm tuyên bố để tiêu đề

// Parameters use 'const' for prevent possible object corruption. 
bool string_equal (const char* arg0, const char* arg1); 

Đối với việc sử dụng, chỉ cần đặt một cuộc gọi 'string_equal' như điều kiện của if (hoặc ternary) tuyên bố/block.

if (string_equal (var1, "dev")) 
{ 
    // It is equal, do what needed here. 
} 
else 
{ 
    // It is not equal, do what needed here (optional). 
} 

Nguồn: sinatramultimedia/fl32 codec (nó được viết bởi bản thân mình)

0

suy nghĩ của bạn về chương trình này dưới

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

int main() 
{ 
char str[][5] = { "R2D2" , "C3PO" , "R2A6" }; 
int n; 
puts ("Looking for R2 astromech droids..."); 
for (n=0 ; n<3 ; n++) 
if (strncmp (str[n],"R2xx",2) == 0) 
{ 
    printf ("found %s\n",str[n]); 
} 
return 0; 
} 
//outputs: 
// 
//Looking for R2 astromech droids... 
//found R2D2 
//found R2A6 

khi bạn nên suy nghĩ về nhập cái gì đó vào một mảng & sau đó sử dụng các hàm strcmp giống như chương trình trên ... hãy xem chương trình đã sửa đổi bên dưới

#include <iostream> 
#include<cctype> 
#include <string.h> 
#include <string> 
using namespace std; 

int main() 
{ 
int Students=2; 
int Projects=3, Avg2=0, Sum2=0, SumT2=0, AvgT2=0, i=0, j=0; 
int Grades[Students][Projects]; 

for(int j=0; j<=Projects-1; j++){ 
    for(int i=0; i<=Students; i++) { 
cout <<"Please give grade of student "<< j <<"in project "<< i << ":"; 
    cin >> Grades[j][i]; 

    } 
    Sum2 = Sum2 + Grades[i][j]; 
    Avg2 = Sum2/Students; 
} 
SumT2 = SumT2 + Avg2; 
AvgT2 = SumT2/Projects; 
cout << "avg is : " << AvgT2 << " and sum : " << SumT2 << ":"; 
return 0; 
} 

thay đổi chuỗi trừ nó chỉ đọc 1 đầu vào và ném phần còn lại ra có lẽ cần hai cho các vòng lặp và hai con trỏ

#include <cstring> 
#include <iostream> 
#include <string> 
#include <stdio.h> 
using namespace std; 
int main() 
{ 
char name[100]; 
//string userInput[26]; 
int i=0, n=0, m=0; 
cout<<"your name? "; 
cin>>name; 
cout<<"Hello "<<name<< endl; 

char *ptr=name; 
for (i = 0; i < 20; i++) 
{ 
cout<<i<<" "<<ptr[i]<<" "<<(int)ptr[i]<<endl; 
} 
int length = 0; 
while(name[length] != '\0') 
{ 
length++; 
} 
        for(n=0; n<4; n++) 
       { 
          if (strncmp(ptr, "snit", 4) == 0) 
          { 
      cout << "you found the snitch " <<  ptr[i]; 
          } 
       } 
cout<<name <<"is"<<length<<"chars long"; 
}