gpt4 book ai didi

c - 将结构成员保存到 C 中的 .txt 文件时出现意外结果

转载 作者:行者123 更新时间:2023-12-05 00:13:46 26 4
gpt4 key购买 nike

我在尝试时遇到一些问题 将信息从我的程序保存到 .txt 文件 (或任何文件真的)。我一直在查看我的代码几次,但似乎找不到问题所在。最初我认为可能存在某种形式的内存泄漏(虽然我不知道内存泄漏的后果所以我不能确定)。

我想澄清一下,这是一项学校作业,毕竟我是来学习的,所以不要轻易给我答案!

这项任务是我们最后的也是最大的。我们正在创建一个带有结构的购物 list 。当我尝试使用结构成员将信息保存到 .txt 文件中(如果需要,稍后将它们加载到程序中)时,问题就开始了。我知道代码可能很可怕而且很伤眼睛,但请耐心等待。

这是我的“保存”功能。这是非常基本的,而且非常可怕。

void saveList(struct GList *grocery)
{
char file[20];
FILE *fp;

printf("What do you want to save the list as? (Don't include file extension): ");
scanf("%s", file);

fp = fopen(strcat(file, ".txt"), "w");

for (int i=0; i<grocery->Items; i++)
{
printf("%s %f %s\n", grocery->list[i].name, grocery->list[i].amount, grocery->list[i].unit);
fprintf(fp, "%s %f %s\n", grocery->list[i].name, grocery->list[i].amount, grocery->list[i].unit);
}
fclose(fp);
}

这是我在程序中输入的内容(添加项目时):
Name of the item: Avocado
Unit: kg
Amount: 10

这就是保存到我的 .txt 文件中的内容(它没有显示,但第一行总是包含一些奇怪的符号)。
  10.000000 kg
milk 10.000000 litres

同样的问题一直发生;第一个项目名称(例如鳄梨)显示为一些奇怪的符号。

这是我的完整代码,问题可能出在这里。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>

struct Grocery {
char name[20];
char unit[20];
float amount;
};

struct GList {
size_t Items;
struct Grocery *list;
};

int addGrocery();
void printList();
void hQuit();
void inputError();
void removeItem();
void changeItem();
void saveList();

int main()
{
struct GList glist;
glist.Items = 1;

size_t menuChoice = 0;
char cont = 'y';

if((glist.list = malloc(sizeof(glist.list))) == NULL)
return ENOMEM;

puts("Welcome to your Grocery List Manager");

do
{
printf("\n- - - - - - - - - - -\n[1] Add an item\n[2] Print grocery list\n[3] Remove a grocery\n[4] Edit a grocery\n[5] Save your list\n[6] Load a list\n[7] Quit\n\nPlease choose action: ");
if(!scanf("%u", &menuChoice))
return EIO;

putchar('\n');

switch(menuChoice)
{
case 1:
addGrocery(&glist);
break;
case 2:
printList(&glist);
break;
case 3:
removeItem(&glist);
break;
case 4:
changeItem(&glist);
break;
case 5:
saveList(&glist);
break;
case 6:
//Load shopping list
break;
case 7:
hQuit(&glist);
break;
default:
inputError();
break;
}
} while (cont == 'y');

//free(grocery);

return 0;
}

int addGrocery(struct GList *grocery)
{
printf("Name of the grocery: ");
if(!scanf("%s", grocery->list[grocery->Items].name))
return EIO;

printf("Unit: ");
if(!scanf("%s", grocery->list[grocery->Items].unit))
return EIO;

printf("Amount: ");
if(!scanf("%f", &grocery->list[grocery->Items].amount))
return EIO;

printf("You have added %f %s of %s into your list!\n\n", grocery->list[grocery->Items].amount, grocery->list[grocery->Items].unit, grocery->list[grocery->Items].name);

(grocery->Items)++;
grocery->list = realloc(grocery->list, grocery->Items * sizeof(grocery->list));

if(grocery->list == NULL)
return ENOMEM;

return 1;
}

