7

按照我之前的问题:尽管手册页有免责声明,为什么`strchr` 似乎适用于多字节字符?,我发现这strchr是一个糟糕的选择。

相反,我正在考虑使用strstr来查找单个字符(不是多字节char):

const char str[] = "This string contains é which is a multi-byte character";
char * pos = strstr(str, "é"); // 'é' = 0xC3A9: 2 bytes 
printf("%s\n", pos);

输出:

é 是一个多字节字符

这是我所期望的:我的多字节字符的第一个字节的位置。

先验,这不是规范的使用,strstr但它似乎运作良好。
这种解决方法安全吗?你能想到任何会导致错误的副作用或特殊情况吗?

[编辑]:我应该准确地说我不想使用wchar_ttype 并且我处理的字符串是 UTF-8 编码的(我知道可以讨论这个选择,但这是一个无关紧要的辩论)

4

2 回答 2

8

编辑
基于来自 OP 的更新问题“这种误报是否存在于 UTF-8 上下文中”所以答案是 UTF-8 的设计方式是它不受如上所示的字符部分不匹配的影响并导致任何错误积极的。因此使用strstrUTF-8 编码的多字节字符是完全安全的。

Original Answer
Nostrstr不适用于包含多字节字符的字符串。

如果您在包含多字节字符的字符串中搜索不包含多字节字符的字符串,则可能会给出误报。(虽然在日语语言环境中使用shift-jis 编码,strstr("掘something", "@some") 可能会给出误报)

+---------+----+----+----+
|   c1    | c2 | c3 | c4 |  <--- string
+---------+----+----+----+

     +----+----+----+
     | c5 | c2 | c3 |  <--- string to search
     +----+----+----+

如果 c1 的尾随部分(意外)与 c5 匹配,您可能会得到不正确的结果。我建议将 unicode 与 unicode 子字符串检查功能或多字节子字符串检查功能一起使用。(例如_mbsstr )

于 2014-08-29T15:49:44.063 回答
1

现代系统使用 UTF-8(或 ASCII)作为其多字节编码,使用此函数是安全的。

为了严格遵守并使您的代码即使在旧的/外来平台上也能工作,您需要考虑其他问题。

首先,好消息:在每个多字节编码中,一个 0 字节表示一个字符串的结尾,不管状态如何。这意味着,您strstr不会导致崩溃或其他问题,但结果可能是错误的。

例如,考虑 UTF-7,一种 7 位干净的 Unicode 编码方式。UTF-7 是一种具有shift state的多字节编码,这意味着如何解释一个字节可能取决于它出现的上下文。例如(参见Wikipedia)“£1AKM”被编码为+AKM-AKMUTF-7,其中+符号改变状态和字母的解释,如A. Doingstrstr(str, "AKM")将匹配第一个 AKM 部分(在 之后+),尽管这是编码的一部分£并且实际上应该匹配AKM之后的部分-(将移位状态设置回初始状态)。

于 2014-08-29T16:03:07.370 回答