If you choose to use an array with automatic storage duration, you must declare the array in the calling function and pass a pointer to the array to your function. You can then fill the array in the function. However, you must also provide a way to return the number of strings read. Your choice of a void
type for your function complicates this (slightly) as you would normally choose a meaningful return type such as size_t
allowing you to return the number of strings read. That notwithstanding, you can pass a pointer to a size_t
value and update the value at that address within your function thereby making the number of strings available back in the calling function.
A few notes:
/* if you need a constant, #define one (or more) */
#define STRSZ 32 /* maximum string stize in array */
#define NSTR 100 /* maximum number of strings in array */
(don't skimp on buffer size) The longest word in the unabridged dictionary (non-medical) is 29-characters and the longest 64-bit number is 20-character (including sign), so for normal use a buffer size of 30
will suffice, 32
will account for any trailing punctuation mark. (if space isn't a consideration for the number of strings you need to read, double STRSZ
to 64
) Adjust the number of strings and the maximum characters in each as needed.
Your function can then be written to take a pointer to an array of char [32], e.g.
void to_array (char (*arr)[STRSZ], FILE *fp, size_t *nstr)
{
*nstr = 0; /* initialize number of strings to zero */
/* protect array bounds while reading each string from file */
while (*nstr < NSTR && fscanf (fp, "%31s" , arr[*nstr]) != EOF)
(*nstr)++; /* increment number of strings */
}
(note: the use of the field-width modifier "%31s"
to protect the bounds of each string when reading from the file, and the use of *nstr < NSTR
to protect the array bounds for the number of strings read from the file)
In main()
, you can simply declare a 2D array with automatic storage duration and a variable to keep track of the number of strings filled, e.g.
char arr[NSTR][STRSZ] = {{0}}; /* array to hold strings (max 31 char) */
size_t n = 0; /* number of strings read */
Now you can call your to_array()
function as follows:
to_array (arr, fp, &n); /* read strings from file, n holds number */
Putting it altogether along with proper validation that your file is open for reading before your call to to_array()
, you could do:
#include <stdio.h>
/* if you need a constant, #define one (or more) */
#define STRSZ 32 /* maximum string size */
#define NSTR 100 /* maximum number of strings in array */
void to_array (char (*arr)[STRSZ], FILE *fp, size_t *nstr)
{
*nstr = 0; /* initialize number of strings to zero */
/* protect array bounds while reading each string from file */
while (*nstr < NSTR && fscanf (fp, "%31s" , arr[*nstr]) != EOF)
(*nstr)++; /* increment number of strings */
}
int main (int argc, char **argv) {
char arr[NSTR][STRSZ] = {{0}}; /* array to hold strings (max 31 char) */
size_t n = 0; /* number of strings read */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
to_array (arr, fp, &n); /* read strings from file, n holds number */
if (fp != stdin) fclose (fp); /* close file if not stdin */
for (size_t i = 0; i < n; i++) /* output each string in arr */
printf ("arr[%2zu] : '%s'\n", i, arr[i]);
}
Example Input File
$ cat ../dat/10int_nl.txt
8572
-2213
6434
16330
3034
12346
4855
16985
11250
1495
Example Use/Output
$ ./bin/fscanffile ../dat/10int_nl.txt
arr[ 0] : '8572'
arr[ 1] : '-2213'
arr[ 2] : '6434'
arr[ 3] : '16330'
arr[ 4] : '3034'
arr[ 5] : '12346'
arr[ 6] : '4855'
arr[ 7] : '16985'
arr[ 8] : '11250'
arr[ 9] : '1495'
Look things over and let me know if you have further questions. Consider using fgets()
if you need to read a line-at-a-time.