0

我被分配管理一家音乐商店。在数据库(保存为 .dat 文件)中,我们有一个艺术家姓名和专辑。

我在写入和读取文件时遇到问题。第一件事是,即使我不写任何东西,只需创建文件,然后在记事本中打开文件,我就会看到乱码和中文或日文字母。即使我写到失败,或者使用 Visual Studio 从它读取,这似乎并没有改变。这是我的代码:

我打开文件:

p=fopen("database.dat","w+");

添加项目功能:

void add_item(char* artist,char* record,FILE* p) //adds an item with artist and record to store
{
    item node;
    int item_size=sizeof(item);
    rewind(p);
    strcpy(node.artist,artist);
    strcpy(node.record,record);
    fwrite(&node,item_size,1,p);
    printf("Data added\n");
}

item 是用于在商店中定义单个项目的结构。它有 2 个字段,字符串艺术家和字符串记录。

typedef struct item
{
    char artist[100],record[100];
}item;

这是为了阅读:

void print_file(FILE* p) //print the entire file
{
    int size=sizeof(item);
    item node;
    rewind(p);
    while(!feof(p))
    {
        fread(&node,size,1,p);
        printf("%s - %s\n",node.artist,node.record);
    }
}

如果我使用 print_file,我会看到乱码,如果我真的用记事本打开文件,我会看到日语。

帮助!:D

编辑:刚刚发现了一些东西。如果我添加一个项目,然后读取文件,我将读取该项目。但是,如果我再次运行该程序并尝试立即读取文件,我会看到乱码。

4

2 回答 2

2

问题在于“w+”,它会将现有文件截断为零长度并打开它以进行读写。当您第二次运行程序时,会发生这种情况,并且您的读取(写入之前)返回乱码。更多关于 fopen 的信息在这里

于 2013-05-24T01:19:08.850 回答
-1

我根据您的症状猜测字符串被定义为char*而不是char[],这将是您的问题。文件上的字符串 IO 不能那样工作。请记住,字符串实际上是 type char*,即指向一个或多个 8 位整数的指针。当您将字符串写入文件时,您实际上是在写入地址本身的值,而不是它指向的字符。

您应该使用该fprintf()函数将字符串写入文件:
http
: //www.cplusplus.com/reference/cstdio/fprintf/ 然后fscanf()读取它们:
http ://www.cplusplus.com/reference/cstdio/fscanf/

一般来说,如果你打算使用结构体作为文件格式,你不能在结构体中放置指针。您可以放置char[]​​值,因为它们的处理方式与指针不同,但这需要对字符串大小进行硬限制。这就是为什么有些人不鼓励将结构作为文件格式的原因之一——最好一次读取和写入一个值,适当地处理字符串等等。

当您立即读回文件时(在退出程序之前)它起作用的原因是因为该指针地址对该字符串仍然有效。但是字符串本身从未被写入文件。

于 2013-05-24T00:21:47.997 回答