简体   繁体   中英

fscanf specific digits from a file

So I got this file and i want to scanf() only the digits inside the first {} than the digits inside the second {} and so on. I've managed to call just the digits from the file, but I don't know how to separate them into groups

this is the file:

{5, 2, 3}, {1,5}, { }, { }, {3}, { }, { }

Below is the code I use so far

    void main()
{
    int rc=0,num,size;
    FILE* f = fopen("graph-file.txt","rt");
    if (f == NULL)
    {
        printf("Failed to open the file\n");
    }
    size = fscanf(f,"%d",&num);
    fseek(f,1,SEEK_CUR);
    while(rc != EOF)
    {
            if( rc == 1)
            {
                printf("%d\n",num);
            }
            fseek(f,1,SEEK_CUR);
        rc = fscanf(f,"%d",&num);

    }
}

Arrays are probably what you're going to need to accomplish this task. Arrays allow you to have various amounts of digits that you can store what you read into. That's how you can separate the groupings. The next part will be how to change which part of the array you're looking at, which this link should also help with. C Arrays Tutorial.

If the numbers that you're trying to read will only be single digit numbers, then you could ditch the fseek and fscanf functions and use getc instead. Just check each read for anything that's not a number '0'-'9'. C getc

Those websites I linked also have a lot of other good tutorials on them for learning C\\C++.

Good luck. Edit: less condescending.

Your code as it is has some issues, for example the mode string is wrong "rt" ? You only need to specify "b" for binary and that only affects the end of line character which can be a problem if the file is read/written on different platforms.

To achieve what you want there is no simple way, as @ JonathanLeffler suggests in this comment you could use a json library json-c 1 is a very easy to use one.

If you want to do it yourself, try this code that I did just write

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

int
append_number(int size, int **arrays, int value)
{
    void *pointer;

    pointer = realloc(arrays[0], (++size + 1) * sizeof(**arrays));
    if (pointer == NULL)
        return 0;
    arrays[0] = pointer;
    arrays[0][size] = value;

    return 1;
}

int
get_value(const char *input)
{
    if (input == NULL)
        return -1;
    while ((*input != '\0') && (isspace((unsigned char) *input) != 0))
        input++;
    if (*input == '\0')
        return -1;
    return atoi(input);
}

int *
extract_arrays(char *array)
{
    int value;
    int *list;
    list = malloc(sizeof(*list));
    if (list == NULL)
        return NULL;
    list[0] = 0;
    while (array != NULL)
    {
        char *delimiter;

        delimiter = strchr(array, ',');
        if (delimiter != NULL)
            *delimiter = '\0';
        value = get_value(array);
        if (value > 0)
            list[0] += append_number(list[0], &list, value);
        if (delimiter != NULL)
            array = delimiter + 1;
        else
            array = NULL;
    }

    return list;
}

void
print_array(int *list)
{
    fprintf(stdout, "[");
    for (int j = 1 ; j < list[0] ; ++j)
        fprintf(stdout, "%d ", list[j]);
    if (list[0] > 0)
        fprintf(stdout, "%d", list[list[0]]);
    fprintf(stdout, "]\n");
}

int **
parse_line(char *line, size_t *count)
{
    char *open;
    char *close;
    char *next;
    int **arrays; // Depends on the maximum size of an inner array

    *count = 0;
    arrays = NULL;
    next = line;

    while ((next != NULL) && ((open = strchr(next, '{')) != NULL))
    {
        close = strchr(open, '}');
        if (close != NULL)
        {
            void *pointer;
            char *values;

            *close = '\0';
            next = strchr(close + 1, ',');
            values = open + 1;
            pointer = realloc(arrays, (*count + 1) * sizeof(*arrays));
            if (pointer == NULL)
                goto error;
            arrays = pointer;

            arrays[(*count)++] = extract_arrays(values);
        }
        else
            next = open + 1;
    }
    return arrays;
error:
    for (size_t i = 0 ; i < *count ; ++i)
        free(arrays[i]);
    free(arrays);
    *count = 0;
    return NULL;
}

int main(void)
{
    char line[100];
    size_t count;
    int **arrays;
    FILE *file;

    file = fopen("graph-file.txt", "r");
    if (file == NULL)
        return -1; // Failure openning the file
    while (fgets(line, sizeof(line), file) != NULL)
    {
        arrays = parse_line(line, &count);
        for (size_t i = 0 ; i < count ; ++i)
        {
            print_array(arrays[i]);
            // DO something with it ...
            free(arrays[i]);
        }
        free(arrays);
    }
    fclose(file);
    return 0;
}

Of course, there are a lot of possible optimizations ( specially the realloc() parts ), but I leave that to you.

Above, the int ** pointer returned by parse_line() contains count arrays where the first element is the length of each array.


1 I know that on most linux distributions it can be installed with the package manager, and I have been using it a lot recently for some web development related projects.

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