我这样做:
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个字符的行。那些具有更多字符的,我想忽略并向“保存”数组或perror
或stout
流写一些特殊消息。
但是,我怎么可能知道我是否只有100个字符,或者我的fgets
是否只是停止阅读?
我怎么知道我首先是否超过100?
答案 0 :(得分:2)
请勿使用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。
答案 1 :(得分:1)
首先让我们假设fgets()
不会读取空字符。如果是这样,以下方法可能不够。
我只想读取小于或等于100个字符的行。那些有更多角色的人,我想忽略并写一些特别的信息给" save"阵列
问题1. 100个字符的'\n'
或输入部分吗?让我们假设它不是。
OP似乎仍然希望读取该行,无论是长度还是短于100或COLS
个字符,这只是一个如何处理它的问题。
推荐COLS+3
的缓冲区。一个用于空字符,一个用于'\n'
,另一个用于超长线检测。
#define ROWS 100
#define COLS 100
char save[ROWS][COLS+1]; // +1 for \0
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] = '\0';
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++;
}
答案 2 :(得分:0)
您可以检查字符串长度和最后一个字符。如果长度为99
个字符且最后一个字符不是换行符,则fgets
无法读取的行中有更多字符(尽管其余字符可能只是换行符)
如果fgets
读取整行,则字符串的长度将小于99
,或者最后一个字符将是换行符(如果fgets
适合,则'\0'
总是添加缓冲区)。
请注意,我说 99 个字符,因为100个字符的数组只能容纳99个字符加上字符串终结符fgets
。如果你想读取(包括)100个字符,你的缓冲区需要大101个字符。
Example showing it in "action"。前两个输出来自更长的读取线,并且fgets
没有读取所有线。第二行输出是FileInfo mostrecentlog = (from f in logDirectory.GetFiles("Receive") orderby f.LastWriteTime descending select f).First();
读取整行。