Чтение данных с разделителями табуляции в массив в C

У меня есть входной файл в текстовом формате, который выглядит так:

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

Я хотел бы установить каждый из них в массив, массив соответственно. Из этого ответа я увидел чтение входных параметров из текстового файла с помощью C способ чтения некоторых значений, но как мне получить массивы G и C?

РЕДАКТИРОВАТЬ:

Если бы я удалил G: и C: из файла .txt, я мог бы просто запустить цикл for.

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]); 

Это сработает, но я хотел бы иметь возможность учитывать, что кто-то сохраняет файл .txt в другом порядке или в какой-то момент добавляет больше строк (с другими параметрами).

Что касается вашей проблемы, это то, что вы показываете файл полный? Это полная запись, но таких записей в файле может быть больше? Может ли быть произвольное количество строк G и C после двух первых строк заголовка?

Some programmer dude 29.05.2019 18:06

В любом случае, мой совет: не пытайтесь обобщать это, если только строки C и G не могут встречаться несколько раз, и в этом случае вы можете обобщить эти два типа. В противном случае прочитайте четыре строки отдельно и проанализируйте их отдельно. Сделает ваш код намного менее сложным.

Some programmer dude 29.05.2019 18:08

@Someprogrammerdude, да, в файле будут эти четыре строки. Длина C и G на самом деле зависит от Nbp, что может быть проблемой, поскольку мне нужно будет динамически выделить массив после чтения этого числа. Можете ли вы уточнить, как вы будете анализировать каждую строку отдельно. Это так же просто, как искать, пока я не найду строку «G:», а затем использовать цикл for?

Gregory 29.05.2019 19:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
649
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, ваша проблема в том, что atof() в c отбрасывает все пробелы после первого допустимого числа. Если вы хотите получить все числа, вам придется разделить tmpstr2 и выполнить каждый элемент отдельно в atof().

Вы можете использовать strtok, чтобы разделить его на токены, а затем использовать atof() для каждого.

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

Конечно, если вы заранее знаете, сколько номеров вы получите.

Просмотрите эту статью для получения дополнительной информации: Разделить строку с разделителями в C

Ответ принят как подходящий

Я не фанат scanf и настоятельно рекомендую вам разобрать строку самостоятельно. Если вы настаиваете на использовании scanf, я рекомендую использовать для этого вариант sscanf, чтобы вы могли заранее проверить строку, чтобы увидеть, какой массив нужно записать. Я не уверен, почему вы вообще используете именованные массивы. C не очень хорош в самоанализе, и вы можете сделать свою программу более гибкой, не пытаясь привязать свой ввод к определенным символам. Что-то типа:

#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;
}

Другие вопросы по теме