标准 IO(Standard Input/Output)是由 Dennis Ritchie 在 1975 年设计的一套 IO 库,后来成为 C 语言的标准组成部分,并被 ANSI C 所采纳。它是对底层文件 IO 的封装,提供了更便捷、可移植的文件操作接口。
/dev/input
)在 Linux 系统中,一切皆文件,IO 操作本质上都是对文件的操作。标准 IO 作为 C 语言标准库的一部分,为文件操作提供了统一接口。
文件是 Linux 系统中存储数据(包括普通数据和指令)的基本单位,是数据持久化的载体。
d
:目录文件-
:普通文件l
:链接文件(link)p
:管道文件(pipe)s
:套接字文件(socket)c
:字符设备文件b
:块设备文件可通过ls -l
命令查看文件类型,第一个字符即表示文件类型。
stdio.h
(位于/usr/include/stdio.h
)stdio.h
→stdio.c
→libc.so
(动态库,位于/usr/lib
)#include
:引用系统库函数头文件
/usr/include/
)#include "xxx.h"
:引用用户自定义头文件
流是数据从文件流入和流出所体现的字节序列,在标准 IO 中用FILE*
指针表示(称为流对象或文件流指针)。
C 语言默认打开三个标准流:
stdin
:标准输入流(对应键盘)stdout
:标准输出流(对应显示器)stderr
:标准错误流(对应显示器)标准 IO 的一大特点是采用缓冲机制,目的是减少系统调用,提高效率。
行缓冲(1KB)
stdout
)\n
、缓冲区满、程序正常结束、fflush()
强制刷新全缓冲(4KB)
fflush()
强制刷新无缓冲(0KB)
stderr
)fflush(FILE *stream)
:强制刷新缓冲区fopen()
:打开文件并建立流
FILE *fopen(const char *path, const char *mode);
mode
参数:
r
:只读(文件不存在则报错)r+
:读写(文件不存在则报错)w
:只写(文件不存在则创建,存在则清空)w+
:读写(文件不存在则创建,存在则清空)a
:追加写(文件不存在则创建)a+
:追加读写(文件不存在则创建)fclose()
:关闭文件流
int fclose(FILE *stream);
fgetc(FILE *stream)
:从流中读取一个字符fputc(int c, FILE *stream)
:向流中写入一个字符getchar()
:从标准输入读取一个字符(fgetc(stdin)
的宏定义)putchar(int c)
:向标准输出写入一个字符(fputc(c, stdout)
的宏定义)示例:实现简单的输入输出循环
while(1)
fputc(fgetc(stdin), stdout);
fgets(char *s, int size, FILE *stream)
:从流中读取一行数据
char *fgets(char *s, int size, FILE *stream);
size-1
个字符,自动添加\0
\n
会停止读取,且\n
会被包含在结果中fputs(const char *s, FILE *stream)
:向流中写入一行数据
int fputs(const char *s, FILE *stream);
gets()
/puts()
:与fgets()
/fputs()
类似,但gets()
没有缓冲区大小限制,存在安全隐患
fread()
:从流中读取指定大小的数据块
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
fwrite()
:向流中写入指定大小的数据块
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
示例:结构体读写
struct person {
char name[20];
int age;
char sex;
char addr[100];
};
struct person p = {"Tom", 20, 'M', "Beijing"};
fwrite(&p, sizeof(struct person), 1, fp);
fseek()
:移动文件指针
int fseek(FILE *stream, long offset, int whence);
whence
参数:
SEEK_SET
:从文件开头SEEK_CUR
:从当前位置SEEK_END
:从文件末尾ftell()
:获取当前文件指针位置
long ftell(FILE *stream);
rewind()
:将文件指针移到开头(等效于fseek(stream, 0L, SEEK_SET)
)
void rewind(FILE *stream);
printf()
/scanf()
:格式化输入输出sprintf()
:将格式化数据写入字符串feof()
:判断文件是否到达末尾ferror()
:检测流是否出错clearerr()
:清除流出错标记fopen()
获取文件流指针(FILE*
)fclose()
关闭文件流,释放资源cat
程序#include
int main(int argc, char *argv[]) {
FILE *fp;
int c;
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open file %s\n", argv[1]);
return 1;
}
while ((c = fgetc(fp)) != EOF) {
fputc(c, stdout);
}
fclose(fp);
return 0;
}
#include
#include
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
FILE *src, *dest;
char buffer[BUFFER_SIZE];
size_t n;
if (argc != 3) {
fprintf(stderr, "Usage: %s source destination\n", argv[0]);
return 1;
}
src = fopen(argv[1], "rb");
if (src == NULL) {
fprintf(stderr, "Cannot open source file %s\n", argv[1]);
return 1;
}
dest = fopen(argv[2], "wb");
if (dest == NULL) {
fprintf(stderr, "Cannot open destination file %s\n", argv[2]);
fclose(src);
return 1;
}
while ((n = fread(buffer, 1, BUFFER_SIZE, src)) > 0) {
fwrite(buffer, 1, n, dest);
}
fclose(src);
fclose(dest);
return 0;
}
man 手册是查询函数和命令的重要工具,分为不同章节:
man 1 xxx
:查看命令帮助man 2 xxx
:查看系统调用函数man 3 xxx
:查看标准库函数例如:
man 3 fopen
:查看 fopen 函数的详细说明man 3 printf
:查看 printf 函数的用法标准 IO 是 C 语言中处理文件操作的重要接口,通过缓冲机制提高了 IO 效率,同时提供了丰富的函数族满足不同场景的需求。掌握标准 IO 的使用,对于 C 语言程序开发至关重要。从基本的字符读写到复杂的文件定位,标准 IO 都提供了简洁而强大的解决方案,是每个 C 程序员必须掌握的基础知识。