2
int main(void) {
    Fr = fopen("ContactList.txt", "r");
    while (fscanf(Fr, "%d", &num) != EOF) {
        ++counter;
    }

ContactList.txt类似这样:

Name Surname XXX-XXX-XXXX XXX-XXX-XXXX Adress Adress Mail
Name(1) Surname XXX-XXX-XXXX XXX-XXX-XXXX Adress Adress Mail
Name(2) Surname XXX-XXX-XXXX XXX-XXX-XXXX Adress Adress Mail
... 
4

4 回答 4

2

fscanf"%d"当输入流中的下一个字符不能以数字开头时,将返回 0 作为格式。您只需测试EOF,它仅在文件末尾返回。你一直试图解析一个数字并fscanf固执地告诉你没有数字......确实是无限循环。

该文件甚至不包含数字。你为什么试图解析一个数字?

于 2015-12-18T23:03:02.337 回答
1

fscanf()函数将根据您提供的格式字符串扫描文本,留下未使用的任何与格式不匹配的内容。使用您提供的格式,它将使用任何前导空格,然后尝试将后面的任何内容与可能有符号的十进制整数匹配。1如果它成功匹配一个(一个)整数,并且0如果遇到不能作为整数匹配的非空格,它将返回。EOF只有在EOF消耗前导空格时它才会返回。

因此,如果您的文件包含除空格和十进制数字以外的任何内容,则扫描最终将达到无法解析输入数字的程度(因此返回0而不消耗任何内容),但您不断要求它重试。

您可以做什么取决于文件的格式,以及“计数行号”的含义。根据您的措辞和scanf()格式,我首先认为您的数据中有文字行号(例如,BASIC 或 Fortran 源代码可能有),而您想计算这些。我现在怀疑你的意思是你只是想计算行数。如果就是你所追求的,那么你可能会做这样的事情:

char c;
size_t count = 1;

while (fscanf(Fr, "%*[^\n]%c", &c) == 1) {
    count += 1;
}

scanf()格式扫描并忽略直​​到换行符或 EOF 的所有内容,然后如果有下一个字符(只能是换行符),则使用下一个字符。1当且仅当它成功扫描换行符时它才返回。初始化countto1对应于将换行符视为 line separators,而不是 line terminators,因此行数比换行符多一。

还有其他方法,可能上面的方法并不完全适合您,但它应该让您了解如何进行。

于 2015-12-18T23:02:22.767 回答
0

要计算文件中的行数:

int main(void) {
  Fr = fopen("ContactList.txt", "r");
  if (Fr) {
    unsigned long long count = 0;
    int previous = '\n';
    while ((ch = fgetc(Fr)) != EOF) {
      if (previous == '\n') count++;
      previous = ch;
    }
    printf("Line Count %llu\n", count); 
    fclose(Fr);
  }
  return 0;
}

这会计算文件中的最后一行,即使它不以 . 结尾'\n'

于 2015-12-19T04:17:21.347 回答
0

fscanf() 返回扫描和格式化的值的数量。您正在将其与 EOF 进行比较,EOF 可能为 -1。因此,即使您没有阅读任何内容,您的循环也将永远运行。

更改为 fgets() 而不是 fscanf() - 更简单、更快并且会读取空格。fgets 将读取到下一个换行符,这在处理文本文件时非常有用。

char buffer[80];  // 80 might not be enough. Your call.
 while (fgets(buffer, 80, fr)) != NULL){
...
}
于 2015-12-18T23:05:24.010 回答