在C语言中比较用户输入的字符

16

下面的代码片段来自一个C程序。

用户输入Y或N。

char *answer = '\0';

scanf (" %c", answer);

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

我不明白为什么这个if语句的判断结果为假。

我使用printf检查了输入的y或n,确认我已经得到了用户的输入。而且当我将if语句的条件替换为1(使其为真)时,它可以正确地求值。

4个回答

22

我看到两个问题:

answer指针是一个null指针,而你正试图在scanf中引用它,这会导致未定义行为

你不需要在这里使用char指针。你可以直接使用char变量,例如:

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

要检查读取的字符是否为'y''Y',您应该执行以下操作:

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

如果你真的需要使用字符指针,你可以这样做:

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

为什么在 scanf 中 %c 前面要加一个空格?如果我在 scanf 中去掉 %c 前面的空格,它就不能正常工作。 - hunch
1
@hunch 从 man 手册 (scanf(3)) 中可以看到:[...对于类型修饰符 "c" ...] 通常会跳过前导的空白字符。如果要先跳过空格,请在格式中使用显式空格。[...]我猜测你的输入流中可能还有一些空格,当你访问该流时,这些空格就会弹出来,从而“跳过”了 scanf。我猜你已经发现了这一点... - Haini

9

answer不应该是一个指针,显然意图是要保存一个字符。 scanf 取这个字符的地址,因此应该这样调用:

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

接下来,你的“或”语句构造有误。
if (answer == 'Y' || answer == 'y')

您原先写的是要将answer'Y' || 'y'的结果进行比较,我猜想这不是您想要的。

我已经修改了它,但由于某种原因,if语句的主体仍未被评估。 - Joe Scho
@Joe,有一个小错误,多了一个括号,如果你从我的答案中复制粘贴,可能会失败。 - Mark Elliot

5

因为比较并不是这样工作的。'Y' || 'y' 是一个逻辑或运算符;如果它的任意一个参数为真,则返回1(真)。由于'Y''y'都为真,所以你正在将*answer与1进行比较。

你想要的是 if(*answer == 'Y' || *answer == 'y') 或者可能是:

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

5
首先,你的answer变量应该是char类型,而不是char*
至于if语句:
if (answer == ('Y' || 'y'))

这里首先评估了'Y' || 'y',在布尔逻辑中(对于ASCII),由于它们都是“true”(非零),所以结果为真。换句话说,只有在某种方式下输入了CTRLA(对于ASCII,在那里真值等于1)*a,您才会让if语句执行。

您也可以使用更正确的写法:

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

但是你真的应该使用:

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

因为这是实现同样目的最便携的方式,所以我建议使用它。


*a 你可能会想为什么我的陈述中要加入各种条件。虽然绝大多数的C语言实现都使用ASCII和特定的已知值,但这并不一定是ISO标准规定的。我知道至少有一种编译器仍在使用EBCDIC,所以我不喜欢做出没有根据的假设。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接