我试图创建一个可以在文本文件中存储某些信息的程序。我遇到的问题是,到目前为止我写的代码中存储的信息是一堆奇怪的符号和字符。我设法找到它发生的地方,但我似乎无法解决它。看起来在我的register_item函数中,项目编号和余额由于某种原因得到了奇怪的值。如果有人能看到我犯了什么错误,那将不胜感激。
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 20
struct vara
{
int itemnumber[20];
char name[30];
int balance[20];
};
open_file(FILE *ange_filnamn, char filnamn[], struct vara varor[], int *antal_varor)
{
int mainmenu = 0;
while (mainmenu != 1 && mainmenu != 2)
{
printf("Do you want to open an existing file (1) or create a new one (2)?\n");
scanf("%d", &mainmenu);
//system("CLS");
if(mainmenu==1)
{
printf("Choose filename (ex. .txt).\n");
scanf("%s", filnamn);
ange_filnamn=fopen(filnamn, "r+");
while(!feof(ange_filnamn))
{
fread(&varor[*antal_varor], sizeof(struct vara), 1, ange_filnamn);
if(!feof(ange_filnamn))
{
*antal_varor=*antal_varor + 1;
}
}
printf("\nNumber of items: %d \n",*antal_varor);
fclose(ange_filnamn);
}
if(mainmenu==2)
{
printf("What name do you want for your new file?\n");
scanf("%s", filnamn);
ange_filnamn=fopen(filnamn, "w+");
printf("File is created!\n");
*antal_varor = 0;
fclose(ange_filnamn);
}
}
}
register_item(struct vara *varor, int *antal_varor)
{
printf("Item number:\n");
scanf("%d", varor[*antal_varor].itemnumber);
printf("Name:\n");
scanf("%s", varor[*antal_varor].name);
printf("Balance:\n");
scanf("%d", varor[*antal_varor].balance);
*antal_varor+=1;
}
print_item(struct vara varor[], int antal_varor)
{
int i;
for (i=0; i < antal_varor; i++)
{
printf("%d. Item number: %d Name: %s Balance: %d\n", i, varor[i].itemnumber, varor[i].name, varor[i].balance);
}
}
quit_program(char filnamn[], struct vara varor[], int *antal_varor)
{
FILE *fil;
//printf("%s", filnamn);
fil=fopen(filnamn, "w+");
fwrite(varor, sizeof(struct vara), *antal_varor, fil);
fclose(fil);
}
int main(void)
{
FILE *ange_filnamn;
struct vara varor[MAX];
int mainmenu, menu, antal_varor=0;
char filnamn[20], filen[30];
open_file(ange_filnamn,filnamn, varor, &antal_varor);
//Second menu
while(menu!=7)
{
printf("\n");
printf("1. Register new items to inventory.\n");
printf("2. Print all items from inventory.\n");
printf("3. Search for item.\n");
printf("4. Change inventory.\n");
printf("5. Sort inventory.\n");
printf("6. Deregister item from inventory.\n");
printf("7. Quit.\n");
scanf("%d", &menu);
if(menu==1)
{
register_item(varor, &antal_varor);
}
if (menu==2)
{
print_item(varor, antal_varor);
}
if (menu==3)
{
printf("test");
}
if (menu==4)
{
printf("test");
}
if (menu==5)
{
printf("test");
}
if(menu==6)
{
printf("test");
}
if (menu==7)
{
quit_program(filnamn, varor, &antal_varor);
}
}
}
答案 0 :(得分:2)
你有一系列结构。该数组包含antal_varor
个结构,每个结构包含成员(元素)itemnumber
,name
和balance
。
在我们开始之前,请注意一点:我认为您的结构定义有一些错误。根据您使用它的方式,我认为您想要
struct vara
{
int itemnumber;
char name[30];
int balance;
};
但你的问题是关于编写文件。当你打电话
fwrite(varor, sizeof(struct vara), *antal_varor, fil);
你正在写出整个数组,一次性地在&#34;二进制&#34;中,这就是你无法读取的原因。如果你想用更易读的形式写出来,你可以做这样的事情。在这里,我有一个关于数组元素的显式循环,每次循环,我打印出该元素的所有成员:
int i;
for(i = 0; i < *antal_varor; i++ {
fprintf(fil, "varor %d:\n", i);
fprintf(fil, " itemnumber: %d\n", varor[i].itemnumber);
fprintf(fil, " name: %s\n", varor[i].name);
fprintf(fil, " balance: %d\n", varor[i].balance);
}
所以,首先尝试一下。您应该会发现输出文件非常易读。
现在,问题在于,因为您以这种更好,更易读的格式编写了文件,您的代码将数据读回来,以前用过
fread(&varor[*antal_varor], sizeof(struct vara), 1, ange_filnamn);
不再适用了。但是这里有一些你可以用来读回新格式文件的代码。这段代码用fgets
逐行读取文件,弄清楚每行是什么,然后逐个插入数据项<{1}}数组重建它。
varor
我还没有对此进行测试,所以可能会有一些小错误,但它应该会给你这个想法。
(还有更好的方式来编写这类东西,但它们更复杂或需要更多的基础设施,所以我坚持一些非常简单和易懂的东西,尽管它已经过去了。不太健壮。)
答案 1 :(得分:0)
你问题的评论者是对的。
- printf显示的内容(并使用fprintf写入文件)是数字的ASCII表示
- 存储在存储器中(并用fwrite写入)是实际的“二进制”值
在C中,无论存储的值如何,int变量始终占用内存中相同的字节数。这就是你的sizeof()一致工作的原因。读写能够始终如一。
(请注意,并非所有C实现都使用相同大小的int。在我现在使用的x86 Linux中它是4个字节)。
显示ASCII表示时,所需的ASCII数字字符数取决于值。因此,如果读取的值已经以这种方式存储,则必须“解析”文本并从读取的数字中构建整数值,并且通常将是可变数字的数字。 (这就是scanf所做的。)因此,读取和解析ASCII可能被认为比读取存储为二进制int的值更复杂,该值总是相同的大小。
重要提示:如果您要将文件读取为二进制文件,则应使用“b”属性将其打开,如下所示:
ange_filnamn=fopen(filnamn, "r+b");
相似,打开二进制写:
fil=fopen(filnamn, "w+b");