简体   繁体   中英

What is the best way to extract substrings from a longer string in C

I have a file formatted as a string followed by a long list of floats separated by spaces:

string (space) float (space) ... float

string (space) float (space) ... float

.

.

.

string (space) float (space) ... float

Each line's string and floats are to be put in a struct, and currently the way I am doing it is by storing each line as a string using fgets, and then incrementing through that string, checking for substrings between spaces, and then converting those strings to floats and storing those in my struct.

This is getting to be very tedious and very complex. Is there a better way to do it?

Depending on number of variables to be fixed or variadic, there are two possible approaches. In case of fixed number of floats the possible solution might be:

'test_data.txt' file with data:

test1 1.41 1.73 2.78 3.14
test2 2.41 2.73 3.78 4.14

and source file for reading the data might be:

#include <stdio.h>

int main(int argc, char ** argv)
{
        FILE * file = fopen("test_data.txt", "r");
        if (file == NULL)
        {
                printf("Cannot open file.\n");
                return 1;
        }

        char string[32] = { 0 };
        float f1, f2, f3, f4;
        while (feof(file) == 0)
        {
                fscanf(file, "%s %f %f %f %f", string, & f1, & f2, & f3, & f4);
                printf("For string: %s values are:\n\t%f %f %f %f\n", string, f1, f2, f3, f4);
        }

        fclose(file);
        return 0;
}

But taking into consideration you stated number of floats are variadic, the possible solution might have been like this:

'test_data.txt' file with data:

test1 1.41 1.73 2.78 3.14
test2 2.41 2.73 3.78 4.14 5.15

and source file for reading the data might be:

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

static void remove_trailing_spaces(char ** begin)
{
        while (isspace(** begin))
                ++(* begin);
        return;
}

static void get_string(char ** begin, char * output)
{
        remove_trailing_spaces(begin);

        char * end = * begin;
        while (isalnum(* end))
                ++end;

        strncpy(output, * begin, (int)(end - * begin));
        * begin = end;
        return;
}

static void get_float(char ** begin, float * output)
{
        remove_trailing_spaces(begin);

        char * end;
        * output = strtof(* begin, & end);
        * begin = end;
        return;
}

int main(int argc, char ** argv)
{
        FILE * file = fopen("test_data.txt", "r");
        if (file == NULL)
        {
                printf("Cannot open file\n");
                return 1;
        }

        char buffer[1024] = { 0 };
        char string[32] = { 0 };
        while (feof(file) == 0)
        {
                if (fgets(buffer, 1024, file) != NULL)
                {
                        char * begin = & buffer[0];
                        get_string(& begin, string);
                        printf("For string: %s values are:\n\t", string);

                        while ((feof(file) == 0) && (* begin != '\n'))
                        {
                                float f = 0.0;
                                get_float(& begin, & f);
                                printf("%f ", f);
                        }
                        printf("\n");
                }
        }
        fclose(file);
        return 0;
}

Bear in mind it may not be the best possible solution. It only shows that parsing of text file with changing number of data in each line of the test_data.txt file is a bit more effort than in first case.

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