我一直在研究一个需要验证字符串中字符的项目。
比如说我的有效字符集是' abcde'所有角色都发起不同的功能。
首先,代码要求用户输入。之后,将其与此集进行比较以检查是否存在任何无效输入(abcde
以外的任何字母)。在此之后,角色会发起各自的职能。
我知道可以使用以下方式执行此操作:
for (i = 0; i <= sizeof(string) - 1; i++) {
if (string[i] != 'a' || string[i] != 'b' || string[i] != 'c' ||
string[i] != 'd' || string[i] != 'e') {
printf("Invalid Input");
}
}
用户可以从该组中输入任意组合的三个或四个字母。
除了在if语句中输入整个条件之外,还有更简单的方法吗?任何帮助将不胜感激。
答案 0 :(得分:5)
编辑:感谢评论指出标准的strspn()
功能已经从我的雷达中消失了,我们可以像这样实现它:
const size_t num_valid = strspn(string, "abcde");
if(string[num_valid] != '\0')
printf("Invalid input: '%s'\n", string + num_valid);
这很好,因为它会将循环推出用户的代码,使其不那么复杂。
最初我声称这是[strchr()
]的典型案例
(https://linux.die.net/man/3/strchr),我仍然认为是:
for(size_t i = 0; string[i] != '\0'; ++i)
{
if(strchr("abcde", string[i]) == NULL)
{
printf("Invalid input: '%c'\n", string[i]);
break;
}
}
答案 1 :(得分:2)
听起来你可以使用strpbrk
函数,它完全符合你的需要:从字符列表中找到任何字符的第一个匹配项。例如:
#include <string.h>
#include <stdio.h>
int main()
{
const char STR_VALID[] = "abcde";
char data[] = "invalid code";
for(char* ptr=strpbrk(data, STR_VALID); ptr!=NULL; ptr=strpbrk(ptr+1, STR_VALID))
{
putc(*ptr, stdout);
}
}
输出:
adcde
答案 2 :(得分:1)
strchr
,但是老实说,你拥有它的方式是非常理想的。 不要通过写表面上华而不实的if(string[i] < 'a' || string[i] > 'e')
来诱惑牺牲便携性。
sizeof(string) - 1
我遇到了更多问题。如果string
将衰减指针,则sizeof(string)
将不会为您提供元素数量。此外,sizeof
会返回unsigned
类型,-1
可以将您推送到零,达到最大size_t
值!
使用预先计算的strlen
代替。
答案 3 :(得分:0)
对于您的用例最简单的解决方案是单次调用标准但很少使用库函数strspn()
:
size_t i = strspn(string, "abcde");
if (string[i] != '\0') {
printf("Invalid input: '%c'\n", string[i]);
}
strspn()
计算string
与"abcde"
中某个字符匹配时的字符数。 i
是与a
,b
,c
,d
和e
中的任何一个都不匹配的第一个字符的偏移量。如果它不是字符串的结尾,则输入无效。
请注意,问题中的代码存在一些问题:
循环测试i <= sizeof(string) - 1
容易出错,如果string
是指针,sizeof(string)
将与其指向的数组中的字符数无关(如果有的话) ),如果string
是数组,sizeof(string)
是数组的大小,而不是字符数加1。请改用:
for (i = 0; string[i] != '\0'; i++)
您打算使用&&
代替||
。发布的版本始终打印字符串的第一个字符,除非它是空的。