请问C语言如何把链表存入文件,从文件读取到链表

Zip Zou 2014-12-18 06:29:06
Consumer* read_list()
{
FILE *fp;
if ((fp = fopen("CONSUMER.dat", "rb")) == NULL)
{
printf("无法读取 CONSUMER.dat\n");
return NULL;
}
int sign;
Consumer *s,*p,*head;

head= (Consumer*)malloc(SIZE_C);
if (head == NULL)
{
printf("读取失败!内存空间申请不足!\n");
return NULL;
}
fseek(fp, 0, SEEK_END);
if (ftell(fp) == 0)
{
return NULL;
}
p = head;
p->next = NULL;
while (feof(fp))
{
s = (Consumer*)malloc(SIZE_C);
fread(s, SIZE_C, 1, fp);
p->next = s;
p = s;
p->next = NULL;
}
fclose(fp);
return head;
}//读取文件到链表
int save_consumer(Consumer *p)
{
FILE *fp;
Consumer *head;
head = p;//p为已经构建好的链表
if ((fp = fopen("CONSUMER.dat", "ab+")) == NULL)
{
printf("无法打开 CONSUMER.dat!\n");
return -1;
}
while (p != NULL)
{

fwrite(p, SIZE_C, 1, fp);
p = p->next;
}
fclose(fp);
return 1;
}//储存链表到文件
...全文
23836 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
请问一下SIZE_C是什么意思呢?
  • 打赏
  • 举报
回复
引用 10 楼 q3733353520 的回复:
[quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 q3733353520 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
linux 咋看呢[/quote]
#include <stdio.h>
#include <string.h>
FILE *f;
char buffer[4096];
int r,a;
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
int main(int argc,char **argv) {
    if (argc<2) {
        fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);
        return 2;
    }
    f=fopen(argv[1],"rb");
    if (NULL==f) {
        fprintf(stderr,"Can not open file [%s]!\n",argv[1]);
        return 1;
    }
    a=0;
    while (1) {
        r=fread(buffer,1,4096,f);
        HexDump(buffer,r,a);
        a+=r;
        if (r<4096) break;
    }
    fclose(f);
    return 0;
}
[/quote] 哦, 谢谢赵老师[/quote] 文件的其实 od 可以,内存还是用gdb调试好点
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
[quote=引用 7 楼 q3733353520 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
linux 咋看呢[/quote]
#include <stdio.h>
#include <string.h>
FILE *f;
char buffer[4096];
int r,a;
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
int main(int argc,char **argv) {
    if (argc<2) {
        fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);
        return 2;
    }
    f=fopen(argv[1],"rb");
    if (NULL==f) {
        fprintf(stderr,"Can not open file [%s]!\n",argv[1]);
        return 1;
    }
    a=0;
    while (1) {
        r=fread(buffer,1,4096,f);
        HexDump(buffer,r,a);
        a+=r;
        if (r<4096) break;
    }
    fclose(f);
    return 0;
}
[/quote] 哦, 谢谢赵老师
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
linux 咋看呢
赵4老师 2014-12-20
  • 打赏
  • 举报
回复
引用 7 楼 q3733353520 的回复:
[quote=引用 6 楼 zhao4zhong1 的回复:] 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
linux 咋看呢[/quote]
#include <stdio.h>
#include <string.h>
FILE *f;
char buffer[4096];
int r,a;
void HexDump(char *buf,int len,int addr) {
    int i,j,k;
    char binstr[80];

    for (i=0;i<len;i++) {
        if (0==(i%16)) {
            sprintf(binstr,"%08x -",i+addr);
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        } else if (15==(i%16)) {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
            sprintf(binstr,"%s  ",binstr);
            for (j=i-15;j<=i;j++) {
                sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
            }
            printf("%s\n",binstr);
        } else {
            sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
        }
    }
    if (0!=(i%16)) {
        k=16-(i%16);
        for (j=0;j<k;j++) {
            sprintf(binstr,"%s   ",binstr);
        }
        sprintf(binstr,"%s  ",binstr);
        k=16-k;
        for (j=i-k;j<i;j++) {
            sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
        }
        printf("%s\n",binstr);
    }
}
int main(int argc,char **argv) {
    if (argc<2) {
        fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);
        return 2;
    }
    f=fopen(argv[1],"rb");
    if (NULL==f) {
        fprintf(stderr,"Can not open file [%s]!\n",argv[1]);
        return 1;
    }
    a=0;
    while (1) {
        r=fread(buffer,1,4096,f);
        HexDump(buffer,r,a);
        a+=r;
        if (r<4096) break;
    }
    fclose(f);
    return 0;
}
w74839520 2014-12-20
  • 打赏
  • 举报
回复
好帖子。学习学习。
xionggch 2014-12-19
  • 打赏
  • 举报
回复

Consumer* read_list()
{
	FILE *fp;
	if ((fp = fopen("CONSUMER.dat", "rb")) == NULL)
	{
		printf("无法读取 CONSUMER.dat\n");
		return NULL;
	}
	int sign;
	Consumer *s,*p,*head;
	
	head= (Consumer*)malloc(SIZE_C);
	if (head == NULL)
	{
		printf("读取失败!内存空间申请不足!\n");
		return NULL;
	}
	fseek(fp, 0, SEEK_END);
	if (ftell(fp) == 0)
	{
		return NULL;
	}
	p = head;
	p->next = NULL;
	while (feof(fp))
	{
		s = (Consumer*)malloc(SIZE_C);
		//fread(s, SIZE_C, 1, fp);
                fread(s, sizeof(char), SIZE_C, fp);
		p->next = s;
		p = s;
		p->next = NULL;
	}
	fclose(fp);
	return head;
}//读取文件到链表
int save_consumer(Consumer *p)
{
	FILE *fp;
	Consumer *head;
	head = p;//p为已经构建好的链表
	//if ((fp = fopen("CONSUMER.dat", "ab+")) == NULL)
        if ((fp = fopen("CONSUMER.dat", "wb")) == NULL)
	{
		printf("无法打开 CONSUMER.dat!\n");
		return -1;
	}
	while (p != NULL)
	{
		//fwrite(p, SIZE_C, 1, fp);
                fwrite(p, sizeof(char), SIZE_C, fp);
		p = p->next;
	}
	fclose(fp);
	return 1;
}//储存链表到文件
Zip Zou 2014-12-19
  • 打赏
  • 举报
回复
3楼,你的分析是对的,就是feof函数的原因,所以我改成了fread的返回值去判断,在读文件时我再设置了文件指针的位置,用fseek,这样就可以实现了,我逐语句调试,发现feof做循环控制条件的话,循环执行3次,所以feof正如你分析的一样!
赵4老师 2014-12-19
  • 打赏
  • 举报
回复
推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
a138762698828 2014-12-18
  • 打赏
  • 举报
回复
while (!feof(fp)) { s = (Consumer*)malloc(SIZE_C); fread(s, sizeof(SIZE_C), 1, fp); p->next = s; p = s; p->next = NULL; } 试下能不能运行, while(!feof(fp))是循环来控制文件内容的读取, 例如当前读取的内容不是文件尾部,则feof(fp)为0,去非运算后为1,那么就继续循环执行! 如果执行到文件尾部,则feof(fp)为1,取非为0,循环借宿,读取文件结束。
「已注销」 2014-12-18
  • 打赏
  • 举报
回复
for reference only,我就只写文件到链表了,链表o大n文件用对应的fprintf就可以了
/*************************************************************************
    > File Name: test3.c
    > Author: jukay
    > Mail: hellojukay@163.com 
    > Created Time: 2014年12月18日 星期四 19时29分18秒
 ************************************************************************/

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

struct date
{
	char str[3];
	struct date *next;
};

//链表长度为len
struct date *create_link(int len)
{
	struct date *head;
	struct date *tmp;
	int i;
	head = malloc(sizeof(struct date));
	tmp = head;
	for(i = 1; i < len; ++i)
	{
		head ->next = malloc(sizeof(struct date));
		head = head ->next;
	}
	head ->next = NULL;
	return tmp;
}

//读文件到链表
void read_file_to_link(struct date *head,FILE *fp)
{
	if(head == NULL || fp == NULL)
	{
		fprintf(stderr,"null pointer");
		exit(EXIT_FAILURE);
	}
		do
		{
			fscanf(fp,"%3s",head ->str);
			head = head ->next;
		}while(head != NULL);
}

//显示链表中的内容
void print_link(struct date *head)
{
	if(head == NULL)
	{
		fprintf(stderr,"null pointer");
		exit(EXIT_FAILURE);
	}
	do
	{
		printf("%s",head ->str);
		head = head ->next;
	}while(head != NULL);
}

int main()
{
	FILE *fp;
	int len; //链表长度
	scanf("%d",&len);
	fp = fopen("a.txt","r");
	struct date *head;
	head = create_link(len);
	read_file_to_link(head,fp);
	print_link(head);

	exit(EXIT_SUCCESS);
}
Zip Zou 2014-12-18
  • 打赏
  • 举报
回复
有知道的吗?
1.基于数组的“学生信息管理系统” 实验内容: 编写并调试程序,实现学校各专业班级学生信息的管理。定义学生信息的结构体类型,包括:学号、姓名、专业、班级、3门成绩。N定义为符号常量,定义N名学生信息的结构体数组。 实验要求: main函数:以菜单形式将各项功能提供给用户,根据用户的选择,调用相应的函数。 功能: (1)定义函数Input:功能是可以从键盘输入任意个学生信息。 (2)定义函数Save:将输入的学生信息全部或者选择性的存入指定文件(如:输入5个学生信息,选择其中前3或者2个存入文件,或者全部存入文件)。 (3)定义函数Output:将某个学生信息格式化输出(学生信息文件读取,并且提供可选择的学号)。 (4)定义函数Fetch:文件中随机读取某个学生的信息。 (5)定义函数Del:删除指定学号学生信息,并保存到原文件中。 (6)定义函数:实现输出所有学生信息的功能(包括学生的平均分和总分)。 (7)定义函数Max:求所有学生某门课程的最高分,并将此学生的分数以及学生姓名输出(注意:当有多名相同最高分数时,可将所有学生姓名输出)。 (8)定义函数Sort_select:对某个专业的学生,按总平均成绩由低到高进行简单选择排序。 (9)定义函数Sort_buble:对某个专业中某个班级的学生,按总平均成绩由高到低进行起泡排序。 (10)定义函数Sort_insert:对某个专业中某个班级的学生,按某门课程成绩由低到高进行直接插入排序。 (11)定义函数Search:实现某专业中某班级的成绩综合查找(如智能专业1班,总分240分以上同学)。 (12) 定义函数printmenu: 打印菜单 退出 2.基于链表的“学生信息管理系统” 实验内容:编写并调试程序,实现学校各专业班级学生信息的管理。定义学生信息的链表结点类型,包括:学号、姓名、班级、专业、3门成绩。 实验要求: (1)main函数:以菜单形式将各项功能提供给用户,根据用户的选择,调用相应的函数。 (2)定义函数CreateList:按学号由小到大,建立有序的链表。逆序输入 n 个学生信息(调用n次input),学号大的先输入,建立带头结点的单链表。 (3)定义函数Output:以指向某个学生结点的指针为参数,将学生信息格式化输出。 (4)定义函数Save:将某个学生信息存入文件。 (5)定义函数Fetch:文件中随机读取某个学生的信息。 (6)定义函数Search_num:查找指定学号的学生,返回指向该学生结点的指针。 (7)定义函数InsertList:在函数中输入一个学生的信息,将该学生信息插入到链表中的相应位置,并保持此链表按学号的有序性。 (8)定义函数Delete_num:从链表中删除指定学号的学生。 (9)定义函数Search_major _subject_score:查找某个专业的、某门课程的成绩小于某个分数的学生,返回指向该学生结点的指针。 (10)定义函数Delete_ major _subject:从链表中删除某个专业的、某门课程的成绩小于某个分数的学生。

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