Parsing Tab Delim Lines Into Array in C Programmin

2019-08-25 01:35发布

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:

  1. Finding ways of how to assign each line to the correct array.
  2. Printing out the content of the array (for checking).

标签: c parsing
3条回答
在下西门庆
2楼-- · 2019-08-25 02:17
  1. You're going to need dynamically allocated arrays. Unless you can be absolutely sure at compile time of the amount of data you're going to read in (and you can't, or at least shouldn't), you're going to have to use pointers to arrays allocated with malloc() and realloc(). If you don't know how to do this, read up on memory management in C.
  2. You're going to need to convert char * (textual) data to numeric types. My personal favorite functions are strtol() and strtod(), but there are also atoi() and atof() functions that may be avaliable. However, since we're working with a file stream, here, you may have much better luck with fscanf() to do the conversion for you. All of these functions are in the standard library, except strtod(), 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))

查看更多
Deceive 欺骗
3楼-- · 2019-08-25 02:25

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.

#include <stdio.h>
#include <assert.h>

const unsigned MAX_N=1000; /* use malloc/realloc if it matters to you */
double Line3[MAX_N];
unsigned N3=0;

unsigned c;
FILE *f;
f=fopen("myfile.txt","r");
while ((c=fgetc(f)) != EOF) {
  if (c=='\n'||c=='\r') break;
  ungetc(c,f);
  assert(N3<MAX_N);
  fscanf(f," %lf",&Line3[N3++]); /* the space means 'skip whitespace' */
} /* Line3 holds N3 items */

/* similar for int except fscanf " %d" */
查看更多
\"骚年 ilove
4楼-- · 2019-08-25 02:26

strtok() in string.h should get the job done.

查看更多
登录 后发表回答