【发布时间】:2010-11-07 11:27:52
【问题描述】:
我正在尝试检查一个字符是否属于无效字符列表/数组。
来自 Python 背景,我以前只能说:
for c in string:
if c in invalid_characters:
#do stuff, etc
如何使用常规的 C 字符数组做到这一点?
【问题讨论】:
我正在尝试检查一个字符是否属于无效字符列表/数组。
来自 Python 背景,我以前只能说:
for c in string:
if c in invalid_characters:
#do stuff, etc
如何使用常规的 C 字符数组做到这一点?
【问题讨论】:
假设您的输入是标准的以空字符结尾的 C 字符串,您想使用 strchr:
#include <string.h>
char* foo = "abcdefghijkl";
if (strchr(foo, 'a') != NULL)
{
// do stuff
}
另一方面,如果您的数组不是以 null 结尾的(即只是原始数据),则需要使用 memchr 并提供大小:
#include <string.h>
char foo[] = { 'a', 'b', 'c', 'd', 'e' }; // note last element isn't '\0'
if (memchr(foo, 'a', sizeof(foo)))
{
// do stuff
}
【讨论】:
C 库中鲜为人知但非常有用(自 C89 以来为标准 - 意思是“永远”)的函数在一次调用中提供信息。实际上,有多种功能——财富的尴尬。与此相关的是:
7.21.5.3 strcspn 函数
概要
#include <string.h> size_t strcspn(const char *s1, const char *s2);说明
strcspn 函数计算字符串的最大初始段的长度 由 s1 指向的,它完全由不是来自于指向的字符串的字符组成 s2.
返回
strcspn 函数返回段的长度。
7.21.5.4 strpbrk 函数
概要
#include <string.h> char *strpbrk(const char *s1, const char *s2);说明
strpbrk 函数定位由 s1 指向的字符串中的第一个匹配项 s2指向的字符串中的字符。
返回
strpbrk 函数返回一个指向字符的指针,如果没有字符则返回一个空指针 from s2 发生在 s1 中。
问题询问'对于字符串中的每个字符......如果它在无效字符列表中'。
有了这些函数,你可以写:
size_t len = strlen(test);
size_t spn = strcspn(test, "invald");
if (spn != len) { ...there's a problem... }
或者:
if (strpbrk(test, "invald") != 0) { ...there's a problem... }
哪个更好取决于您还想做什么。还有相关的strspn() 函数有时很有用(白名单而不是黑名单)。
【讨论】:
strchr! strpbrk 显然是理想的解决方案。
any character from the string pointed to by s2 的描述中,但在您的示例中,您针对 "invalid" 进行测试。这不会查找字符串"invalid" 中任何单个字符的出现吗?
strpbrk 的描述中,您有正确的定义,但是,在您的示例if (strpbrk(test, "invalid") != 0) { ...there's a problem... } 中,您似乎在寻找一个连续的字符串"invalid",但会搜索第一次出现的 "invalid" 中包含的任何 字符。这是真的和正确的吗?
我相信原来的问题说:
一个字符属于一个列表/数组 无效字符
而不是:
属于以空字符结尾的字符串
如果确实如此,那么strchr 确实是最合适的答案。但是,如果字符数组没有空终止符,或者字符位于列表结构中,则您需要创建一个空终止符字符串并使用 strchr 或手动迭代集合中的元素,依次检查每个。如果集合很小,那么线性搜索就可以了。大型集合可能需要更合适的结构来缩短搜索时间 - 例如排序数组或平衡二叉树。
选择最适合您的情况。
【讨论】:
等效的 C 代码如下所示:
#include <stdio.h>
#include <string.h>
// This code outputs: h is in "This is my test string"
int main(int argc, char* argv[])
{
const char *invalid_characters = "hz";
char *mystring = "This is my test string";
char *c = mystring;
while (*c)
{
if (strchr(invalid_characters, *c))
{
printf("%c is in \"%s\"\n", *c, mystring);
}
c++;
}
return 0;
}
请注意,invalid_characters 是一个 C 字符串,即。一个以 null 结尾的 char 数组。
【讨论】:
strpbrk()。
在处理 C 字符串时使用 strchr 函数。
const char * strchr ( const char * str, int character );
这是你想要做的一个例子。
/* strchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char invalids[] = ".@<>#";
char * pch;
pch=strchr(invalids,'s');//is s an invalid character?
if (pch!=NULL)
{
printf ("Invalid character");
}
else
{
printf("Valid character");
}
return 0;
}
在处理内存块时使用 memchr(作为非空终止数组)
const void * memchr ( const void * ptr, int value, size_t num );
/* memchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char * pch;
char invalids[] = "@<>#";
pch = (char*) memchr (invalids, 'p', strlen(invalids));
if (pch!=NULL)
printf (p is an invalid character);
else
printf ("p valid character.\n");
return 0;
}
【讨论】:
你想要
strchr (const char *s, int c)
如果字符 c 在字符串 s 中,它会返回一个指向 s 中位置的指针。否则返回 NULL。因此,只需使用您的无效字符列表作为字符串。
【讨论】:
strchr 用于从开头搜索字符(strrchr 从结尾):
char str[] = "This is a sample string";
if (strchr(str, 'h') != NULL) {
/* h is in str */
}
【讨论】: