C 如何确定FGET是否在读取所有字母之前停止?
我是这样做的:C 如何确定FGET是否在读取所有字母之前停止?,c,file,fgets,C,File,Fgets,我是这样做的: char buf[100]; int n = 0; char save[100][100]; while (fgets(buf,100, file)!=NULL) { strcpy(save[n], buf); printf("%s",buf); n++; } 我打开了一个带有错误处理的文件=*文件。 我只想读少于或等于100个字符的行。对于那些具有更多字符的字符,我想忽略
char buf[100];
int n = 0;
char save[100][100];
while (fgets(buf,100, file)!=NULL) {
strcpy(save[n], buf);
printf("%s",buf);
n++;
}
我打开了一个带有错误处理的文件=*文件。
我只想读少于或等于100个字符的行。对于那些具有更多字符的字符,我想忽略它们,并将一些特殊消息写入“save”数组或perror
或stout
流
然而,我怎么可能知道我到底是得到了100个字符,还是我的fgets
已经完全停止了阅读
我怎么知道我一开始的成绩是否超过100分 您可以检查字符串长度和最后一个字符。如果长度为99个
字符,且最后一个字符不是换行符,则行上有更多未读取的字符(尽管剩余字符可能只是换行符)
如果fgets
读取整行,则字符串的长度将小于99
,或者最后一个字符将是换行符(如果适合缓冲区,则fgets
始终添加)
请注意,我说的是99个字符,因为100个字符的数组只能容纳99个字符加上字符串终止符'\0'
。如果要读取最多(包括)100个字符,则缓冲区需要有101个字符大
。前两个输出来自读取较长的行,而fgets
没有读取所有行。第二行输出是当fgets
读取整行时。不要使用fgets()
。使用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++;
}
}
在将行复制到数组之前,您可能希望从每行中删除任何尾随的换行符
请注意,我使用了strdup()
来复制该行-这不是C标准函数。首先让我们假设fgets()
不会读取空字符。如果是,以下方法可能不够
我只想读少于或等于100个字符的行。对于那些具有更多字符的字符,我想忽略它们,并将一些特殊消息写入“save”数组
问题1。是“\n”
还是输入100个字符的一部分?让我们假设它不是
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++;
}
#定义行100
#定义COLS 100
字符保存[行][COLS+1];//+1代表\0
char buf[COLS+3];
int n=0;
while(n0&&buf[len-1]='\n'){
buf[--len]='\0';
EOLorEOFfound=真;
}
//如果线太长。。。
如果(len>COLS){
//消耗生产线的剩余部分
而(!EOLorEOFfound){
int ch=fgetc(文件);
EOLorEOFfound=ch='\n'| | ch==EOF;
}
//向“save”数组写入一些特殊消息
断言(COLS>=3);
strcpy(保存[n],“***”号);
}
//线路不要太长
否则{
strcpy(save[n],buf);//或memcpy(save[n],buf,len+1);
printf(“%s\n”,buf);
}
n++;
}
您最多可以读取101个字符,如果您有101个字符,那么您就有100多个!如果要读取(和打印)n个字符,则需要:字符缓冲区[n+1];如果声明字符缓冲区[102],则可以读取101个字符并检查长度。如果是101,最后一个字符是一个换行符,那么您已经准确地读取了100个字符(删除换行符)。详细信息:getline()
也不是C标准函数getline()
会强制执行每行的内存分配。仅当输入可能为.NMDV时,我才将此视为一个问题。然而,“如果长度为99个字符,并且最后一个字符不是换行符,那么fgets没有读取的行上有更多字符”在读取文件的最后一行时可能不是真的。与“如果FGET读取整行,则字符串的长度将小于99…”类似的问题。一个不以结尾的文件\n'
是一个麻烦。我认为你的答案很好,也很简单,如果有一种方法可以处理@chux提到的问题,那会很好,也很容易。尽管我或多或少同意你的答案,你介意解释一下if(len>COLS)
furhter中的表达式吗?我不明白你为什么要把ch声明为int,而且我也不明白int ch==fgetc(stdin)
后面那行的表达式是什么意思。还有,为什么连双精度都是等号呢?事实上,我不明白整个“消耗剩余行”部分发现了你的错误:int ch==fgetc(stdin)
有两个错误。@Josch Kraus代码if(len>COLS)
测试如上注释“if line太长…”。您需要太长而无法检测的行,这就是if()
检测到的ch
声明为int
,因为这是由fgetc()返回的类型。该函数返回无符号字符
和EOF
范围内的值。使用char
是有问题的。=
应该是=
。除了=
部分之外,您还看到int ch=fgetc(stdin)
有什么问题。它必须是文件,而不是stdin