首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在结构中使用指针读取文件

在结构中使用指针读取文件
EN

Stack Overflow用户
提问于 2013-12-31 01:46:22
回答 3查看 1.5K关注 0票数 0

我尝试使用结构中的指针对文件进行写入和读取。但是当我从文件中读取时,我看到了一些无用的值。我在Linux上使用的是GCC 4.7.2。我需要一些帮助。

阅读:

代码语言:javascript
运行
复制
//read from a file

#include<stdio.h>

typedef struct 
{
    char* name;
    char* phone;
}LISTING;

int main(void)
{
    LISTING phoneList[14];  
    FILE * fp = NULL;

    fp = fopen("/media/Study/PhoneDirectory.dat","rb"); 

    if(fp == NULL)
        printf("Error opening file!!!");    

    fseek(fp,0,SEEK_SET);

    if(fread(&phoneList[1],sizeof(LISTING),1,fp)==1)
        printf("%s %s",phoneList[1].name,phoneList[1].phone);

    fclose(fp);

    return 0;
}

并写道:

代码语言:javascript
运行
复制
//Write to file

#include<stdio.h>

typedef struct 
{
    char* name;
    char* phone;
}LISTING;

int main(void)
{
    LISTING phoneList[2];   
    FILE * fp = NULL;

    fp = fopen("/media/Study/PhoneDirectory.dat","wb");

    phoneList[1].name = "Santosh";
    phoneList[1].phone = "9657681798";

    if(fwrite(&phoneList[1],sizeof(LISTING),1,fp)==1)
        printf("inserted");

    fclose(fp);

    return 0;
}
EN

回答 3

Stack Overflow用户

发布于 2013-12-31 03:02:21

指针只有在它们产生的应用程序进程中才有意义。如果你将它们写到一个文件中,就像你在这里做的那样,你读回的值将是没有意义的--它们很可能指向未初始化的内存,或者指向正在被完全用于其他事情的内存。

您需要想出另一种将此数据写入文件的方法。

票数 1
EN

Stack Overflow用户

发布于 2013-12-31 08:08:31

您遇到的问题是char*和char[]之间的模棱两可。当然,您可以为char*赋值字符串文字,但您需要了解清单结构的内容,以及如何将数据序列化和反序列化到文件中。

保存来自一个进程的指针并将其读入另一个进程是没有意义的,因此您可能希望保存内容(指针所指向的内容)。您希望将两个值(name、phone)存储到文件中。由于您可能希望存储文字名称和文字电话,让我们考虑一下该文件可能是什么样子:

代码语言:javascript
运行
复制
roast duck|212-333-4444
peking duck|411-511-61111
duck soup|314-222-3333
free duck|800-111-2222
...

您需要函数来序列化和反序列化数据。由于清单类型是指针,因此需要在读取这些值时为它们分配适当的空间,并且需要函数(方法)从文件读取序列化数据并将序列化数据写入文件。

读取(您将需要分配足够的空间),

代码语言:javascript
运行
复制
int
listing_read(FILE*fp, LISTING* listing)
{
    char name_buffer[100];
    char phone_buffer[100];

    if(!fp) return(-1);
    if(!listing) return(-2);

    int res = fscanf(fp,"%s|%s\n",name_buffer,phone_buffer);
    if( !res ) {
        //handle error here
    }
    //careful here, you cannot free if you didn't malloc/strdup
    if(listing->name) free(listing->name);
    if(listing->phone) free(listing->phone);

    listing->name = strdup(name_buffer);
    listing->phone = strdup(phone_buffer);
    return(0);
}

编写(您需要提供适当的格式),

代码语言:javascript
运行
复制
int
listing_write(FILE*fp, LISTING* listing)
{
    if(!fp) return(-1);
    if(!listing) return(-2);

    fprintf(fp,"%s|%s\n",listing->name,listing->phone);
    return(0);
}

以下是修改代码所需方法,

代码语言:javascript
运行
复制
//read from a file
#include<stdio.h>

typedef struct 
{
char* name;
char* phone;
}LISTING;

int main(void)
{
    LISTING phoneList[14];  
    FILE* fp = NULL;
    if( !(fp = fopen("/media/Study/PhoneDirectory.dat","rb")) ) {
        printf("Error opening file!!!");
        exit(1);
    }

    fseek(fp,0,SEEK_SET);
    if( listing_read(fp,&phoneList[0]) >= 0 ) {
        printf("%s %s",phoneList[0].name,phoneList[0].phone);
    }
    fclose(fp);

    return 0;
}

这是如何写文件的变化,

代码语言:javascript
运行
复制
//Write to file
#include<stdio.h>

typedef struct 
{
char* name;
char* phone;
}LISTING;

int main(void)
{
    LISTING phoneList[14];   
    FILE* fp = NULL;

    if( !(fp = fopen("/media/Study/PhoneDirectory.dat","wb")) ) {
        printf("error, cannot write file\n");
        exit(1);
    }

    phoneList[0].name = "Santosh";
    phoneList[0].phone = "9657681798";

    if( listing_write(fp,&phoneList[0])>=0) {
        printf("inserted");
    }
    fclose(fp);

    return 0;
}

请注意,在编写程序时,需要将字符串"Santosh“和"9657681798”分配给列表成员的姓名和电话。虽然这样做是合法的,但您需要更好地理解C语言在这里的作用。C获取这些C字符串常量的地址,并将这些地址分配给honelist1.name和honelist1.phone成员指针。

考虑一下,如果你完成了这项任务,

代码语言:javascript
运行
复制
    phoneList[0].name = "Santosh";
    phoneList[0].phone = "9657681798";

您已将指向常量字符串的指针分配给结构成员。

但如果要分配空间(例如,使用strdup()),

代码语言:javascript
运行
复制
    phoneList[0].name = strdup("Santosh");
    phoneList[0].phone = strdup("9657681798");

您已经为字符串分配了空间,为这些成员元素分配了独立的位置。这更有可能是你想要做的。

请注意,我使用了phonelist,因为C具有从零开始的数组。

票数 0
EN

Stack Overflow用户

发布于 2013-12-31 02:58:27

代码语言:javascript
运行
复制
printf("%s %s",phoneList[1].name,phoneList[1].phone);

上面的语句调用了未定义的行为。

由于结构对象phoneList[1]的指针namephone没有初始化,因此取消对它们的引用将调用UB。在你的例子中,他们抛出了垃圾值,但这也可能导致崩溃。

为了适合读取文件内容并将其存储在结构对象中的情况,使用getline函数按行读取它们(假设所有细节都是按行存储的),然后为char指针动态分配内存,然后将它们赋给读取值。但是,这种方法导致了大量的内存管理,这很容易出错。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20845119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档