2013-06-10 86 views
7

Tôi gặp sự cố khi so sánh hai ký tự. Tôi đã viết một bài toán C cơ bản để thử các đối số dòng lệnh.C - So sánh hai ký tự

Đây là mã của tôi cho đến nay:

#include <stdio.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) { 
    char ch; 
    char *type = ""; 
    char *gender = ""; 
    int baby = 0; 
    int count = 0; 

    /* Options: 
    * -t = type of pet 
    * -g = gender 
    * -b = baby or adult 
    */ 
    while ((ch = getopt(argc, argv, "t:g:b")) != EOF) 
     switch (ch) { 
      case 't': 
       type = optarg; 
       break; 
      case 'g': 
       gender = optarg; 
       break; 
      case 'b': 
       baby = 1; 
       break; 
      default: 
       fprintf(stderr, "Invalid option.\n"); 
       return 1; 
     } 

    argc -= optind; 
    argv += optind; 

    printf("You have chosen a %s.\n", type); 
    if (gender == 'f') 
     puts("It's a girl"); 
    if (gender == 'b') 
     puts("It's a boy."); 

    // The main command line arguments should be about the traits of the pet 
    printf("%s", "Traits: "); 
    for (count = 0; count < argc; count++) 
     printf("%s ", argv[count]); 

    return 0; 
} 

Vì vậy, nếu tôi gõ này vào thiết bị đầu cuối:

$ ./pet_shop -t dog -g f cute small 

tôi có được điều này là đầu ra:

You have chosen a dog: 
    Traits: cute small 

Sản lượng nó thiếu thông tin về giới tính, nó phải là một cô gái kể từ khi tôi bước vào f. Nhưng tôi đã thử kiểm tra bằng printf ("% i", giới tính) đưa ra giá trị 0. Có phải g == 'f' không chính xác cách so sánh hai ký tự không?

+2

Các định nghĩa như 'char * type =" ";' chỉ đọc, tức là bạn không thể gán trực tiếp chuỗi cho 'type' khi bạn đã khai báo nó. Đọc qua thông tin này - http://msdn.microsoft.com/en-us/library/8kc54dd5(v=vs.80).aspx – Nobilis

+1

Bật cảnh báo trình biên dịch (ví dụ: với '-Wall' của GCC) và các lỗi như thế này sẽ dễ dàng được tìm thấy. – interjay

+3

@Nobilis: Bạn chắc chắn có thể gán thứ cho 'loại'. Bạn không thể viết vào giá trị được chỉ định nhưng OP không làm điều đó. – interjay

Trả lời

3

Vấn đề là bạn đang so sánh một chuỗi (hoặc đúng hơn, một char*) với một số char. So sánh này (ví dụ: if(gender == 'f')) sẽ so sánh giá trị con trỏ thô với ký tự thay vì so sánh nội dung của chuỗi với ký tự. Thay vào đó, bạn cần phải dereference con trỏ và sau đó so sánh giá trị đó, hoặc chỉ mục vào chuỗi, tức là if(gender[0] == 'f').

Tất nhiên, bạn cũng nên kiểm tra xem chuỗi có chứa nội dung nào đó trước khi cố gắng để tránh bị phân đoạn không.

+1

Điều này cho kết quả dương tính giả nếu 'giới tính' là bất kỳ chuỗi nào bắt đầu bằng' 'f''. – interjay

4

Bạn có:

char *gender = ""; 

Vì vậy gender là một chuỗi, không phải là một nhân vật. Để so sánh các chuỗi, hãy sử dụng strcmp.

15

genderchar*, tức là một con trỏ đến bộ lọc đầu tiên của chuỗi. Khi bạn so sánh nó với một đơn char, cả hai char và con trỏ được chuyển đổi thành số nguyên và so sánh số nguyên được thực hiện.

Để so sánh chuỗi, sử dụng strcmp từ <string.h>:

if (strcmp(gender, "f") == 0) 
    // it's a girl 

Lưu ý các dấu nháy kép (") mà biểu thị một chuỗi, chứ không phải là một nhân vật duy nhất.

+3

Strcmp là một chút ... quá mức cần thiết để so sánh một ký tự đơn – slugonamission

+2

@slugonamission: viết dễ dàng hơn nhiều so với 'giới tính [0] == 'f' && giới tính [1] == '\ 0''. Nó có khả năng sẽ được inlined khi được sử dụng với một chuỗi ngắn chữ và hiệu suất không thực sự quan trọng trong chương trình này. –

+0

Điều này không hiệu quả đối với tôi :( – Alex

4

Bạn đầu tiên tuyên bố giới tính như là một chuỗi:

char *gender = ""; 

Sau đó, bạn điều trị sau đó là như một nhân vật duy nhất:

if(gender == 'f') 
    [...] 
if(gender == 'b') 

Bạn cần phải làm rõ trong tâm trí của riêng bạn những gì gender là, trước khi bạn thử và mã nó.
Chọn một định nghĩa và gắn với định nghĩa đó.