Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何确定FGET是否在读取所有字母之前停止?_C_File_Fgets - Fatal编程技术网

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