如何确定 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" 数组或 perror
或 stout
流。
但是,我怎么可能知道我是否恰好收到了 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'
或Enter是100个字符的一部分吗?让我们假设它不是。
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++;
}
我是这样做的:
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" 数组或 perror
或 stout
流。
但是,我怎么可能知道我是否恰好收到了 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'
或Enter是100个字符的一部分吗?让我们假设它不是。
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++;
}