为什么应该使用strtok(line,"n")**not**去除fgets()留下的换行符

fgets()是一个读取一行输入的安全函数,但它会将从文件中读取的新行字节存储'n'在数组中(如果合适的话)。

在许多情况下(如果不是大多数情况),必须在进一步处理行内容之前删除此新行

可以使用几种简单的方法,但我看到了一个紧凑而棘手的建议:

strtok(line, "n");    // strip the newline

为什么这种方法不正确,为什么它并不总是有效?

回答

该方法很棘手,因为该strtok()函数对全局隐藏状态变量有副作用。这可能会影响周围的代码并证明难以调试。

此外,有一种简单的情况strtok(line, "n")不会'n'用空字节覆盖:如果读取的行fgets()是仅包含单个新行字节的空行。对于此内容,strtok()将跳过初始的新行,搜索不存在的不同字符,并返回NULL 修改数组。因此它不会剥离新行

这是不用于strtok(line, "n")剥离新行字节的一个令人信服的理由。

当然,可以通过编写以下内容来解决此问题:

   if (*line == 'n')
       *line = '';
   else
       strtok(line, "n");

或繁琐的单线:

    (void)(*line == 'n' ? (*line = '') : (strtok(line, "n"), 0);
    if (!strtok(line, "n")) *line = '';
    (void)(strtok(line, "n") || (*line = ''));

但是代码不再紧凑,仍然有其他副作用。

其他方法可用:

  • 使用显式for语句:

      for (char *p = line; *p; p++) {
          if (*p == 'n')
              *p = '';
      }
    
  • 使用strlen()

      size_t len = strlen(line);
      if (len > 1 && line[len - 1] == 'n') {
          line[--len] = '';
      }
      // len is the length if the stripped line
    
  • 使用strchr()

      char *p = strchr(line, 'n');
      if (p) {
          *p = '';
      }
    
  • 使用strcspn()在一衬垫:

      line[strcspn(line, "n")] = '';  // strip the newline if any.
    

以上是为什么应该使用strtok(line,"n")**not**去除fgets()留下的换行符的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>