将整数,结构体,结构体数组,链表写到文件

在之前的学习中,忘文件中写的内容都是字符串或字符,本节学习如何写入其他各种类型的数据。

回看write和read函数的形式:

ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);

其中,第二个参数都是一个无类型的指针,只不过之前一直将这里定义为一个字符串,其实,这个指针可以指向各种形式数据的地址。 

写入一个整数

demo7.c:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main()
{
	int fd; // file description
	int data = 100;
	int data2 = 0;

	fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);

	printf("file description = %d, open successfully!\n",fd);

	write(fd, &data, sizeof(int));

	lseek(fd,0,SEEK_SET);

	read(fd, &data2, sizeof(int));
        printf("context:%d\n",data2);

	close(fd); //close after writing 

	return 0;
}

运行代码:

注意,如果此时打开file1:(此时需要使用vi打开)

发现是乱码,但是这并不影响程序运行时的读取和写入

写入一个结构体

demo7.c:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>


struct Test
{
	int i;
	char c;
};

int main()
{
	int fd; // file description
	struct Test data = {30,'k'};
	struct Test data2;

	fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);

	printf("file description = %d, open successfully!\n",fd);

	write(fd, &data, sizeof(struct Test));

	lseek(fd,0,SEEK_SET);

	read(fd, &data2, sizeof(struct Test));
        printf("data.i:%d,data.c=%c\n",data2.i,data2.c);

	close(fd); //close after writing 

	return 0;
}

运行代码:

 

 

 写入一个结构体数组

demo7.c:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>


struct Test
{
	int i;
	char c;
};

int main()
{
	int fd; // file description
	struct Test data[2] = {{30,'k'},{100,'p'}};
	struct Test data2[2];

	fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);

	printf("file description = %d, open successfully!\n",fd);

	write(fd, &data, sizeof(struct Test)*2);

	lseek(fd,0,SEEK_SET);

	read(fd, &data2, sizeof(struct Test)*2);
        printf("data[0].i:%d,data[0].c=%c\n",data2[0].i,data2[0].c);
	printf("data[1].i:%d,data[1].c=%c\n",data2[1].i,data2[1].c);

	close(fd); //close after writing 

	return 0;
}

 运行代码:

写入一个链表 

demo7.c:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

struct Test
{
	int data;
	struct Test *next;
};


int main()
{
	int fd; // file description
	struct Test head = {20,NULL};
	struct Test node1 = {30,NULL};
	struct Test node2 = {40,NULL};
	head.next = &node1;
	node1.next = &node2;


	fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);

	printf("file description = %d, open successfully!\n",fd);


	write(fd, &head, sizeof(struct Test));
	write(fd, &node1, sizeof(struct Test));
	write(fd, &node2, sizeof(struct Test));


	lseek(fd,0,SEEK_SET);

	struct Test node_read_1 = {0,NULL};
	struct Test node_read_2 = {0,NULL};
	struct Test node_read_3 = {0,NULL};
 	read(fd, &node_read_1, sizeof(struct Test)); 
	read(fd, &node_read_2, sizeof(struct Test));
	read(fd, &node_read_3, sizeof(struct Test));
	
	printf("no.1=%d\n",node_read_1.data);
	printf("no.2=%d\n",node_read_2.data);
	printf("no.3=%d\n",node_read_3.data);


	close(fd);

	return 0;
}

运行代码:

 

但是以上的代码有点笨,且容错性太低,首先读取和写入应该封装成函数,并且我认为通常在读取链表的时候,不一定知道链表有多少元素,所以应该一边用尾插法动态创建链表一边读取

改进代码demo8.c:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

struct Test
{
	int data;
	struct Test *next;
};

struct Test *insertBehind(struct Test *head, struct Test *new)
{
	struct Test *p = head;
	if(p == NULL){
		head = new;
		return head;
	}

	while(p->next != NULL){
		p = p->next;
	} //将p先移动到链表的尾部
	p->next = new;

	return head;
}

void writeLink2File(int fd,struct Test *p){

	while(p != NULL){
		write(fd, p, sizeof(struct Test));
		p = p->next;
	}
}

void readLinkFromFile(int fd,struct Test *head){
	struct Test *new;
	int size = lseek(fd,0,SEEK_END); //先计算文件大小
	lseek(fd,0,SEEK_SET); //然后不要忘记把光标移到文件头

	while(1){
		new = (struct Test *)malloc(sizeof(struct Test));
		read(fd, new, sizeof(struct Test));
		printf("link data:%d\n",new->data);
		if(lseek(fd,0,SEEK_CUR) == size){ //每次读取一个数据之后,动态创建下一个链表节点之前,都要判断“当前光标是否已经在文件尾”,如果是,说明读取已经完成
			printf("read finish\n");
			break;
		}
		head = insertBehind(head,new);
	}

}



