我正在写需要限制使用输入字符只能从代码A到H.那么大的H不应该被接受.我看到数字,我可以使用如下:
if (input == 0 - 9) return 1;
Run Code Online (Sandbox Code Playgroud)
但是,我怎么做,A到H(char)?
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;
}
Run Code Online (Sandbox Code Playgroud)
虽然比较ASCII值的解决方案可能在实践中有效,但这种方法是可移植的.请注意,在我发布的原始代码中,错过了一个边缘案例,正如@chux所指出的那样.可以'\0'从键盘输入一个字符(或通过其他方法获得一个字符),并且由于字符串包含该'\0'字符,因此这将被接受为有效输入.我已更新验证码以检查此情况.
然而,使用上述解决方案还有另一个优点.请考虑以下比较样式代码:
if (input >= 'A' || input <= 'H') {
puts("Valid input");
} else {
puts("Invalid input");
}
Run Code Online (Sandbox Code Playgroud)
现在,假设有效输入的条件发生变化,并且必须修改程序.修改验证字符串更简单,例如更改为:
char *valid_input = "ABCDEFGHIJ";
Run Code Online (Sandbox Code Playgroud)
使用可能出现在多个位置的比较代码,必须在代码中找到每个比较.但是使用验证字符串,只需要找到并修改一行代码.
此外,验证字符串对于更复杂的要求更简单.例如,如果有效输入是范围中'A' - 'I'的字符或范围中的字符'0' - '9',则验证字符串可以简单地更改为:
char *valid_input = "ABCDEFGHI0123456789";
Run Code Online (Sandbox Code Playgroud)
比较方法开始看起来很笨重:
if ((input >= 'A' && input <= 'I') || (input >= '0' && input <= '9')) {
puts("Valid input");
} else {
puts("Invalid input");
}
Run Code Online (Sandbox Code Playgroud)
请注意,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);
}
Run Code Online (Sandbox Code Playgroud)