如何从文件或标准输入中安全简单地读取一行文本?

时间:2021-09-19 07:15:03

Given that fgets only sometimes includes a linebreak, and fscanf is inherently unsafe, I would like a simple alternative to read text line-by-line from a file. Is this page a good place to find such a function?

鉴于fgets有时只包含换行符,而fscanf本质上是不安全的,我想要一个简单的替代方法,从文件中逐行读取文本。这个页面是找到这样一个功能的好地方吗?

1 个解决方案

#1


1  

Yes. The following function should satisfy this requirement without creating any damaging security flaws.

是。以下功能应满足此要求,而不会产生任何破坏性的安全漏洞。

/* reads from [stream] into [buffer] until terminated by
 * \r, \n or EOF, or [lastnullindex] is reached. Returns
 * the number of characters read excluding the terminating
 * character. [lastnullindex] refers to the uppermost index
 * of the [buffer] array. If an error occurs or non-text
 * characters (below space ' ' or above tilde '~') are
 * detected, the buffer will be emptied and 0 returned.
 */
int readline(FILE *stream, char *buffer, int lastnullindex) {
  if (!stream) return 0;
  if (!buffer) return 0;
  if (lastnullindex < 0) return 0;
  int inch = EOF;
  int chi = 0;
  while (chi < lastnullindex) {
    inch = fgetc(stream);
    if (inch == EOF || inch == '\n' || inch == '\r') {
      buffer[chi] = '\0';
      break;
    } else if (inch >= ' ' && inch <= '~') {
      buffer[chi] = (char)inch;
      chi++;
    } else {
      buffer[0] = '\0';
      return 0;
    }
  }
  if (chi < 0 || chi > lastnullindex) {
    buffer[0] = '\0';
    return 0;
  } else {
    buffer[chi] = '\0';
    return chi;
  }
}

#1


1  

Yes. The following function should satisfy this requirement without creating any damaging security flaws.

是。以下功能应满足此要求,而不会产生任何破坏性的安全漏洞。

/* reads from [stream] into [buffer] until terminated by
 * \r, \n or EOF, or [lastnullindex] is reached. Returns
 * the number of characters read excluding the terminating
 * character. [lastnullindex] refers to the uppermost index
 * of the [buffer] array. If an error occurs or non-text
 * characters (below space ' ' or above tilde '~') are
 * detected, the buffer will be emptied and 0 returned.
 */
int readline(FILE *stream, char *buffer, int lastnullindex) {
  if (!stream) return 0;
  if (!buffer) return 0;
  if (lastnullindex < 0) return 0;
  int inch = EOF;
  int chi = 0;
  while (chi < lastnullindex) {
    inch = fgetc(stream);
    if (inch == EOF || inch == '\n' || inch == '\r') {
      buffer[chi] = '\0';
      break;
    } else if (inch >= ' ' && inch <= '~') {
      buffer[chi] = (char)inch;
      chi++;
    } else {
      buffer[0] = '\0';
      return 0;
    }
  }
  if (chi < 0 || chi > lastnullindex) {
    buffer[0] = '\0';
    return 0;
  } else {
    buffer[chi] = '\0';
    return chi;
  }
}