【问题标题】:Segmentation fault while reading binary file in C在C中读取二进制文件时出现分段错误
【发布时间】:2014-05-02 03:54:31
【问题描述】:

我是 C 的初学者。 我想写和读一个二进制文件,到目前为止我已经做到了:

我可以将我的结构转换成二进制文件,并且可以读取。

问题一:我只能读取整数,不知何故字符串被打印为垃圾或随机字符。

问题二:如果我运行我的程序,我将一些条目添加到我的二进制文件中,然后我打印所有工作正常的条目(除了问题一),但是在我终止我的程序之后并再次运行,我在尝试读取文件时遇到了分段错误。

请帮帮我,我无法前进。

/* Our structure */
struct rec
{
    int max,cost;
    char *name;
};


struct rec addNewEntry()
{

    //init
    char name[256];
    int max;
    int cost;

    //input
    printf("Type name: \n");
    scanf("%s" , &name) ;

    printf("Type guests limit: \n");
    scanf("%d", &max);

    printf("Type price: \n");
    scanf("%d", &cost);

    //create record
    struct rec record;

    record.name = name;
    record.max = max;
    record.cost = cost;

    return record;

}

int main()
{

    FILE *ptr_myfile;


    //////////////////////////MENU////////////////////////////////

    int option=-1;


    while(option!=3)
    {

        printf("\n=== MENU === \n");
        printf("\n1. Print all entries");
        printf("\n2. Add new entry");
        printf("\n3. Exit");
        printf("\n");

        printf("\nType menu option:");

        scanf("%d", &option);


        if(option == 1)
        {
            printf("\n...Printing all entries\n");



            int f=open("stadionok.db",O_RDONLY); 
            if (f<0){ perror("Error at opening the file\n");exit(1);}

             struct rec my_record; 

             while (read(f,&my_record,sizeof(my_record))){ //use write for writing
                printf("name: %s  \n",my_record.name);
                printf("max: %d  \n",my_record.max);
                printf("cost: %d  \n",my_record.cost);
             } 


            close(f);


        }
        else if(option ==2)
        {

            printf("\n...Type a new entry\n");


            //OPEN AND CHECK
            ptr_myfile=fopen("stadionok.db","a");
            if (!ptr_myfile)
            {
                printf("Unable to open file!");
                return 1;
            }

            //TYPE A NEW ENTRY
            struct rec new_stad = addNewEntry();

            //WRITE TO FILE
            fwrite(&new_stad, sizeof(struct rec), 1, ptr_myfile);


            //CLOSE
            fclose(ptr_myfile);

            printf("Done.\n");
        }


    }   




    return 0;
}

编辑:

我按照您的建议进行了修改,现在我得到了: 错误:分配中的类型不兼容

在:

char name[256];


//input
printf("Type name: \n");
scanf("%s" , &name) ;


struct rec record;

record.name = name; //HERE

【问题讨论】:

  • name 已经是一个地址,所以不需要在它前面加上 &。你不能像这样将一个数组分配给另一个数组。使用 memcpy 或 strncpy 复制数组的内容。
  • 谢谢,效果很好。

标签: c


【解决方案1】:

您得到垃圾字符串的原因是您正在将一个字符 指针 写入文件。 做你想做的事情的简单方法是在你的结构中使用一个固定长度的 char 数组。像这样:

struct rec
{
    int max,cost;
    char name[1024];
};

这也是崩溃的原因。当您读取数据并尝试打印字符串时,printf() 可能会尝试从无效的内存块中读取,因为内存地址已更改。

如果你想将动态大小的字符串写入文件,它会变得有点复杂。
那么你不应该写结构本身,而是它的值和字符串的大小。
伪代码示例:

write(max);
write(cost);
write(strlen(name)); // strlen + 1 if you want to include \0
write(name);

max = readInt();
cost = readInt();
nameLen = readInt();
allocatememory(nameLen);
name = read_n_bytes(namelen);


对您的编辑: 如果 rec.name 仍然是指针 (char*),则必须为其分配指针,而不是数组。

rec.name = &name;

如果你的 rec.name 现在是一个固定大小的数组:

strncpy(rec.name, name, sizeof(rec.name)); // copy the string to rec.name
rec.name[strlen(name)] = '\0'; // add a binary 0 to the end of the string

注意:如果您正在读取超过 1 个结构(在循环中),则不应使用 char name[256];,因为每个 rec.name 都会指向名称,每次读取新值时都会覆盖该名称。对每个条目使用以下构造:

char* name; //define name as a pointer
name = malloc(256); // allocate a new memory block and assign a pointer to it to name
scanf("%s" , name); // No & needed because name is already a pointer
rec.name = name; // No & needed because name is already a pointer

【讨论】:

  • 查看我的编辑。我还纠正了我这边的一个错误。 printf 崩溃是因为它想访问一个不再有效的内存地址
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 2022-10-04
  • 2019-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多