If you want to pick out only integers from a mess of a file, then you actually need work through each line you read with a pointer to identify each beginning digit (or beginning -
sign for negative numbers) converting each integer found one at a time. You can do this with a pointer and sscanf
, or you can do this with strtol
making use of the endptr
parameter to move to the next character following any successful conversion. You can also use character-oriented input (e.g. getchar
or fgetc
) manually performing the digit identification and conversion if you like.
Given you started with the fgets
and sscanf
approach, the following continues with it. Whether you use sscanf
or strtol
, the whole key is to advance the start of your next read to the character following each integer found, e.g.
#include <stdio.h>
#include <stdlib.h>
#define MAXC 256
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* buffer to hold MAXC chars at a time */
int nval = 0; /* total number of integers found */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) {
char *p = buf; /* pointer to line */
int val, /* int val parsed */
nchars = 0; /* number of chars read */
/* while chars remain in buf and a valid conversion to int takes place
* output the integer found and update p to point to the start of the
* next digit.
*/
while (*p) {
if (sscanf (p, "%d%n", &val, &nchars) == 1) {
printf (" %d", val);
if (++nval % 10 == 0) /* output 10 int per line */
putchar ('\n');
}
p += nchars; /* move p nchars forward in buf */
/* find next number in buf */
for (; *p; p++) {
if (*p >= '0' && *p <= '9') /* positive value */
break;
if (*p == '-' && *(p+1) >= '0' && *(p+1) <= '9') /* negative */
break;
}
}
}
printf ("\n %d integers found.\n", nval);
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
Example Input
The following two input files illustrate picking only integers out of mixed input. Your file:
$ cat dat/blah.txt
8 blah blah
10 blah blah
2 blah blah
3 blah blah
A really messy file
$ cat ../dat/10intmess.txt
8572,;a -2213,;--a 6434,;
a- 16330,;a
- The Quick
Brown%3034 Fox
12346Jumps Over
A
4855,;*;Lazy 16985/,;a
Dog.
11250
1495
Example Use/Output
In your case:
$ ./bin/fgets_sscanf_int_any_ex < dat/blah.txt
8 10 2 3
4 integers found.
With the really messy file:
$ ./bin/fgets_sscanf_int_any_ex <dat/10intmess.txt
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495
10 integers found.
Look things over and let me know if you have any questions.