#c #file #struct #scanf #readfile
#c #файл #структура #scanf #readfile
Вопрос:
Я работаю над назначением, которое помещает файл, содержащий рецепт, и создает экземпляр структуры для хранения информации. Это формат, которому соответствует моя структура:
struct Dinner
{
char* recipeName;
unsigned numMainDishIngredients;
char** mainDishIngredients;
unsigned numDessertIngredients;
char** DessertIngredients;
};
Мне нужно выяснить, как использовать чтение в файле, который будет структурирован следующим образом:
Первая строка будет содержать название рецепта, во второй строке будет указано количество ингредиентов в основном блюде, затем в следующих строках каждая будет содержать по одному ингредиенту, который входит в основное блюдо, пока не появится одна пустая строка. Строка, следующая за пустой строкой, будет содержать количество ингредиентов в десерте, а каждая следующая строка будет содержать ингредиент десерта.
Пример выглядит следующим образом:
Pizza and Ice Cream
4
Dough
Cheese
Sauce
Toppings
3
Cream
Sugar
Vanilla
Я в основном не уверен в том, как читать в типах char **. Пока это все, что у меня есть:
struct Dinner* readRecipe(const char* recipeFile)
if (!recipeFile)
{
return NULL;
}
File* file = fopen(recipeFile, "r");
if (!file)
{
return NULL;
}
char recipeName[50]; // specified that strings wont exceed 49 chars
int numMainIngredients, numDessertIngredients;
fscanf(file, "%s, %d", amp;recipeName, numMainIngredients);
...
}
В принципе, я не знаю, как прочитать несколько строк файла в тип массива в структуре, и я был бы очень признателен за любые советы о том, как это сделать.
Комментарии:
1. Задание, должно быть, пыталось научить вас чему-то раньше. Что это было? Возможно, это связано с выделением памяти и такими функциями, как
malloc
,calloc
,realloc
иfree
? См. en.cppreference.com/w/c/memory2. Да, мы должны использовать malloc или calloc, а также free в назначении, но я в основном не понимаю, как я могу выделять память, одновременно используя fscanf.
3. Один из вариантов — прочитать строку во временную переменную like
char ingredient[32]
, а затем продублировать ее сchar *p = malloc(strlen(ingredient) 1); strcpy(p, ingredient);
помощью .4. Другой вариант — выделить больше, чем вам нужно. Если максимальная длина равна 50, выделите 51 (всегда помните о завершающем ‘ 0’ в строках.
5. Удаление
fscanf()
. Прочитайте строку сfgets()
помощью, а затем проанализируйте строку.
Ответ №1:
Чтение из файла довольно простое. Большинство функций std предназначены для чтения одной строки из файла, а затем автоматического перехода к следующей строке. Итак, все, что вам действительно нужно сделать, это цикл.
Я рекомендую вам написать следующее
#define MAXCHAR 256
char[MAXCHAR] line;
while(fgets(line, MAXCHAR, file) != NULL)
{
// line now has the next line in the file
// do something with it. store it away
// use atoi() for get the number?
// whatever you need.
}
То есть мы используем fgets()
для захвата следующей строки в файле; и если мы зациклим эту связку; он будет считываться до конца файла (EOF).
Обратите внимание, что я использовал fgets()
вместо fscanf()
. fgets()
это более безопасный и эффективный вариант, чем fscanf. Конечно, в нем нет причудливой возможности указывать форматирование строк и тому подобное; но это не так уж сложно сделать самостоятельно.
редактировать: я довольно сильно перепутал свои языки .. исправил это.