简体   繁体   中英

C: read json array using fscanf

I have an JSON array of arbitrary length in a file like this:

[ 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18 ]

I want to get the integers and store them in an new array.

I tried using fscanf(f, " [ %d , ", data); to capture the first integer but the fscanf returned -1 (using gcc on Ubuntu terminal).

Is the format specifier wrong? How to skip the square brackets and use comma to separate different integers?

My code here:

typedef struct {
    int *data;
    unsigned int len;
} intarr_t;    

intarr_t *intarr_load_json(const char *filename) {

    if (filename == NULL) {
        return NULL;
    }

    FILE *f = fopen(filename, "r");

    if (f == NULL) {
        printf("file open failed\n");
        return NULL;
    }

    int char_input = 0;
    int count = 0;
    int num_count = 0;

    //count the # of numbers in the file by counting # of ","
    while ((char_input = fgetc(f)) != EOF) {
        if (char_input == 44) {
            count++;
        }
    }

    num_count = count+1;

    printf("num_count is %d\n", num_count);

    intarr_t *intarr_loaded_json = malloc(sizeof(intarr_t));

    if (intarr_loaded_json == 0) {
        return NULL; // intarr_loaded_json malloc failed
    }

    if (num_count == 0) {
        intarr_loaded_json->len = num_count;
        intarr_loaded_json->data = NULL;
        return intarr_loaded_json;
    }

    intarr_loaded_json->len = num_count;
    intarr_loaded_json->data = malloc(sizeof(int) * num_count);

    if (intarr_loaded_json->data == 0) {
        printf("Malloc failed\n");
        return NULL; 
    }

    int a = 0;
    int b = 0;
    int i = 0;
    //char temp;
    int value = 0;

    //printf("a is %d\n", a);

    if ((a = fscanf(f, "[ %d , ", intarr_loaded_json->data + i) > 0) {
        printf("got first number\n");
        i++;
    }

    //printf("temp is %c\n", temp);
    printf("a is %d\n", a);

    while ((b = fscanf(f, " , %d", intarr_loaded_json->data + i)) == 1) {
        i++;
        printf("do while loop %d th time\n", i);
    }

    printf("b is %d\n", b);
    // printf("intarr_loaded_json->len is %d\n", intarr_loaded_json->len);

    return intarr_loaded_json;

    fclose(f);
}

You read through the file as far as EOF in order to count the number of commas. You never rewind the file, so you're at the end of file when you start trying to read the [ , and fscanf() correctly returns EOF (aka -1 — technically, EOF can be any negative number, but in practice it is always -1 ).

Add rewind(f); before trying to read the data a second time.

Or, better, don't do the counting up front — allocate more space as needed, usually doubling the size of the allocated array each time you need more space to avoid quadratic copying behaviour.

There could be other problems — more serious than the use of if (char_input == 44) instead of if (char_input == ',') or the misplaced and non-reachable fclose(f); . But the primary one is you've read to EOF and you don't rewind before trying to reread the data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM