如何确定 fgets 是否在读取所有字母之前停止?

How to determine if fgets stopped before all letters were read?

我是这样做的:

char buf[100];              
int n = 0;                  
char save[100][100];        

while (fgets(buf,100, file)!=NULL) {
    strcpy(save[n], buf);
    printf("%s",buf);
    n++;
}

我打开了一个FILE = *file,之前有错误处理。 我只想阅读少于或等于 100 个字符的行。那些具有更多字符的字符,我想忽略并将一些特殊消息写入 "save" 数组或 perrorstout 流。

但是,我怎么可能知道我是否恰好收到了 100 个字符,或者我的 fgets 只是读到了极限?

我如何知道我是否在第一时间获得了超过 100 个?

您可以检查字符串长度和最后一个字符。如果长度为 99 个字符且最后一个字符不是换行符,则该行中有更多字符 fgets 未读取(尽管其余字符可能只是换行符)。

如果 fgets 读取整行,则字符串的长度将小于 99 或者最后一个字符将是换行符(如果 fgets 总是添加它适合缓冲区)。

请注意,我说的是 99 个字符,因为 100 个字符的数组只能容纳 99 个字符加上字符串终止符 '[=15=]'。如果您想读取最多(包括)100 个字符,您的缓冲区需要 101 个字符。

Example showing it in "action"。前两个输出来自较长的读取行,并且 fgets 没有读取所有行。后两行输出是 fgets 读取整行时。

不要使用 fgets()use getline()。使用 fgets(),一旦您阅读了太长的一行(无论您如何识别它),您将不得不继续阅读该行并丢弃它,直到您到达新的一行。换句话说,您需要跟踪状态,如果您使用 getline() 则不需要跟踪状态,因为它会为您提供整行,并告诉您它有多长:

FILE *fp = // fopen() however you need to

char *lineArray[ MAX_LINES ];
int ii = 0;

char *line = NULL;
size_t len = 0UL;

// loop until getline() fails
for ( ;; )
{
    ssize_t lineLen = getline( &line, &len, fp );
    if ( lineLen == -1L )
    {
        break;
    }

    if ( lineLen > 100L )
    {
        // handle too-long line
    }
    else
    {
        lineArray[ ii ] = strdup( line );
        ii++;
    }
}

在将行复制到数组之前,您可能希望从每一行中删除任何尾随 newline 个字符。

请注意,我使用 strdup() 复制该行 - 这不是 C 标准函数,but it is POSIX

首先让我们假设 fgets() 不会读取空字符。如果是,则以下方法可能不够。

I only want to read the lines that have less than or equal to 100 characters. Those that feature more characters, I want to ignore and write some special message to the "save" array

问题 1.'\n'Enter100个字符的一部分吗?让我们假设它不是。

OP 似乎仍然想 阅读 行,无论是长于还是短于 100 或 COLS 个字符,这只是一个如何处理的问题然后它。

推荐缓冲区COLS+3。一种用于空字符,一种用于 '\n',另一种用于超长行检测。

#define ROWS 100
#define COLS 100
char save[ROWS][COLS+1];  // +1 for [=10=]      
char buf[COLS + 3];              
int n = 0;                  

while (n < ROWS && fgets(buf, sizeof buf, file)!=NULL) {
  size_t len = strlen(buf);
  bool EOLorEOFfound = false;

  // lop off potential \n
  if (len > 0 && buf[len - 1] == '\n') {
    buf[--len] = '[=10=]';
    EOLorEOFfound = true;
  }

  // if line is too long ...
  if (len > COLS) {
    // consume rest of line
    while (!EOLorEOFfound) {
      int ch = fgetc(file);
      EOLorEOFfound = ch == '\n' || ch == EOF;
    }
    // write some special message to the "save" array
    assert(COLS >= 3);
    strcpy(save[n], "***");
  } 
  // Line not too long
  else {
    strcpy(save[n], buf);  // or memcpy(save[n], buf, len+1);
    printf("%s\n", buf);
  }
  n++;
}