В вашем коде есть некоторые проблемы, например, строка режима неверна "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