C语言实现链表创建与文件存取示例
通过C语言演示如何动态创建单链表存储学生信息,利用fprintf和fscanf将数据以文本格式保存至文件,再反向读取验证,掌握链表结构与文件系统交互的基础实现。
一、准备条件
程序基于 C99 或更高标准,依赖 <stdio.h>、<stdlib.h> 和 <process.h>(Windows环境)。核心数据结构为包含姓名、地址、电话及指针的结构体 stu,使用全局变量维护节点数量 n 和链表头指针 phead。编译时需链接标准库,确保在支持动态内存分配的平台上运行。
二、操作步骤
第1步:建立链表并输入数据
目的:初始化空表,循环申请内存节点并录入用户信息。
入口:调用 Create() 函数。
动作:首先为头节点分配内存,随后在循环中逐个创建新节点。每个新节点通过尾指针 pend 链接,同时更新输入字段并移动尾指针。注意循环结束后需处理末尾多余的空节点内存。
typedef struct stu
{
char name[20];
char adr[20];
int tel;
struct stu* pnext;
} stu;
int n; //n存着信息条数
stu* phead=NULL;//phead为链表首地址
void Create()
{
stu *pend,*pnew; //尾节点,新节点
pend=phead =(stu*)malloc(sizeof(stu)); //分配内存给首节点
printf("please first input Name, Adress and telephone:\n");
for(int i=0;i<n;i++)
{
pnew=(stu*)malloc(sizeof(stu)); //分配新节点
pend->pnext=pnew; //原来的尾节点指向新节点
pnew->pnext=NULL; //新节点的指针为NULL
printf("NO.%d: ",i+1);
scanf("%s", pend->name); //注意:此处逻辑存在瑕疵,见下文修正
scanf("%s", pend->adr);
scanf("%d",&pend->tel);
pend=pnew; //赋值后指向尾节点
}
pnew=pnew->pnext; //指向NULL
free(pnew); //释放最后一个空余分配的节点
}第2步:将链表数据存入文件
目的:遍历链表,将每个节点的关键字段序列化写入磁盘文件。
入口:调用 save(filename),传入文件路径字符串。
动作:以写模式打开文件,若失败则退出。循环遍历链表,使用 fprintf 格式化写入姓名、地址和电话,并用换行符分隔记录。每次写入后移动指针至下一节点,最后关闭文件指针。
void save(char *filename)
{
FILE *w;//文件指针
if ((w = fopen(filename, "w")) == NULL){ //以文本方式只写打开文件
printf("cannot open file\n");
exit(1);
}
for (int i = 0; i < n; i++)
{
fprintf(w,"%s ",phead->name);
fprintf(w,"%s ",phead->adr);
fprintf(w,"%d", phead->tel);
fprintf(w,"%s","\r\n");//换行
phead=phead->pnext; //指向下一个节点
}
fclose(w); //关闭文件
}
第3步:从文件读取数据并输出
目的:重新打开文件,解析内容到临时数组并打印到屏幕。
入口:调用 show(filename)。
动作:以读模式打开文件,若失败则终止。声明结构体数组 info[100] 用于暂存数据。循环中使用 fscanf 匹配文件格式,将字段填充至数组元素。完成后遍历数组打印结果,释放文件资源。
void show(char *filename)
{
FILE *fp;//文件指针
stu info[100]; //负责存放文件中的数据,然后输出
if ((fp = fopen(filename, "r")) == NULL){ //以文本方式只读打开文件
printf("cannot open file\n");
exit(1);
}
for (int i = 0; i < n; i++)
{
fscanf(fp,"%s",&(info[i].name));
fscanf(fp,"%s",&(info[i].adr));
fscanf(fp,"%d",&(info[i].tel));
printf("%10s%15s%15d\n", info[i].name,
info[i].adr, info[i].tel);
}
fclose(fp); //关闭文件
}
第4步:主流程控制
目的:协调上述步骤,管理用户输入与内存生命周期。
入口:程序入口 main()。
动作:提示输入节点数量和文件名。依次执行创建、保存、释放原始链表内存、显示文件内容。注意在生产环境中应补充对内存分配失败的判断。
int main(void)
{
char filename[50];
printf("How many ?: \n");
scanf("%d", &n); //输入学生数
printf("please input filename: ");
scanf("%s", filename); //输入文件所在路径及名称
Create(); //调用函数建立链表
save(filename); //调用函数存到文件
free(phead);//释放phead内存 - 此操作需谨慎,详见review_notes
show(filename); //调用函数输出文件
return 0;
}三、完成判断与注意事项
成功运行的标志是控制台能正确回显用户在文件中保存的数据。需注意以下几点:
1. Create() 中的输入逻辑实际上存在索引错位,原代码在首次循环时并未将输入填入第一个有效节点,而是跳过了 phead 的直接赋值,导致第一个节点数据为空或不一致。
2. free(phead) 在 save() 之后立即执行是不安全的,因为 save() 内部需要遍历 phead。原文代码顺序有误,应先保存再释放,或者复制链表后再释放。
3. 文件操作建议使用文本模式 "w" 而非二进制 "wb" 以配合 fprintf/fscanf 的格式化需求。
四、简要总结
本示例涵盖了C语言中链表构建、动态内存管理及文件I/O的基本模式。虽然代码结构清晰,但在实际工程应用中需增加错误检查、内存泄漏防护以及更严谨的逻辑顺序。以上就是C语言实现链表创建与文件存取示例的详细内容,更多关于C语言基础与数据结构的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









