2010-10-12 13 views
15

Poniższe fragmenty kodu pochodzą z programu C.Porównywanie wprowadzanych przez użytkownika znaków w C

Użytkownik wprowadza Y lub N.

char *answer = '\0'; 

scanf (" %c", answer); 

if (*answer == ('Y' || 'y')) 
    // do work 

Nie mogę zrozumieć, dlaczego to if oświadczenie nie ocenia się prawdą.

Sprawdziłem dla wejścia y lub n z printf i jest tam, więc wiem, że otrzymuję dane wejściowe użytkownika. Również, gdy zastępuję warunek instrukcji if wartością 1 (czyniąc ją prawdą), to jest ona poprawnie obliczana.

Odpowiedz

22

Widzę dwa problemy:

Wskaźnik answer JEST null wskaźnik i próbujesz go usunąć w scanf, co prowadzi do nieokreślonego zachowania .

Nie potrzebujesz tutaj wskaźnika char. można po prostu użyć zmiennej char jak:

char answer; 
scanf(" %c",&answer); 

Dalej, aby sprawdzić, czy znak odczytu jest 'y' lub 'Y' należy zrobić:

if(answer == 'y' || answer == 'Y') { 
    // user entered y or Y. 
} 

Jeśli naprawdę trzeba użyć wskaźnika char ty może zrobić coś takiego:

char var; 
char *answer = &var; // make answer point to char variable var. 
scanf (" %c", answer); 
if(*answer == 'y' || *answer == 'Y') { 
+1

.. lub przez wywołanie 'malloc()' – Arun

+0

@ArunSaha: tak, lub spraw, aby wskazywało na lokalną zmienną char. – codaddict

+0

dlaczego konieczne jest wprowadzenie spacji przed% c w scanf? dla mnie nie działa, jeśli usunę spację przed% c w scanf. – hunch

9

answer nie powinien być wskaźnikiem, celem jest oczywiście przytrzymanie postaci. scanf trwa adres tej postaci, więc powinien być nazywany jako

char answer; 
scanf(" %c", &answer); 

Dalej, twój „lub” oświadczenie powstaje nieprawidłowo.

if (answer == 'Y' || answer == 'y') 

Co napisałeś początkowo prosi, aby porównać answer z wynikiem 'Y' || 'y', który Zgaduję nie jest całkiem to, czego chcieliśmy zrobić.

+0

Zmieniłem go, ale z jakiegoś powodu treść instrukcji if nadal nie jest warta oceny –

+0

@Joe, miał niewielką literówkę z dodatkowym tekstem, jeśli skopiowałeś i wkleiłeś z mojej odpowiedzi prawdopodobnie nie powiodło się. –

+0

Tak, złapałem literówkę, dziękuję –

5

Ponieważ porównanie nie działa w ten sposób. 'Y' || 'y' jest operatorem logicznym lub operatorem; zwraca 1 (true), jeśli którykolwiek z argumentów jest prawdziwy. Od 'Y' i 'y' są zarówno prawdziwe, jesteś porównując *answer z 1.

Co chcesz jest if(*answer == 'Y' || *answer == 'y') czy może:

switch (*answer) { 
    case 'Y': 
    case 'y': 
    /* Code for Y */ 
    break; 
    default: 
    /* Code for anything else */ 
} 
5

Na początek twój answer va riable powinno być typu char, a nie char*.

chodzi o rachunku if:

if (answer == ('Y' || 'y')) 

to pierwszy oceny 'Y' || 'y' które w operacji logicznych (i dla ASCII) jest prawdziwe, ponieważ obaj są "true" (non-zero).Innymi słowy, można dostać tylko oświadczenie if na ogień, gdybyś jakoś weszła CTRL (znów dla ASCII, i gdzie prawdziwe wartości równa się 1) * a.

Ty mógłby użyć bardziej poprawna:

if ((answer == 'Y') || (answer == 'y')) 

ale naprawdę powinny być przy użyciu:

if (toupper(answer) == 'Y') 

ponieważ jest to bardziej przenośne sposobem osiągnięcia tego samego celu.


* a Być może zastanawiasz się, dlaczego Kładę w różnego rodzaju warunkowych dla moich stwierdzeń. Podczas gdy zdecydowana większość implementacji C używa ASCII i niektórych znanych wartości, nie jest to wymagane przez normy ISO. Wiem na pewno, że przynajmniej jeden kompilator nadal używa EBCDIC, więc nie lubię robić nieuzasadnionych założeń.

Powiązane problemy