操作系统实践(二)

  本节课的主要内容是:文件读写。在C语言中,我们可以使用fopen,fclose等函数进行文件操作。但下放到操作系统层次,就是一些文件的系统调用了。本节的主要内容也就是介绍下与文件相关的一些系统调用。
  我发现自己写的,远没有老师提供的资料全面。所以在这里,我就直接用图片说明内容啦~

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  以上就是本节的主要理论学习内容,下面还有三个作业进行巩固,我就把自己的答案附在上面,可能不是很简洁,但我后面会慢慢的进行修改完善滴~

一、练习一:

在这里插入图片描述

#include<stdio.h>
int main(int argc, char *argv[]) {
    
    
	// argc的参数计算是从头开始的,所以使用./a.out也算一个,真正的参数是从索引1开始
	for (int i=1; i<argc; i++) {
    
    
	// argv是指针数组,使用的时候要注意。因为这里面测试的样例是字符,所以用%s和%c都可以
	//但是puts不可以,puts输出的只能是常量字符串
	printf("%s ", argv[i];
	printf("%c ", *(argv[i]));
	// puts(argv)
	}
	printf("\n");
}

  写这个的时候,遇到这样一个直接的问题:不定参数如何输入?原来在main函数中,它的参数列表就可以作为它的不定输入。设定argc和argv。其中argc代表输入参数个数,argv代表输入参数内容。更为详细的内容的可以参考:https://www.cnblogs.com/x_wukong/p/5326557.html

  还有就是,输出的时候会出现一种这样的情况:输出的最后总是有个%,这是怎么回事呢?其实这个就是Linux下一个习惯,提示输出到了最后。如果不想要的话,可以在最后增加一个换行符(这个问题困扰了我很久,感谢https://segmentfault.com/q/1010000004687388)

二、练习二:

在这里插入图片描述
  思路:因为文件内内容长度的不确定性,不想数据库那样有严格的结构体。这里利用read读文件如果到文件底会返回0做判断,同时read返回值就是文件读出来的字节count改变偏移量offset。以offset作为lseek偏移数,不断累加,进行读取。源码如下:

#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

// 输出错误提示信息
void panic(char *message) {
    
    
	perror(message);
	exit(EXIT_FAILURE);
}

int fd;

struct record {
    
    
	char content[100];
};

// 打开文件,使用系统调用open
void db_open(char *path) {
    
    
	mode_t mode = 0777;
	fd = open(path, O_RDWR | O_APPEND | O_CREAT, mode);
	if (fd < 0)
		panic("open");
}

// 关闭文件,使用系统调用close
void db_close() {
    
    
	close(fd);
}

// 文件内容输出,使用系统调用lseek,read
void db_dump() {
    
    
	int offset = 0;
	while (1) {
    
    
		lseek(fd, offset, SEEK_SET);
		struct record record;
		int count = read(fd, &record, 100);
		if (count == 0)
			break;
		else {
    
    
			offset += count;
			printf("%s\n", record.content);
		}
	}
}

int main(int argc, char *argv[]) {
    
    
	db_open(argv[1]);
	db_dump();
	db_close();
	return 0;
}

  效果图如下:
在这里插入图片描述

三、练习三:

在这里插入图片描述
  思路:读取文件部分与问题二一致,同时增加写文件部分,文件名为第二个传入的参数值。源代码如下(代码是有问题的,问题在下面说):

#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

// 输出错误信息
void panic(char *message) {
    
    
	perror(message);
	exit(EXIT_FAILURE);
}

int fd_source;
int fd_target;

struct record {
    
    
	char content[100];
};

// 打开源文件
void db_open_source(char *path) {
    
    
	mode_t mode = 0777;
	fd_source = open(path, O_RDWR | O_APPEND | O_CREAT, mode);
	if (fd_source < 0)
		panic("open_source");
}

// 生成目标文件
void db_open_target(char *path) {
    
    
	mode_t mode = 0777;
	fd_target = open(path, O_RDWR | O_APPEND | O_CREAT, mode);
	if (fd_target < 0)
		panic("open_target");
}

void db_close() {
    
    
	close(fd_source);
	close(fd_target);
}

// 目标文件内容填入(尾部填充)
void db_append(char *content) {
    
    
	struct record record;
	strcpy(record.content, content);
	int count = write(fd_target, &record, 100);
	if (count < 0)
		panic("write");
}
// 从源文件读,向目标文件写
void db_dump() {
    
    
	int offset = 0;
	int num = 0;
	while (1) {
    
    
		lseek(fd_source, offset, SEEK_SET);
		struct record record;
		int count = read(fd_source, &record, sizeof(record));
		if (count == 0)
			break;
		else {
    
    
			offset += count;
			db_append(record.content);
			printf("%s", record.content);
		}
	}
	printf("\n");
}

int main(int argc, char *argv[]) {
    
    
	db_open_source(argv[1]);
	db_open_target(argv[2]);
	db_dump();
	db_close();
	return 0;
}

  问题:这个代码在执行的时候,在终端输出的是没有问题的。但写入到目标文件中的内容,最终会出现一行乱码(长度恰好是100),如下图:
在这里插入图片描述
  有问题是好事,等我解决了,再补充说明吧~

  呼,第二次实验结束,继续加油!

因作者水平有限,如有错误之处,请在下方评论区指出,谢谢各位!

Guess you like

Origin blog.csdn.net/gls_nuaa/article/details/115586876