1

I'm trying for hours to find the answer for this question i've got in university. I tried running this with writing a file with two lines of : hello world and it reads the file perfectly, So i cant find the answer. I would appreciate your help !

A student wrote the next function for reading a text file and printing it exactly as it is.

void ReadFile(FILE *fIn)
{
  char nextLine[MAX_LINE_LENGTH];
  while(!feof(fIn))
 {
 fscanf(fIn,"%s",nextLine);
 printf("%s\n",nextLine);
 }
}

What are the two errors in this function?

You can assume that each line in the file is not longer than MAX_LINE_LENGTH characters, and that it is a text file that contains only alphabet characters, and that each line is terminated by '\n'.

Thanks.

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
user2630165
  • 311
  • 3
  • 10

3 Answers3

1
  1. It discards white space. Try adding multiple spaces and tabs.

  2. It may evaluate a stream more than once, and If there is a read error, the loop never terminates.
    See: Why is “while ( !feof (file) )” always wrong?

  3. Reading strings via scanf is dangerous. There is no bounds checking. You may read past you MAX_LINE_LENGTH.(and boom! Segfault)

Community
  • 1
  • 1
bsd
  • 2,707
  • 1
  • 17
  • 24
1

The main error is that fsacnf( fIn, "%s", nextLine ) doesn't scan a complete line. From man page:

s Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null byte ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.

Thus if you have a line "a b" the first fscanf() will scan just "a" and the second one "b" and both are printed in two different lines. You can use fgets() to read a whole line.

The second one is maybe that it's stated "each line in the file is not longer than MAX_LINE_LENGTH characters" but nextLine can contain atmost MAX_LINE_LENGTH-1 characters (+ '\0'). That problem becomes even more important if you replace fscanf() by fgets() because than nextLine must have also capacity to store '\n' or '\r\n' (depending on the platform you're on)

Ingo Leonhardt
  • 9,435
  • 2
  • 24
  • 33
  • 1
    correct point, but need to add `feof()` not good, correct is `while(fscanf(fIn,"%s",nextLine)!= EOF){ printf("%s\n",nextLine); }` – Grijesh Chauhan Jul 29 '13 at 16:30
  • @grijesh i totally agree, the correct question would have been: "what are the three errors ...". As it was a question in university, I suspect forgetting the '\0' was the mistake made intentionally, but of course I may be wrong – Ingo Leonhardt Jul 29 '13 at 16:35
  • 1
    no `scanf()` and `fgets()` both add `\0` maind problem answered by @bsd – Grijesh Chauhan Jul 29 '13 at 16:37
  • @grijesh I never meant that using `fgets()` would solve the length problem, I just said that it can be used to *really* read the file line per line. But thanx on your comment, I've edited my post to clearify – Ingo Leonhardt Jul 29 '13 at 16:44
  • I also means `scanf()` will remove spaces whereas `fgets()` will not. – Grijesh Chauhan Jul 29 '13 at 16:46
  • @grijesh and that's whatthe code is not supposed to do: "reading a text file and printing it exactly as it is". – Ingo Leonhardt Jul 29 '13 at 16:49
1

A correct way of doing that is:

void ReadFile(FILE *fIn)
{
  char nextLine[MAX_LINE_LENGTH];
  while(fgets(nextLine, MAX_LINE_LENGTH, fIn)) {
      printf("%s", nextLine);
  }
}

As some have posted using feof to control a loop is not a good idea nor using fscanf to read lines.

mhcuervo
  • 2,610
  • 22
  • 33