我正在编写需要限制用于输入仅从A
到H
的字符的代码。不应接受大于H
。
我看到数字我可以使用它:
if (input == 0 - 9) return 1;
但是,我如何做到A
到H
(char
)?
答案 0 :(得分:5)
C标准没有规定字符编码应该是ASCII,尽管很可能。尽管如此,编码可能是其他(例如EBCDIC),并且拉丁字母的字符可能不会以连续的顺序编码。这会导致直接比较char
值的解决方案出现问题。
一种解决方案是创建一个包含有效输入字符的字符串,并使用strchr()
在此字符串中搜索输入以进行验证:
#include <stdio.h>
#include <string.h>
int main(void)
{
char *valid_input = "ABCDEFGH";
char input;
printf("Enter a letter from 'A' - 'H': ");
if (scanf("%c", &input) == 1) {
if (input == '\0' || strchr(valid_input, input) == NULL) {
printf("Input '%c' is invalid\n", input);
} else {
puts("Valid input");
}
}
return 0;
}
这种方法是可移植的,但比较ASCII值的解决方案可能在实践中有效。请注意,在我发布的原始代码中,错过了一个边缘案例,如@chux所指出的那样。可以从键盘输入'\0'
字符(或通过其他方法获取一个字符),并且由于字符串包含'\0'
字符,因此这将被接受为有效输入。我已更新验证码以检查此情况。
使用上述解决方案还有另一个优点。请考虑以下比较样式代码:
if (input >= 'A' || input <= 'H') {
puts("Valid input");
} else {
puts("Invalid input");
}
现在,假设有效输入的条件发生变化,并且必须修改程序。修改验证字符串更简单,例如更改为:
char *valid_input = "ABCDEFGHIJ";
使用可能出现在多个位置的比较代码,必须在代码中找到每个比较。但是使用验证字符串,只需要找到并修改一行代码。
此外,验证字符串对于更复杂的要求更简单。例如,如果有效输入是范围'A' - 'I'
中的字符或范围'0' - '9'
中的字符,则验证字符串可以简单地更改为:
char *valid_input = "ABCDEFGHI0123456789";
比较方法看起来很笨重:
if ((input >= 'A' && input <= 'I') || (input >= '0' && input <= '9')) {
puts("Valid input");
} else {
puts("Invalid input");
}
请注意,C标准对字符编码的几个要求之一是字符'0', ..., '9'
以连续的顺序编码。 允许对十进制数字进行便携式直接比较,也可以通过减法可靠地找到与十进制数字相关的整数值:
char ch = '3';
int num;
if (ch >= '0' && ch <= '9') {
printf("'%c' is a decimal digit\n", ch);
num = ch - '0';
printf("'%c' represents integer value %d\n", ch, num);
}
答案 1 :(得分:4)
您在此处提供的if语句等于:
if (input == -9) return 1;
在return 1
等于input
的情况下-9
,因此根本没有范围检查。
要允许从0
到9
的数字,您必须比较如下:
if (input >= 0 && input <= 9) /* range valid */
或您想要的字符(A
到H
) 1 :
if (input >= 'A' && input <= 'H') /* range valid */
如果您希望return 1
input
不在有效范围内,只需将logical not运算符(!
)放在条件前面:
if (!(input >= 'A' && input <= 'H')) return 1; /* range invalid */
1 如果使用使用字符范围的条件,则应该使用已使用的范围,因为范围需要一个编码,以递增顺序指定字母,而范围之间没有任何间隙({ {3}}例如:A = 65, B = 66, C = 67, ..., Z = 90
)。
有这个规则中断的编码。正如@DavidBowling的ASCII code所述,例如other answer(例如:A = 193, B = 194, ..., I = 200, J = 209, ..., Z = 233
),其在A
到Z
的范围之间存在一些差距。然而,条件:(input >= 'A' && input <= 'H')
将适用于两种编码
我从来没有对这样的实现感到失望,这是不太可能的。大多数实现使用条件有效的EBCDIC
然而,他的回答提供了一个适用于每种情况的解决方案。
答案 2 :(得分:4)
这很简单:
if(input >='A' && input<='H') return 1;
C不允许您指定0 - 9
等范围。
事实上,这是一个算术表达式“零减9”并且评估为负9(当然)。
Nerd Corner: 正如其他人所指出的那样,C标准并不保证这一点,因为它没有指定字符编码,但实际上所有现代平台都将这些字符编码为与ASCII相同。因此,你不太可能会失败,如果你在一个无法工作的环境中工作,你就会被告知!
真正可移植的实现可能是:
#include <string.h>//contains strchr()
const char* alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char* pos=strchr(alpha,input);
if(pos!=NULL&&(pos-alpha)<8) return 1;
这会尝试在字母字符串中查找字符,然后确定指向的字符(如果有)是否在“I”之前。
这是完全超过工程而不是你正在寻找的答案。