When reading any set of values from a file into an array, you first need an input routine that will read the values into the type of storage needed. You can either spend your life writing input routines over-and-over again to match each input file format, or you can write a flexible routine once and use it over-and-over again. strtol (or any of the other strtoX functions) provide a simple, format neutral, way to parse values from input regardless of format. The declaration for strtol is:
long int strtol(const char *nptr, char **endptr, int base);
The function takes a pointer to a string given as its first argument. Given any string, you simply use a pointer to skip all non-digit characters and pass the pointer value to strtol when you encounter a - or [0-9]. strtol will convert the digits into number, stopping when it encounters the first non-digit, and then update endptr to point to the first non-digit after the number it just converted.
By using the endptr value and simply working down the string to the next - or [0-9] and using that value as the next input to the function, you can work your way through any string and convert all numbers it contains -- regardless of the input format. When you encounter a '\n', simply repeat the process for the next line until the file is read.
The next part of your problem is simply comparing the values of the numbers converted against 9 and storing any values greater than 9 in an array for later use in your program. As with all functions, you need to do appropriate error checking along the way and respond to any error conditions accordingly.
Below is a short example which does that. note: the strtol function is wrapped in a short function xstrtol which simply provides the required error checking without cluttering the main body of your code with it. Let me know if you have questions:
#include <stdio.h>
#include <stdlib.h> /* for strtol */
#include <limits.h> /* for LONG_MIN/LONG_MAX */
#include <errno.h> /* for errno */
#define MAXL 256
long xstrtol (char *p, char **ep, int base);
int main (int argc, char **argv)
{
int values[MAXL] = {0};
char line[MAXL] = {0};
size_t i, idx = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open */
fprintf (stderr, "error: file open failen '%s'.\n", argv[1]);
return 1;
}
/* read each line in file (up to MAXL chars per-line) */
while (fgets (line, MAXL, fp)) {
char *p = line;
char *ep = p;
int tmp;
errno = 0;
/* convert each string of digits into number */
while (errno == 0) {
/* skip any non-digit characters */
while (*p && ((*p != '-' && (*p < '0' || *p > '9')) ||
(*p == '-' && (*(p+1) < '0' || *(p+1) > '9')))) p++;
if (!*p) break;
/* convert string to number */
tmp = (int)xstrtol (p, &ep, 10);
/* test if tmp > 9 and store */
if (tmp > 9)
values[idx++] = tmp;
if (errno) break; /* check for error */
if (idx == MAXL) { /* check if array full */
fprintf (stderr, "warning: MAXL values read.\n");
break;
}
/* skip delimiters/move pointer to next digit */
while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
if (*ep)
p = ep;
else /* break if end of string */
break;
}
}
if (fp != stdin) fclose (fp);
printf ("\nvalues read from '%s'\n\n", argc > 1 ? argv[1] : "stdin");
for (i = 0; i < idx; i++)
printf (" values[%3zu] : %d\n", i, values[i]);
return 0;
}
/** a simple strtol implementation with error checking.
* any failed conversion will cause program exit. Adjust
* response to failed conversion as required.
*/
long xstrtol (char *p, char **ep, int base)
{
errno = 0;
long tmp = strtol (p, ep, base);
/* Check for various possible errors */
if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtol");
exit (EXIT_FAILURE);
}
if (*ep == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
return tmp;
}
Compile
gcc -Wall -Wextra -O3 -o bin/fgets_xstrtol_select fgets_xstrtol_select.c
(replace the -O3 optimization with -g to generate debugging symbols)
Input File
$ cat dat/intvalues.txt
10 9 13 20 29 29 12 9 3 59
12 14 42 45 65 21 12
0 94 23 12 43 67 49 23 20
Use/Output
$ ./bin/fgets_xstrtol_select <dat/intvalues.txt
values read from 'stdin'
values[ 0] : 10
values[ 1] : 13
values[ 2] : 20
values[ 3] : 29
values[ 4] : 29
values[ 5] : 12
values[ 6] : 59
values[ 7] : 12
values[ 8] : 14
values[ 9] : 42
values[ 10] : 45
values[ 11] : 65
values[ 12] : 21
values[ 13] : 12
values[ 14] : 94
values[ 15] : 23
values[ 16] : 12
values[ 17] : 43
values[ 18] : 67
values[ 19] : 49
values[ 20] : 23
values[ 21] : 20
<= 9?