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

ContactList.txt is similar like this:

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
... 
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Kaan VARLI
  • 31
  • 1

4 Answers4

2

fscanf will return 0 for "%d" format when the next character from the input stream cannot start a number. You just test for EOF, which is only returned at end of file. You keep trying to parse a number and fscanf stubbornly tells you there is no number... endless loop indeed.

The file does not even contain numbers. Why do you attempt to parse a number?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
1

The fscanf() function will scan text according to the format string you provide, leaving unconsumed anything it cannot match to the format. With the format you present, it will consume any leading whitespace and then try to match whatever follows to a possibly-signed decimal integer. It will return 1 if it successfully matches an (one) integer, and 0 if it encounters non-whitespace that it cannot match as an integer. It will return EOF only in the event that it reaches EOF while consuming the leading whitespace.

Therefore, if your file contains anything other than whitespace and decimal numbers, the scan will eventually reach a point where it cannot parse a number from the input (and therefore returns 0 without consuming anything), but you keep asking it to try again.

What you could do instead depends on the format of the file, and on what you mean by "count line numbers". Based on your wording and your scanf() format, I first thought your data had literal line numbers in it (like, for instance, BASIC or Fortran source code might have), and you wanted to count those. I now suspect that what you meant is that you simply want to count the number of lines. If that's what you are after then you might do something like this:

char c;
size_t count = 1;

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

That scanf() format scans and ignores everything up to a newline or EOF, then consumes the next character if there is one (which can only be a newline). It returns 1 if and only if it successfully scans a newline. Initializing count to 1 corresponds to viewing the newlines as line separators, as opposed to line terminators, so that there is one more line than there are newlines.

There are other approaches, too, and it may be that the one above doesn't suit you perfectly, but it should give you an idea of how you can proceed.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 1
    Your suggested code fails on empty lines (`%[` registers a *matching failure* in that case and then won't go on to process the `%c`) – M.M Dec 19 '15 at 00:14
0

fscanf() returns the number of values scanned and formatted. You are comparing that to EOF, which is probably -1. Therefore your loop will run forever even if you don't read anything.

Change to fgets() rather than fscanf() - simpler and faster and will read spaces. fgets will read up to the next newline, which is very useful when processing text files.

char buffer[80];  // 80 might not be enough. Your call.
 while (fgets(buffer, 80, fr)) != NULL){
...
}
nicomp
  • 4,344
  • 4
  • 27
  • 60
0

To count the number of lines in a file:

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;
}

This counts the last line in a file even if it does not end with '\n'.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256