关于知识点
知识点归纳
第九章
- 9.1 I/O库函数
系统调用是文件操作的基础,但它们只支持数据块的读/写。I/O库函数是一系列文件操作函数,既方便用户使用,又提高了整体效率。 - 9.2 I/O库函数与系统调用
I/O库函数是封装了系统调用的一组高层函数接口,用于进行输入输出操作。它们提供了一种简便的方式来进行文件和设备的读写操作,并隐藏了底层系统操作的细节。而系统调用是操作系统提供的一组接口,用于访问硬件设备和其他资源。- 缓冲机制:I/O库函数通常会使用缓冲区来提高读写的效率。它们会将数据暂时存储在内存中的缓冲区中,然后进行一次性的读写操作。
- 文件操作:I/O库函数和系统调用都可以用于对文件进行读写操作。I/O库函数如
fopen()
和fwrite()
提供了更简单的接口来打开文件和写入数据,而系统调用如open()
和write()
则提供了底层的文件操作接口。 - 标准输入输出:I/O库函数提供了对标准输入输出的访问接口,如
printf()
和scanf()
用于标准输出和输入流的格式化读写。而系统调用对应的是标准输入输出的文件描述符(stdin、stdout和stderr)。 - 错误处理:I/O库函数通常会返回特定的值来指示出错情况,如EOF表示文件结束,而系统调用通常会返回-1来表示出错。并且,I/O库函数会设置全局变量
errno
来指示具体的错误类型。 - 设备和网络操作:I/O库函数通常用于对设备和网络进行操作,如
fread()
和fwrite()
可以用于读写二进制数据,而系统调用如socket()
和send()
则用于创建和操作网络套接字。
- 9.3 I/O库函数的算法
- fread算法
fread
是C语言中的一个I/O库函数,用于从文件中读取二进制数据。它的函数原型如下:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
fread
函数从给定的文件流stream
中读取count
个元素的数据,每个元素的大小由size
指定,并将读取的数据存储到由ptr
指针指向的内存空间中。读取的总字节数被返回。
fread
函数的工作原理如下:
fread
首先检查文件流的位置指针,确定将要读取的数据的位置。- 它会按照元素的大小
size
和要读取的元素数量count
计算出需要读取的总字节数。 fread
会尽可能从文件中读取足够的字节数,以填满指定的内存空间。如果读取的字节数小于请求的字节数,可能是因为已经到达了文件结尾或者发生了错误。- 读取的数据被存储到由
ptr
指针指向的内存空间中。 fread
会返回实际读取到的元素数量(即总字节数除以size
)。如果返回的值少于请求的元素数量,可能表示已经到达了文件结尾或者发生了错误。
需要注意的是,fread
函数适用于读取二进制数据,对于文本数据的读取,应该使用fgets
或fscanf
等函数。
下面是一个示例的代码段:
#include <stdio.h>
int main() {
FILE *fp;
int data[5];
// 打开文件
fp = fopen("data.txt", "rb");
if (fp == NULL) {
printf("打开文件失败
");
return 1;
}
// 读取数据
size_t elements = fread(data, sizeof(int), 5, fp);
if (elements != 5) {
printf("读取文件失败
");
fclose(fp);
return 1;
}
// 输出数据
for (int i = 0; i < 5; i++) {
printf("%d ", data[i]);
}
// 关闭文件
fclose(fp);
return 0;
}
以上代码简单展示了fread算法的用途。
- *fwrite算法*
fwrite
是C语言中的一个I/O库函数,用于将二进制数据写入文件。它的函数原型如下:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
fwrite
函数将由ptr
指针指向的内存中的二进制数据写入到给定的文件流stream
中。要写入的数据有count
个元素,每个元素的大小由size
指定。写入的总字节数被返回。
fwrite
函数的工作原理如下:
fwrite
会将指定内存中的二进制数据按照元素大小size
和要写入的元素数量count
计算出写入的总字节数。- 它会将计算出的字节数的数据从内存写入到文件流中。
fwrite
会更新文件流的位置指针,使其指向已写入数据的下一个位置。- 如果所有数据都成功写入文件,则返回写入的元素数量(即总字节数除以
size
)。如果返回的值少于请求写入的元素数量,可能表示发生了错误。
需要注意的是,fwrite
函数适用于将二进制数据写入文件,对于文本数据的写入,应该使用fprintf
或fputs
等函数。
下面是一个示例的代码段:
#include <stdio.h>
int main() {
FILE *fp;
int data[] = {10, 20, 30, 40, 50};
// 打开文件
fp = fopen("data.txt", "wb");
if (fp == NULL) {
printf("打开文件失败
");
return 1;
}
// 写入数据
size_t elements = fwrite(data, sizeof(int), 5, fp);
if (elements != 5) {
printf("写入文件失败
");
fclose(fp);
return 1;
}
// 关闭文件
fclose(fp);
return 0;
}
- *fclose算法*
`fclose 是C语言中的一个I/O库函数,用于关闭一个已打开的文件流。它的函数原型如下:
int fclose(FILE *stream);
fclose
函数用于结束对文件的操作,并将与文件流 stream
相关的资源释放。它的工作原理如下:
-
fclose
会将尚未写入到文件的缓冲区的数据写入文件,以确保数据的完整性。 -
它会关闭文件流
stream
,这意味着不能再通过该文件流进行读写操作。关闭文件流会释放与文件流相关的资源,如文件描述符。 -
如果成功关闭文件流,
fclose
返回 0。如果关闭失败,它会返回一个非零值,通常是EOF
。 -
在关闭文件流之后,应该避免再次使用已关闭的文件流进行读写操作,因为这可能导致未定义的行为。
下面是一个示例代码段:
#include <stdio.h>
int main() {
FILE *fp;
// 打开文件
fp = fopen("data.txt", "w");
if (fp == NULL) {
printf("打开文件失败
");
return 1;
}
// 写入数据
fprintf(fp, "Hello, world!");
// 关闭文件
if (fclose(fp) == 0) {
printf("文件已成功关闭
");
} else {
printf("关闭文件失败
");
}
return 0;
}
在上述示例中,fclose
函数用于关闭文件流 fp
,以确保数据被写入文件并释放相关资源。
- 9.4 使用I/O库函数或系统调用
- 9.5 I/O库模式
- 字符模式I/O
- 行模式I/O
- 格式化I/O
- 其他I/O库函数
- 9.6 文件流缓冲
- 无缓冲
- 行缓冲
- 全缓冲
- 9.7 变参函数
苏格拉底挑战
问题1:文件流缓冲
问题2:I/O库函数的算法
遇到问题以及实践过程截图
问题1:fread算法的操作实例