删除C中的多字符常量

时间:2018-02-28 00:06:18

标签: c compiler-warnings portability

这是我在一个非常古老的C库中找到的一些代码,它试图从文件中获取空格...

  while(
    (line_buf[++line_idx] != ' ')  &&
    (line_buf[  line_idx] != '  ') &&
    (line_buf[  line_idx] != ',')  &&
    (line_buf[  line_idx] != '\0') )
  {

This great thread解释问题是什么,但大部分答案都是"只是忽略它"或者"你永远不应该这样做"。然而,我没有看到的是规范的解决方案。任何人都可以使用"正确的方式"?

提供编码此测试的方法

更新:澄清一下,问题是"测试另一个字符串中给定索引处是否存在一个或多个字符串的正确方法是什么?#34; 。如果我使用错误的术语,请原谅我。

2 个答案:

答案 0 :(得分:1)

原始问题

没有规范或正确的方法。多字符常量始终是实现定义的。查找编写代码时使用的编译器的文档,并找出其含义。

更新了问题

您可以使用strchr()匹配多个字符。

while (strchr( " ,", line_buf[++line_idx] ))
{

同样,这并不考虑那个多字符常量。你应该在删除之前找出原因。

此外,strchr()不处理Unicode。例如,如果您正在处理UTF-8流,则需要一个能够处理它的函数。

最后,如果您担心速度,个人资料。编译器可以使用“while”条件中的三个(或四个)单个测试表达式来获得更好的结果。

换句话说,多项测试可能是最佳解决方案!

除此之外,我闻到了一些粗俗的索引:line_idx更新的方式取决于周围的代码来正确启动循环。确保在更新内容时不会创建一个一个错误。

祝你好运!

答案 1 :(得分:1)

  

更新:澄清一下,问题是"测试的正确方法是什么   在给定的情况下存在一个或多个字符的字符串   索引在另一个字符串"。如果我使用了错误,请原谅我   术语

嗯,有很多方法,但标准方法是使用strspn,它有原型:

size_t strspn(const char *s, const char *accept);

它巧妙地:

calculates the length (in bytes) of the initial segment of s 
which consists entirely of bytes in accept.

这允许您测试"在另一个字符串中的给定索引处是否存在一个或多个字符的字符串" 并告诉您有多少字符来自该字符串按顺序匹配。

例如,如果您有另一个字符串char s = "somestring";并想知道它是否包含字母r, s, t,例如,在char *accept = "rst";开头就是第5个字符,你可以测试一下:

size_t n;
if ((n = strspn (&s[4], accept)) > 0)
    printf ("matched %zu chars from '%s' at beginning of '%s'\n",
           n, accept, &s[4]);

要按顺序进行比较,您可以使用strncmp (&s[4], accept, strlen (accept));。你也可以简单地使用nestest循环来迭代s accept中的字符。

所有方式都是"正确" ,只要它们不调用未定义行为(并且合理有效)。