int main()
{
	int fd; // file description
	struct Test head = {20,NULL};
	struct Test node1 = {30,NULL};
	struct Test node2 = {40,NULL};
	head.next = &node1;
	node1.next = &node2;

	fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);

	printf("file description = %d, open successfully!\n",fd);

	writeLink2File(fd,&head);

	struct Test *head_recv = NULL; //准备创建一个新的链表用于接收
 	readLinkFromFile(fd,head_recv);

	close(fd);

	return 0;
}

改进代码运行:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 不使用结构体、指针链表结构体数组,可以使用简单的数组来存储学生信息和成绩,下面是一个示例代码: ``` #include <stdio.h> #define MAX_STUDENTS 100 int main() { int num_students, i; char names[MAX_STUDENTS][50]; int scores[MAX_STUDENTS]; printf("Enter the number of students: "); scanf("%d", &num_students); for (i = 0; i < num_students; i++) { printf("Enter the name of student %d: ", i+1); scanf("%s", names[i]); printf("Enter the score of student %d: ", i+1); scanf("%d", &scores[i]); } printf("\nStudent Scores:\n"); for (i = 0; i < num_students; i++) { printf("%s: %d\n", names[i], scores[i]); } return 0; } ``` 该示例代码中,使用二维字符数组 `names` 存储学生姓名,一维整数数组 `scores` 存储学生成绩。在输入学生信息时,依次输入学生姓名和成绩,分别存储到相应的数组中。最后输出学生信息时,遍历数组,依次输出姓名和成绩即可。 ### 回答2: 在不使用结构体、指针链表结构体数组的情况下,可以使用简单的数组和函数来实现C语言成绩管理系统。 一种可能的实现方式是,可以定义两个一维数组,一个用于存储学生的姓名,一个用于存储学生成绩。数组的大小可以根据实际情况进行调整。 然后,可以编写一些函数来实现不同的功能,比如添加学生信息、删除学生信息、查询学生成绩等。 例如,假设最多可以存储100个学生的信息,可以定义以下数组: ``` char names[100][50]; // 用于存储学生姓名 float scores[100]; // 用于存储学生成绩 int count = 0; // 记录当前已存储的学生数量 ``` 下面是一些可能用到的功能函数的伪代码: 1. 添加学生信息: ```C void addStudent(char name[], float score) { if (count < 100) { // 将姓名和成绩分别存储到对应的数组中 strcpy(names[count], name); scores[count] = score; count++; printf("添加成功!\n"); } else { printf("无法添加,学生数量已达到上限!\n"); } } ``` 2. 删除学生信息: ```C void deleteStudent(char name[]) { int index = -1; for (int i = 0; i < count; i++) { if (strcmp(names[i], name) == 0) { index = i; break; } } if (index >= 0) { for (int i = index; i < count - 1; i++) { strcpy(names[i], names[i + 1]); scores[i] = scores[i + 1]; } count--; printf("删除成功!\n"); } else { printf("未找到该学生信息!\n"); } } ``` 3. 查询学生成绩: ```C void queryScore(char name[]) { int index = -1; for (int i = 0; i < count; i++) { if (strcmp(names[i], name) == 0) { index = i; break; } } if (index >= 0) { printf("%s的成绩是%.2f\n", names[index], scores[index]); } else { printf("未找到该学生信息!\n"); } } ``` 这只是一个简单的示例,实际上还可以根据需求添加其他功能函数。需要注意的是,由于没有使用结构体和指针链表,需要手动维护数组的顺序和数量。 ### 回答3: 如果不使用结构体、指针链表结构体数组,我们可以考虑使用基本的变量和数组来实现C语言成绩管理系统。 首先,我们可以使用一个二维数组来保存学生的成绩信息。假设有n个学生和m门课程,那么我们可以定义一个n行m列的二维数组来存储成绩。例如,用scores[n][m]来表示。 然后,我们可以使用一个一维数组来保存每个学生的姓名。例如,用names[n]来表示。 接下来,我们可以通过循环来输入学生的成绩和姓名,将它们分别保存到相应的数组中。我们可以使用for循环来遍历每个学生和每门课程,然后使用scanf函数来输入成绩。同样地,我们可以使用for循环来输入学生的姓名。 在输入完成绩和姓名后,我们可以进行一些简单的操作,比如计算每个学生的总分和平均分,以及每门课程的平均分。 最后,我们可以使用循环来输出学生的成绩和相关统计信息,比如总分和平均分。同样地,我们可以使用循环来输出每门课程的平均分。 需要注意的是,不使用结构体、指针链表结构体数组可能会增加代码的复杂度和可读性。这种方法适用于简单的学生成绩管理系统,但对于更复杂的情况,使用结构体、指针链表结构体数组会更加方便和灵活。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值