-1

I have a file for marks of student as shown as below:

T1 T2 T3 HW1 HW2 HW3 HW4 PRJ 
47 17 50 10  10  10  10  68
20 41 40 15  10  10  10  80

but I don't know how the number of students in the class. I try to write a code to read the data from the file but I get infinite loop.

  char header[10];
  int data;
  int a;
  int nos=0;

  //READ HEADINGS OF THE TABLE
  while(fscanf(f1, "%s", header) != '\n')
  {
      printf("%s \t", header);
  }
  printf("\n");

  //READ DATA OF THE TABLE     
  while(fscanf(f1, "%d", data) != EOF)
  {
      for(a=0; a<=7; ++a)
      {
          printf("%d \t", data);
      }
      printf("\n");
  }
  printf("\n");
  printf("Number of students in class: %d", nos/8); 
  system("pause");
Mr_Pouet
  • 4,061
  • 8
  • 36
  • 47
raz
  • 11
  • 1
  • 3
    Your assumptions about the nature of `fscanf()`s return value are incorrect. RTFM. – EOF Jan 06 '16 at 17:33
  • 5
    Why are you comparing `fscanf()`'s return value to `'\n'`, sorry to ask like this but Did you bother reading the documentation? – Iharob Al Asimi Jan 06 '16 at 17:33
  • Rather than using loop like `while (foo() != one_of_several_values_that_cause_trouble)`, use `while (foo() == the_one_value_code_expects)`. IOWs: `while(fscanf(f1, "%d", data) == 1)` – chux - Reinstate Monica Jan 06 '16 at 17:47
  • @chux `while(fscanf(f1, "%d", &data) == 1)` – BLUEPIXY Jan 06 '16 at 17:54
  • Compiler warnings are there for good reasons. Enable and pay heed to them! If your compiler still does not complain, you have a rubbish compiler. Trash it and get a modern one (i.e. less than 10 years old). – too honest for this site Jan 06 '16 at 19:05

2 Answers2

3

An easier way is to read each line in full in a buffer and use sscanf to extract the names.

 #define N 100
 char buffer[N];
 fgets(buffer, N, f1);
 unsigned num_tasks = 0;
 while(sscanf(buffer, "%s", header) == 1) {
     printf("%s \t", header);
     num_tasks++;
 }

Do the same for each line of marks and count students along the way. Stop when fgets() returns EOF.

kfx
  • 8,136
  • 3
  • 28
  • 52
1
  1. fscanf returns the total number of arguments successfully matched so fscanf(f1, "%s", header) != '\n' will always be true as -1 < 10 (EOF), 0 < 10 (Matching failure but not end of file) and also 1 < 10 (matched successfully). Here 10 is ASCII of \n.

  2. Also in second fscanf instead of data, it should be &data.

Please read man -s3 fscanf.

Here correct solution will be:

#define HEADERS 8

char header[10];
int data, a, nos = 0;

for(a = 0; a < HEADERS; a++) //assuming there'll always be 8 headers
{
    fscanf(f1, "%s", header);
    printf("%s \t", header);
}
printf("\n");

while(fscanf(f1, "%d", &data) == 1)
{
    nos++;
    printf("%d \t", data);
    if(!(nos % HEADERS))
        printf("\n");
}

printf("Number of students in class: %d", nos/HEADERS); 
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
rootkea
  • 1,474
  • 2
  • 12
  • 32
  • 2
    `EOF` is not guaranteed to be `-1`. And this will result in an endless loop for invalid input. – too honest for this site Jan 06 '16 at 19:09
  • @Olaf: I assumed the file to contain all valid data as posted by OP himself/herself at the beginning of the question. – rootkea Jan 06 '16 at 19:25
  • This attitude is the reason for rubbish software which crashes if the input is not exactly as expected. Better is defensive programming. – too honest for this site Jan 06 '16 at 19:28
  • @Olaf: Also yes EOF is not guaranteed to be -1 but it's guaranteed to be negative. See http://stackoverflow.com/a/4705984/1783971 So here first `while` loop is an infinite loop as I said. – rootkea Jan 06 '16 at 19:28