Сравнение введенных пользователем символов в C

Ниже перечислены фрагменты кода из программы C.

Пользователь вводит Y или N.

char *answer = '\0';

scanf (" %c", answer);

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

Я не могу понять, почему этот оператор if не оценивает true.

Я проверил вход y или n с printf, и он есть, поэтому я знаю, что получаю вход пользователя. Также, когда я заменяю условие оператора if 1 (делая его истинным), он правильно оценивает.

Ответы

Ответ 1

Я вижу две проблемы:

Указатель answer является указателем null, и вы пытаетесь разыменовать его в scanf, это приводит к поведению undefined.

Здесь вам не нужен указатель char. Вы можете просто использовать переменную char как:

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

Далее, чтобы увидеть, есть ли символ чтения 'y' или 'y':

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

Если вам действительно нужно использовать указатель char, вы можете сделать что-то вроде:

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

Ответ 2

answer не должен быть указателем, целью, очевидно, является удерживание символа. scanf берет адрес этого символа, поэтому его следует вызывать как

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

Затем ваш оператор "или" формируется неправильно.

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

То, что вы написали первоначально, требует сравнить answer с результатом 'Y' || 'y', который, как я предполагаю, не совсем то, что вы хотели сделать.

Ответ 3

Потому что сравнение не работает. 'Y' || 'y' - логический или оператор; он возвращает 1 (true), если любой из его аргументов истинен. Поскольку 'Y' и 'Y' оба истины, вы сравниваете *answer с 1.

Вы хотите if(*answer == 'Y' || *answer == 'y') или возможно:

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

Ответ 4

Для начала ваша переменная answer должна иметь тип char, а не char*.

Что касается оператора if:

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

Сначала оценивается 'Y' || 'y', который в логической логике (и для ASCII) истинен, поскольку оба они являются "истинными" (отличными от нуля). Другими словами, вы должны только запустить инструкцию if, если бы вы каким-то образом ввели CTRL A (опять же, для ASCII и где истинные значения равны 1) * a.

Вы можете использовать более правильные:

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

но вы действительно должны использовать:

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

так как это более портативный способ достичь того же конца.


* a Вам может быть интересно, почему я ввожу во всевозможные условные выражения для своих утверждений. В то время как подавляющее большинство реализаций C использует ASCII и некоторые известные значения, это не обязательно предусмотрено стандартами ISO. Я знаю, что по крайней мере один компилятор по-прежнему использует EBCDIC, поэтому мне не нравится делать необоснованные предположения.