20211325 2023-2024-1 《信息安全系统设计与实现(上)》第二周学习笔记

发布时间 2023-09-17 16:13:13作者: STERNSTUN

 

一、任务要求

自学教材第九章,提交学习笔记(10分)
本章是复习C语言中的文件操作内容,结构化从文本文件操作,二进制文件操作两个大内容考虑,以前可能只关注文本文件的操作,我们以后更多的是操作二进制文件。
文本文件中考虑字符读写,行读写,任意位置读写等
文件操作都有什么?
二进制文件和文本文件如何转换?
数据结构如何读写?
...

,评分标准如下

1. 知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容 (4分)

“我在学***X知识点,请你以苏格拉底的方式对我进行提问,一次一个问题”

核心是要求GPT:“请你以苏格拉底的方式对我进行提问”

然后GPT就会给你提问,如果不知道问题的答案,可以反问AI:“你的理解(回答)是什么?”

如果你觉得差不多了,可以先问问GPT:“针对我XXX知识点,我理解了吗?”

GPT会给出它的判断,如果你也觉得自己想清楚了,可以最后问GPT:“我的回答结束了,请对我的回答进行评价总结”,让它帮你总结一下。


2. 问题与解决思路,遇到问题最先使用chatgpt等AI工具解决,并提供过程截图(3分)
3.   实践过程截图,代码链接(2分)
4.    其他(知识的结构化,知识的完整性等,提交markdown文档,使用openeuler系统等)(1分)

二、课本第9章知识总结

(1)、I/O库函数与系统调用

I/O库函数的根都在对应的系统调用函数中

1、系统调用函数

open():open函数用来打开或创建一个文件,若成功返回文件描述符,否则返回-1。
read() :read函数逐个字节或者字符读取文件中的内容;
write() :write函数会把参数buf 所指的内存写入count 个字节到参数fd 所指的文件内。如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入erro 中。
lseek() :每一个已打开的文件都有一个读写位置,当read()或write()时, 读写位置会随之改变,lseek函数是用来控制该文件的读写位置。
close():close函数用于关闭由open函数所打开的文件。

2、I/O库函数

fopen()

fopen函数用于打开文件,第一个形式参数表示文件名,可以包含路径和文件名两部分。其调用格式为:FILE *fopen(char *xxx, *type)。

fread()

fread函数用于从文件流中读取数据。

fwrite()

fwrite函数写入文件(可安全用于二进制文件)返回写入的字符数,出现错误时则返回 false。

fseek()

fseek函数用于重定位流上的文件指针,成功则返回0,否则返回其他值。

fclose()

fclose()函数用来关闭一个由fopen()函数打开的文件,其调用格式为int fclose(FILE *stream)。该函数返回一个整型数。当文件关闭成功时,返回0,否则返回一个非零值。可以根据函数的返回值判断文件是否关闭成功。

(2)、I/O库函数算法

1、fread算法

第一次调用时,fread()使用保存的文件扫描符fd发出 n=read(fd, fbuffer, BLKSIZE);系统调用,用数据块填充内部的fbuff[];
初始化fbuff[]指针、计数器和状态变量;
将数据复制到程序缓冲区;
若内部缓冲没有足够的数据,则使用read()继续填充内部缓冲区,并将数据从内部缓冲区复制到程序缓冲区;
复制完之后,更新内部缓冲区的指针、计数器,为下次read()做准备。

2、fwrite算法

将数据写入内部缓冲区,调整缓冲区指针、计数器和状态变量;
若缓冲区满,则调用write()将缓冲区写入系统内核。

3、fclose算法

关闭文件流局部缓冲区;
发出close(fd)系统调用关闭file结构体文件描述符;
释放file结构体,并将file指针重置为null。

(3)、I/O库模式

“r”:打开一个用于读取的文件。该文件必须存在。
“w”:创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。
“a”:追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。
“r+”:打开一个用于更新的文件,可读取也可写入。该文件必须存在。
“w+”:创建一个用于读写的空文件。
“a+”:打开一个用于读取和追加的文件。

1、字符模式I/O

int fgetc(FILE *fp):
int ungetc(int c ,FILE *fp);
int fputc(int c,FILE *fp);
fgetc()返回的是整数,而不是字符,因为他必须在文件结束时返回文件结束符。文件结束符通常是-1,将他与文件流中的任何字符分开。

2、行模式I/O

char *fgets(char *buf,int size,FILE *fp):从fp中读取最多为一行(以\n结尾)的字符。
int fputs(char *buf,FILE *fp):将buf中的一行写入fp中。

3、格式化I/O

格式化输入:
scanf(char *FMT ,&items);
fscanf(fp,char *FMT ,&items);
格式化输出:
printf(char *FMT,items);
fprintf(fp,char *FMT,items);

4、内存中的转换函数

sscanf(buf ,FMT,&items);
sprintf(buf ,FMT, items);

(4)、文件流缓冲

三种文件缓冲方案

无缓冲_IONBUF:从非缓冲流中写入(读取)的字符将尽快单独传输到文件(从文件传输)
行缓冲_IOLBUF:遇到换行符,写入行缓冲流的字符以块的形式传输,如文件流stdout
全缓冲_IOFBUF:文件流的正常缓冲方案,以块大小传出

三、课堂代码实现

(1)动态库打包

 

 

 

 

 

 

 

 

 (2)gdb调试

调试代码如下

#include<stdio.h>
#include<unistd.h>
void test()
{
    printf("test8");
}
void main()
{
    int i = 0;
    printf("test1");
    printf("test2");
    printf("test3");
    printf("test4");
    printf("test5");
    printf("test6");
    printf("test7");
    test();
}

  

 

 

 

 四、苏格拉底问答挑战

(1)I/O库模式

 

 

 

 (2)文件流缓冲

 

 

 (ps:有关我使用的本地大模型的建立方式将在后续课程中单独写一份博客说明)