Given a file (e.g. myfile.txt) with this content (always three lines):
0 2 5 9 10 12
0 1 0 2 4 1 2 3 4 2 1 4
2 3 3 -1 4 4 -3 1 2 2 6 1
How can we parse the file, such that it is stored in arrays, just as if they were hard coded this way:
int Line1[] = { 0, 2, 5, 9, 10, 12 };
int Line2[] = { 0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4 };
double Line3[] = { 2, 3, 3, -1, 4, 4, -3, 1, 2, 2, 6, 1 };
Update: based on comments by wrang-wrang. I am currently stuck with this code.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main ( int arg_count, char *arg_vec[] ) {
int ch;
FILE * fp;
int i;
if (arg_count <2) {
printf("Usage: %s filename\n", arg_vec[0]);
exit(1);
}
//printf("%s \n\n", arg_vec[i]); // print file name
if ((fp = fopen(arg_vec[1], "r")) == NULL) { // can't open file
printf("Can't open %s \n", arg_vec[1]);
exit(1)
}
const unsigned MAX_N=1000;
int Line1[MAX_N];
int Line2[MAX_N];
double Line3[MAX_N];
unsigned N3=0;
// Parsing content
while ((ch = fgetc(fp)) != EOF) {
if (ch=='\n' || ch=='\r') break;
ungetc(ch,fp);
assert(N3<MAX_N);
fscanf(fp, " %1f", &Line3[N3++]);
// not sure how to capture line 1 and 2 for
// for array Line1 and Line2
}
fclose(fp);
// This fails to print the content the array
for (int j=0; j <Line3; j++) {
printf(Line3[j],"\n");
}
return 0;
}
In principle I have problem in:
- Finding ways of how to assign each line to the correct array.
- Printing out the content of the array (for checking).
malloc()
andrealloc()
. If you don't know how to do this, read up on memory management in C.char *
(textual) data to numeric types. My personal favorite functions arestrtol()
andstrtod()
, but there are alsoatoi()
andatof()
functions that may be avaliable. However, since we're working with a file stream, here, you may have much better luck withfscanf()
to do the conversion for you. All of these functions are in the standard library, exceptstrtod()
, which is C99-specific (so it's in there if you're lucky).If you don't know how to use any of the functions named there, it should be easy to find manpages for them, either on your system (section 3, e.g.
man 3 malloc
) or the internets (malloc(3))Here's a less-usual approach that makes only a single pass over the input bytes. Scanf will skip whitespace for you, but you don't want it skipping newlines. As long as your newlines immediately follow the last non-space character, reading a single character and putting it back if it's not a newline will work. A more robust solution could manually parse the whitespace and put back the first nonspace char before scanf.
Perhaps just copying the nonspace characters into a buffer and using one of the string->number conversions (sscanf, strtol, etc.) would be simpler.
It's more common to read entire lines at once using a library function, then parse the lines. There's nothing in ANSI C that will do that for you, let alone for arbitrary line length.
strtok() in
string.h
should get the job done.