1

因此,出于某种原因,我需要通过将新文件附加到旧数据的末尾来创建一个外部文件 (.DAT) 来存储数据。

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

int main () {
    typedef struct {
        char *Name;
        int Index;
    } DataFile;

    static FILE *file;
    size_t result;
    DataFile *DataTable;

    file = fopen("database.DAT","ab");
    DataTable = (DataFile *) malloc (sizeof(DataFile));
    DataTable[0].Name = "somefile.txt";
    DataTable[0].Index = 7;
    printf("%s %d \n",DataTable[0].Name,DataTable[0].Index);
    result = fwrite(DataTable,sizeof(DataFile),1,file);
    fclose(file);
    free(DataTable);
    return 0;
}

运行上面的代码后,我检查数据是否存储正确。所以,我在下面做这个代码。

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

int main () {
    typedef struct {
        char *Name;
        int Index;
    } DataFile;

    static FILE *file;
    size_t result;
    long size;
    int i;
    DataFile *DataTable;

    file = fopen("database.DAT","rb");
    if (file == NULL) printf("Error1");

    // Determine the size of file
    fseek(file,0,SEEK_END);
    size = ftell(file);
    rewind(file);

    DataTable = (DataFile *) malloc ((size/sizeof(DataFile)) * sizeof(DataFile));
    if (DataTable == NULL) printf("Error2");

    result = fread(DataTable,sizeof(DataFile),size/sizeof(DataFile),file);
    fclose(file);

    for (i=0; i<result; i++) {
        printf("%s %d \n",DataTable[i].Name,DataTable[i].Index);
    }
    free(DataTable);
    return 0;
}

但是,它给出了输出

somefile.txt 7

从第一个代码块和

Error1 7

从第二个代码块。我注意到问题不是因为打开 .DAT 文件或为 DataTable 分配内存时失败。此外,从 .DAT 文件读取时,它适用于 int 类型(索引),但不适用于 char* 类型(名称)。我不知道如何解决这个 char*-type-reading 问题(以及 'error1' 的来源)。(甚至谷歌都没有给我答案。)

4

3 回答 3

2

您的结构DataFile存储一个指针和一个整数。当您将其写入文件时,您将一些程序特定的指针写入一个字符串和一个整数。

从它读取时,您只需用指针和整数重新填充结构,这意味着这DataFile.Name将是指向可能未初始化的内存段的指针。但是由于您创建了指向第一个硬编码字符串"filename.txt"Error1)

您真正想要做的是在文件中写入真正的字符串。

一个简单的解决方案,如果你想保持孔写入结构的事情是创建一个数组而不是一个指针

typedef struct {
        char Name[512];
        int Index;
    } DataFile;

然后初始化你的数据

strncpy(DataTable[0].Name, "somefile.txt", sizeof(DataTable[0].Name) - 1); // just to make sure you dont overflow your array size
DataTable[0].Name[sizeof(DataTable[0].Name) - 1] = '\0';

并以您的方式重新审核您的数据。

于 2012-11-15T08:01:46.907 回答
1

Achar*只是一个指针,即包含字符串的字符数组的地址。您不会将字符串本身写入文件。读取文件后,由于相同的字符串不再位于相同地址的内存中,应用程序将失败。

您还必须想出一种方法来将字符串本身保存到文件中。可能是先写他们的长度,然后写他们的内容。读取时,您可以使用长度信息动态分配内存,然后读入该内存。

于 2012-11-15T08:00:57.080 回答
0

在您的编写代码中,您没有为char *Name. 当您执行DataTable[0].Name = "somefile.txt"指令时,您实际上并没有将 复制"somefile.txt"到 指向的内存中Name,它实际上是分配一个Name指向常量字符串的值(此外,由于字符串是右值,它会变成悬空指针,即没有内存要通过)。您的文件读取代码也是如此。你需要:

  1. 为您的Name.
  2. 使用或类似方法将字符串复制memcpy到分配的存储中。
于 2012-11-15T08:00:42.360 回答