2013-06-10 16 views
7

Mam problem z porównaniem dwóch znaków. Napisałem bardzo prosty problem z C, aby wypróbować argumenty wiersza poleceń.C - Porównanie dwóch znaków

Oto mój kod do tej pory:

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

Więc jeśli wpisz w terminalu:

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

uzyskać to jako wyjście:

You have chosen a dog: 
    Traits: cute small 

Wyjście IT brakujące informacje na temat płci, to powinna być dziewczyna odkąd wszedłem do f. Ale próbowałem sprawdzić przez printf ("% i", płeć), które dało wartość 0. Czy g == "f" to niewłaściwy sposób porównywania dwóch znaków?

+2

Definicje takie jak "char * type =" ";' są tylko do odczytu, tzn. Nie można bezpośrednio przypisać ciągów do 'type' po ich zadeklarowaniu. Zapoznaj się z tym - http://msdn.microsoft.com/en-us/library/8kc54dd5(v=vs.80).aspx – Nobilis

+1

Włącz ostrzeżenia kompilatora (np. Z '-Wall 'GCC) i błędy takie jak ten będzie łatwo znaleźć. – interjay

+3

@Nobilis: Możesz na pewno przypisać rzeczy do 'type'. Nie można pisać na wskazaną wartość, ale OP tego nie robi. – interjay

Odpowiedz

3

Problem polega na porównaniu napisu (lub raczej, char*) z char. To porównanie (tj. if(gender == 'f')) porówna wartość surowego wskaźnika z charakterem zamiast porównywania zawartości ciągu do znaku. Zamiast tego należy wyłuskać wskaźnik, a następnie porównać tę wartość lub indeksować ciąg znaków, tj. if(gender[0] == 'f').

Oczywiście, dobrze byłoby sprawdzić, czy łańcuch faktycznie zawiera coś, zanim spróbuje tego, aby uniknąć segfault.

+1

Daje to fałszywy alarm, jeśli "gender" to dowolny ciąg rozpoczynający się od ''f''. – interjay

4

Masz:

char *gender = ""; 

Więc gender jest ciągiem znaków, a nie charakter. Aby porównać łańcuchy, użyj strcmp.

15

gender to char*, tj. Wskaźnik do pierwszego znaku karadowego ciągu. Gdy porównamy to z pojedynczym char, zarówno char, jak i wskaźnik są konwertowane na liczby całkowite i wykonywane jest porównanie liczb całkowitych.

Do porównywania ciągów znaków, należy strcmp z <string.h>:

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

Uwaga podwójny cudzysłów (") co oznacza ciąg znaków, zamiast pojedynczego znaku.

+3

Strcmp to trochę ... przesada, aby porównać pojedynczy znak – slugonamission

+2

@usunkcja: łatwiej pisać niż "gender [0] == 'f' && gender [1] == '\ 0''. Najprawdopodobniej zostanie on wprowadzony, gdy użyje się go krótką literałem, a wydajność nie jest tak istotna w tym programie. –

+0

To nie działa dla mnie :( – Alex

4

najpierw ogłosił płci jako wyrażenie:

char *gender = ""; 

Wtedy później traktować to jako pojedynczy znak:

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

Trzeba wyjaśnić w swoim własnym umyśle, co gender jest przed wami spróbuj i zakoduj to.
Wybierz jedną definicję i trzymaj się jej.

Powiązane problemy