字符串中的字符与C

时间:2017-09-07 10:11:10

标签: c string

我一直在研究一个需要验证字符串中字符的项目。

比如说我的有效字符集是' 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语句中输入整个条件之外,还有更简单的方法吗?任何帮助将不胜感激。

4 个答案:

答案 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是与abcde中的任何一个都不匹配的第一个字符的偏移量。如果它不是字符串的结尾,则输入无效。

请注意,问题中的代码存在一些问题:

  • 循环测试i <= sizeof(string) - 1容易出错,如果string是指针,sizeof(string)将与其指向的数组中的字符数无关(如果有的话) ),如果string是数组,sizeof(string)是数组的大小,而不是字符数加1。请改用:

    for (i = 0; string[i] != '\0'; i++)
    
  • 您打算使用&&代替||。发布的版本始终打印字符串的第一个字符,除非它是空的。