为什么不应该使用strtok(line,"\ n")来去除fgets()留下的换行符 [英] Why should strtok(line, "\n") **not** be used to strip the newline left by fgets()

查看:121
本文介绍了为什么不应该使用strtok(line,"\ n")来去除fgets()留下的换行符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

fgets()是读取输入行的安全函数,但它存储换行字节'\ n'读取如果合适的话,从数组中的文件中删除.

fgets() is a safe function to read a line of input, but it stores the new line byte '\n' read from the file in the array if it fits.

在大多数情况下(即使不是大多数情况),必须先删除此新行,然后再进一步处理行内容.

In many if not most cases, this new line must be removed before further processing the line contents.

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

Several simple methods can be used for that, but I have seen a compact and tricky proposal:

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

为什么此方法不正确?为什么它并不总是有效?

Why is this method incorrect and why does it not always work?

推荐答案

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

The method is tricky as the strtok() function has side effects on a global hidden state variable. This may affect surrounding code and prove hard to debug.

此外,在一个简单的情况下, strtok(line,"\ n")不会用空字节覆盖'\ n': fgets()读取的行是一个空行,仅包含一个换行字节.对于此内容, strtok()将跳过开头的换行,搜索不存在的其他字符,并返回 NULL 修改数组.因此,它不会删除换行.

Furthermore, there is a simple case where strtok(line, "\n") will not overwrite the '\n' with a null byte: If the line read by fgets() is an empty line containing only a single new line byte. For this contents, strtok() will skip the initial new line, searching for a different character, which is not present, and return NULL not modifying the array. Hence it will not strip the new line.

这是不使用 strtok(line,"\ n")剥离换行符字节的迫切原因.

This is a compelling reason to not use strtok(line, "\n") to strip the new line byte.

当然可以通过编写以下内容来修复:

Of course one can fix this issue by writing:

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

或者麻烦的一线客:

    (void)(*line == '\n' ? (*line = '\0') : (strtok(line, "\n"), 0);

    if (!strtok(line, "\n")) *line = '\0';

    (void)(strtok(line, "\n") || (*line = '\0'));

但是代码不再紧凑,并且还有其他副作用.

But the code is no longer compact and still has other side effects.

其他可用方法:

  • 使用显式的 for 语句:

  for (char *p = line; *p; p++) {
      if (*p == '\n')
          *p = '\0';
  }

  • 使用 strlen():

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

  • 使用 strchr():

      char *p = strchr(line, '\n');
      if (p) {
          *p = '\0';
      }
    

  • 使用 strcspn()在单线中:

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

  • 这篇关于为什么不应该使用strtok(line,"\ n")来去除fgets()留下的换行符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