Nano Hash - криптовалюты, майнинг, программирование

fscanf определенные цифры из файла

Итак, я получил этот файл, и я хочу scanf() только цифры внутри первого {}, чем цифры внутри второго {} и так далее. Мне удалось назвать только цифры из файла, но я не знаю, как разделить их на группы

это файл:

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

Ниже приведен код, который я использую до сих пор

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

    }
}
14.01.2016

  • Как вы узнали fscanf()? Этот код неверен, например, нет гарантии, что rc будет EOF при первом сбое fscanf(). 14.01.2016
  • if( ch =='{') тестирует неинициализированную переменную, которая даже не устанавливается впоследствии. 14.01.2016
  • я помещаю весь код, если это поможет @WeatherVane не замечайте эту строку, я удалил ее 14.01.2016
  • Значит, вы так долго бились над 20 строками кода, что даже не заметили переменную, которую не используете? Кстати, должно быть int main(void) 14.01.2016
  • Вы уверены, что библиотека JSON не будет лучшим выбором? В противном случае это выглядит как «чтение строки; строка процесса, не обязательно только с sscanf(), было бы разумным подходом, чтобы упростить пропуск { и }. 15.01.2016

Ответы:


1

В вашем коде есть некоторые проблемы, например, строка режима неверна "rt"? Вам нужно указать только "b" для двоичного файла, и это влияет только на символ конец строки, что может быть проблемой, если файл читается/записывается на разных платформах.

Чтобы достичь того, чего вы хотите, нет простого способа, как предлагает @JonathanLeffler в этом комментарии вы можете использовать библиотеку json json-c1 очень прост в использовании.

Если вы хотите сделать это самостоятельно, попробуйте этот код, который я только что написал

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

Конечно, существует множество возможных оптимизаций (особенно realloc() частей), но я оставляю это на ваше усмотрение.

Выше указатель int **, возвращаемый parse_line(), содержит count массивов, где первый элемент — это длина каждого массива.


1Я знаю, что в большинстве дистрибутивов Linux его можно установить с помощью менеджера пакетов, и в последнее время я часто использую его для некоторых проектов, связанных с веб-разработкой.

14.01.2016

2

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

Если числа, которые вы пытаетесь прочитать, будут только однозначными числами, вы можете отказаться от функций fseek и fscanf и вместо этого использовать getc. Просто проверьте каждое чтение на наличие всего, что не является числом от «0» до «9». C getc

На тех веб-сайтах, на которые я ссылался, также есть много других хороших руководств по изучению C\C++.

Удачи. Редактировать: менее снисходительно.

14.01.2016
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..