CharybdeBE
CharybdeBE

Reputation: 1843

How to use fscanf, care about endofline?

I want to read int from a file

The first line is composed of 1 int and the second of 2

ie

 1
 2 3

if i do

 fscanf(FILE, "%d \n %d %d", &a, &b, &c);

I obtain correctly the 3 numbers but if i put all the numbers on the same line in the file ie 1 2 3

I obtain the same result (and that's not what i want)

I want to know : How to force the user to go to a new line in his file ?

Edit : As it seems unclear to some (i'm sorry for that) i want that the file

1 
2 3

Produce the result :

a = 1
b = 2 
c = 3 

And the file

1 2 3 

produce either an error or

a = 1
b = 0
c = 0

Upvotes: 1

Views: 84

Answers (2)

chux
chux

Reputation: 153338

fscanf(FILE, "%d", ...); first scans and discard white space before scanning for int characters. In scanning white-space, both ' ' and '\n' are treated the same, so using '%d' loses the end-of-line.

fscanf(FILE, "\n", ...); and fscanf(FILE, " ", ...); do the same thing: scan and discard any white space. Using "\n" does not scan only for '\n'.

Code could use fscanf(FILE, "%d%*1[\n]%d %d", &a, &b, &c) == 3, to find a '\n' after a, but additional '\n' could be lurking in other places.

The only way using scanf() family to detect a '\n' involves using '%c' or '%[]' or '%n'. It is easier to use fgets() and then parse with sscanf() or strtol().

int Read1and2int(FILE *stream, int *a, int *b, int *c) {
   char buf[100];
   int n;

   if (fgets(buf, sizeof buf, stream) == NULL) return EOF;
   int count = sscanf(buf,"%d %n", a, &n);
   // Non-numeric or extra data
   if (count != 1 || buf[n]) return 0;

   if (fgets(buf, sizeof buf, stream) == NULL) return 1;
   count = sscanf(buf,"%d%d %n", b, c, &n);
   // Non-numeric or extra data
   if (count != 2 || buf[n]) return 1;
   return 3; 
}

Upvotes: 2

Ian Abbott
Ian Abbott

Reputation: 17403

You need to read each line into a char buffer using fgets and parse each line with its own sscanf. You can use an extra %s on the end of the format string (and an extra pointer argument to a dummy variable of type char *) to detect whether the line contains extra stuff after the fields you're looking for.

Upvotes: 3

Related Questions