0

I have an input file in text format that looks like:

G:  5   10  20  30
C:  24  49  4.0 30.0

I'd like to set each of these to an array, array, respectively. I saw from this answer reading input parameters from a text file with C, a way to read some of the values, but how would I get the arrays G and C?

EDIT:

If I removed G:, and C: from the .txt file I could just run a for loop.

double *conc = (double*)malloc(properConfigs*sizeof(double));
double *G = (double*)malloc(properConfigs*sizeof(double));

for (int i=0;i<properConfigs;i++)
    fscanf(inputfile,"%lf", &G[i]);
for (int i=0;i<properConfigs;i++)
    fscanf(inputfile,"%lf", &conc[i]); 

This would work, but I'd like to be able to account for someone saving the .txt file in a different order or at some point adding more rows (with different parameters).

Gregory
  • 341
  • 1
  • 2
  • 10
  • 3
    Please read [Why is “while (!feof(file))” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feoffile-always-wrong) – Some programmer dude May 29 '19 at 16:04
  • As for your problem, is what you show the *complete* file? Is it a complete record, but there can be more records like that in the file? Can there be an arbitrary number of `G` and `C` lines after the two first header lines? – Some programmer dude May 29 '19 at 16:06
  • Anyway, my tip is to not try to generalize it, unless the `C` and `G` lines can occur multiple times, in which case you could generalize for those two type. Otherwise read the four lines separately, and parse the separately. Will make your code much less complex. – Some programmer dude May 29 '19 at 16:08
  • @Someprogrammerdude, yes the file will have these four lines. The C and G length is actually dependent on Nbp, which may be a problem since I will then need to dynamically allocate the array after reading this number in. Can you elaborate on how you would parse each line separately. Is it as simple as searching till I find the string 'G : ' and then using a for loop? – Gregory May 29 '19 at 17:28

2 Answers2

2

I am not a fan of scanf, and would strongly encourage you to parse the line yourself. If you insist on using scanf, I recommend using the sscanf variant for this so you can check the line beforehand to see which array to write. I'm not sure why you're using named arrays at all, though. C is not very good at introspection, and you can make your program more flexible without trying to tie your input to particular symbols. Something like:

#include <stdio.h>
#include <stdlib.h>

#define properConfigs 4
void *Malloc(size_t s);
int
main(int argc, char **argv)
{
        FILE *fp = argc > 1 ? fopen(argv[1],"r") : stdin;
        double *G = Malloc( properConfigs * sizeof *G );
        double *C = Malloc( properConfigs * sizeof *G );
        int line_count = 0;
        char line[256];

        if( fp == NULL ) {
                perror(argv[1]);
                return 1;
        }
        while( line_count += 1, fgets( line, sizeof line, fp ) != NULL ) {
                double *target = NULL;
                switch(line[0]) {
                case 'G': target = G; break;
                case 'C': target = C; break;
                }
                if( target == NULL || 4 != sscanf(
                                line, "%*s%lf%lf%lf%lf",
                                target, target+1, target+2, target+3)) {
                        fprintf(stderr, "Bad input on line %d\n", line_count);
                }
        }
        for(int i=0; i < 4; i += 1 ) {
                printf ("G[%d] = %g\tC[%d] = %g\n", i, G[i], i, C[i]);
        }


        return ferror(fp);
}
void *Malloc(size_t s) {
        void *r = malloc(s);
        if(r == NULL) {
                perror("malloc");
                exit(EXIT_FAILURE);
        }
        return r;
}
William Pursell
  • 204,365
  • 48
  • 270
  • 300
0

Looks like your issue is atof() in c discards any white space after the first valid number. If you want to get all of the numbers you will have to split tmpstr2 and do each element separately in atof().

You can use strtok to split it into tokens then use atof() on each.

char temp[];
char *nums;
nums = strtok(temp, " \t");
int count = 0;
while (nums != NULL)
{
    G[count] = atof(chrs);
    nums = strtok(NULL, " \t");
    count++;
}

Of course that is if you know before hand how many numbers you are going to get.

View this article for more info: Split string with delimiters in C

taras
  • 6,566
  • 10
  • 39
  • 50
Kyrei
  • 240
  • 2
  • 7