Member 14351155 Ответов: 2

Как считывать данные различных типов из csv-файла и хранить их в 2d-массиве


Пример csv-файла:

3,4
,,С 200,
М Целебное Зелье:85,,М Защита:360
,,,

Первая строка файла-это номер строки и столбца, вторая строка-это данные, которые я должен поместить в 2d-массив. Каждый разделитель запятых-это отдельный столбец.

Я изо всех сил пытаюсь придумать способ считывания данных, особенно с запятыми между словами

Что я уже пробовал:

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

/*I know I have to use structure, but I am not sure how to start*/
typedef struct{

}

int main(int argc, char *argv[])
{
FILE *map;

/*I have done declaring a 2d array with malloc*/

}

2 Ответов

Рейтинг:
5

Member 14351155

char **arr;

Арр = (тип char**)Танос(подряд*оператор sizeof(тип char*));

для(i=0; i<row; i++)
{
arr[i] = (char*)malloc(column*sizeof(char));
}


для(i=0; i<row; i++)
для(j=0; j<столбец; j++)


Рейтинг:
2

OriginalGriff

На самом деле это не CSV - файл-это набор строк данных, содержащих элементы, разделенные запятыми: "истинный" файл CVS содержит необязательную строку заголовка, а затем строки, содержащие одинаковое количество элементов одного типа в каждом столбце, необязательно используя двойные кавычки для разграничения строковых значений.

Здесь есть большая разница: CSV-это таблица, а не "случайный" набор данных.

Ваши данные выглядят организованными в строки, но столбцы не являются таблицей - поэтому не называйте их CSV-файлом, называйте их "конфигурационным файлом" или чем-то подобным, потому что это лучше отражает структуру ваших данных. Не каждая строка в вашем образце данных содержит четыре элемента (например, посчитайте запятые в строке "целебное зелье").

Начните с чтения каждой строки - что вы должны знать, как это сделать, - а затем разделите каждую на разделы, найдя запятые.

Я бы не стал сразу переходить к структуре - не так уж очевидно, какие типы данных вам понадобятся из этого небольшого примера, - но 2D-массив довольно тривиален: прочтите первую строку, и она даст вам размеры, так что вы можете построить 2D-массив из двух типов данных. char* Затем каждый отдельный элемент, который вы находите до запятой, копируется в новый char буфер, завершенный нулем и установленный в соответствующий элемент 2D-массива.

Попробуйте это на бумаге, и вы поймете, что я имею в виду.


OriginalGriff

Начните с одной строки и напишите функцию, которая возвращает указатель на массив значений char*, который разбивает его на отдельные строки - это довольно просто, просто не забудьте использовать malloc для всего массива, а затем снова для каждой отдельной строки, Когда вы их разбиваете. (Подсказка: strcpy может быть полезен здесь!)

Проверьте его и убедитесь, что он работает.

Member 14351155

Не могли бы вы написать мне короткий пример? Я все еще не очень уверен, как это сделать.
Я только написал объявление 2D массива:

char **arr;

Арр = (тип char**)Танос(подряд*оператор sizeof(тип char*));
для(I=0; I

Member 14351155

Так что извините, мне трудно понять это словами, можно мне привести пример?

OriginalGriff

Нет, давай - это не сложно, и ты ничего не узнаешь, если я просто дам тебе решение.
Напишите "фреймворк" для метода: верните массив указателей char*, примите один параметр char*.
Когда у тебя это будет, покажи мне.

Member 14351155

Что означает это предложение: "тогда каждый отдельный элемент, который вы находите до запятой, копируется в новый буфер символов, завершается нулем и устанавливается в соответствующий элемент 2D-массива"?

OriginalGriff

Сканируйте строку, которую вам вручили, в поисках запятых.
12345,67,890
Запятые в колонках 5, 8

Когда вы находите один, вы знаете, как долго текст
12345,67,890
Длина текста-5, 2, 3

Теперь вы можете выделить достаточно большой кусок памяти для текста плюс один для нулевого символа Терминатора. Танос что (первый раз 6, второй 3, Третий 4) и добавить указатель на выходной массив.
Затем скопируйте текст (и нуль) в новый буфер.

Member 14351155

Например, я должен прочитать первую строку (,,C 20,) в массив, то, что мне нужно, выглядит так: array[0][0] = nothing, array[0][1] = nothing, если обнаруживает C array[0][2] = 20, то последний array[0][3] = nothing

OriginalGriff

Так что разбейте задачу на части. Начните делать это в несколько простых этапов - и первый состоит в том, чтобы разбить строку на отдельные строки. Это "универсальная" задача - она не зависит от ваших данных, поэтому ее можно использовать для первой строки, содержащей ваши индексы, а также для других.
Поработай над этим, прежде чем двигаться дальше.

Member 14351155

Значит ли это, что я должен использовать strtok?

OriginalGriff

Ты, конечно, можешь.

Member 14351155

Где я должен его использовать? Находится ли он в цикле, где я читаю файл и назначаю его массиву?

Rick York

Проблема с использованием strtok с вашими данными заключается в том, что запятая является разделителем, а strtok обнуляет разделители, поэтому вы пропустите последовательные запятые.