void printList(struct GList *grocery)
{
if ((grocery->Items - 1) > 0)
printf("You have added %d item(s) into your list!\n", grocery->Items - 1);
else
printf("You have no items in your list!\n");

for (int i=1; i<grocery->Items; i++)
{
printf("[%d] %-10s %.1f %s\n", i, grocery->list[i].name, grocery->list[i].amount, grocery->list[i].unit);
}
putchar('\n');
}

void removeItem(struct GList *grocery)
{
size_t index = 0;
printf("Which item would you wish to remove from the list? ");
scanf("%u", &index);
printf("\nYou have removed %s from your grocery list!", grocery->list[index].name);
for (int i=(int)index; i < grocery->Items; i++)
grocery->list[i] = grocery->list[i+1];

(grocery->Items)--;
}

void changeItem(struct GList *grocery)
{
size_t index = 0;
printf("Which item would you like to edit the amount of? ");
scanf("%d", &index);
printf("\nCurrent amount: %.1f %s\nEnter new amount: ", grocery->list[index].amount, grocery->list[index].unit);
scanf("%f", &grocery->list[index].amount);
printf("\nYou changed the amount to %.1f!\n", grocery->list[index].amount);
}

void hQuit(struct GList *grocery)
{
puts("*-*-* Thank you for using the Grocery List! *-*-*");
free(grocery->list);
exit(0);
}

void inputError(struct GList *grocery)
{
puts("No such option. Please try again!\n");
}

void saveList(struct GList *grocery)
{
char file[20];
FILE *fp;
printf("What do you want to save the list as? (Don't include file extension): ");
scanf("%s", file);
fp = fopen(strcat(file, ".txt"), "w");
for (int i=0; i<grocery->Items; i++)
{
printf("%s %f %s\n", grocery->list[i].name, grocery->list[i].amount, grocery->list[i].unit);
fprintf(fp, "%s %f %s\n", grocery->list[i].name, grocery->list[i].amount, grocery->list[i].unit);
}

fclose(fp);
}

如果我的代码在某些地方看起来很奇怪(为什么你有一个 void inputError()?)那是因为我们的老师为我们的作业设置了一些非常奇怪的规则。

请随意抨击我的代码。

最佳答案

问问自己,“C 使用基于 0 还是基于 1 的数组索引”?

调用addGrocery的时候,传递的是glist的地址,

addGrocery(&glist);

第一次调用 addGrocery 时,glist 的第一个/初始值是多少?在添加第一项之前,此列表包含多少项?这是“列表”还是“数组”?

这是您的主要功能的前几行(回答了这个问题),
int main()
{
struct GList glist;
glist.Items = 1;

if((glist.list = malloc(sizeof(glist.list))) == NULL)
return ENOMEM;

考虑定义一个函数(一个构造函数)来创建初始(空)列表。以及将元素添加到列表的函数。

您的 addGrocery 函数将输入数据和将数据添加到列表中。考虑一个仅收集输入然后调用该函数将数据添加到列表的函数。
int addGrocery(struct GList *grocery)
{
printf("Name of the grocery: ");
//what is the value of grocery-Items the first time this is called?
if(!scanf("%s", grocery->list[grocery->Items].name))
return EIO;

//Consider something that creates a grocery list item (does malloc)
//then appends that list item to the list

//then this check would not be needed (well, it would change)
if(grocery->list == NULL)
return ENOMEM;

提示:您是否添加到第一个列表元素?

但还有一个更大的问题。您是使用数组还是列表来存储 struct Grocery 项目?您将 list 声明为一个指针,并在 main 中对其进行初始化。您是否分配了一些项目的数组,或者您想要一个项目列表? struct Grocery 类型没有指针,因此您可能不需要“列表”,而是“数组”(命名很重要)。
struct GList {
size_t Items;
struct Grocery *list;
};

因为您的 addGrocery 函数使用数组索引,所以假设您想要一个 Grocery 项目的数组,但是您创建了多少个?你在解决哪一个?

(这些问题应该为您指明正确的方向)

关于c - 将结构成员保存到 C 中的 .txt 文件时出现意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48198166/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com