目录
一、C-IO
c语言的IO输入/输出是由标准库<stdio.h>提供,见名知意,stdio就是标准库(std)的IO模块。<stdio.h> 头文件提供通用文件操作支持并提供有窄字符输入/输出能力的函数。针对与宽字符,增加了<wchar.h> 作为辅助,该头文件提供有宽字符输入/输出能力的函数。c语言的I/O 流为 FILE 对象所代表,只能通过 FILE* 类型指针访问及操作。每个流与外部物理设备(文件、标准输入流、打印机、序列端口等)关联。
下来看看stdio的主要功能:
//定义于头文件 <stdio.h>
FILE 对象类型,足以保有控制 C I/O 流所需的全部信息(typedef)
fpos_t 非数组完整对象类型,足以唯一指定文件的位置和多字节剖析状态(typedef)
//预定义标准流
stdin 与标准输入流关联的 FILE* 类型表达式(宏常量)
stdout 与标准输出流关联的 FILE* 类型表达式(宏常量)
stderr 与标准错误输出流关联的 FILE* 类型表达式(宏常量)
//函数,文件访问
fopen (C11)打开文件(函数)
fopen_s (C11)打开文件(函数)
freopen (C11)以不同名称打开既存的文件流(函数)
freopen_s (C11)以不同名称打开既存的文件流(函数)
fclose 关闭文件(函数)
fflush 将输出流与实际文件同步(函数)
setbuf 为文件流设置缓冲区(函数)
setvbuf 为文件流设置缓冲区和其大小(函数)
//直接输入/输出
fread 从文件读取(函数)
fwrite 写入到文件(函数)
//无格式输入/输出,窄字符
fgetc 从文件流获取一个字符(函数)
getc 从文件流获取一个字符(函数)
fgets 从文件流获取一个字符串(函数)
fputc 将一个字符写入文件流(函数)
putc 将一个字符写入文件流(函数)
fputs 将一个字符串写入文件流(函数)
getchar 从 stdin 读取一个字符(函数)
gets (C11 中移除)从 stdin 读取一个字符串(函数)
gets_s (C11)从 stdin 读取一个字符串(函数)
putchar 将一个字符写入 stdout(函数)
puts 将一个字符串写入 stdout(函数)
ungetc 将一个字符送回文件流(函数)
//有格式输入/输出,窄字符
scanf 从stdin、文件流或缓冲区读取格式化输入(函数)
fscanf ...
sscanf ...
scanf_s (C11)...
fscanf_s (C11)...
sscanf_s (C11)...
vscanf (C99)从 stdin 、文件流或缓冲区读取格式化输入 使用可变参数列表(函数)
vfscanf (C99)...
vsscanf (C99)...
vscanf_s (C11)...
vfscanf_s (C11)...
vsscanf_s (C11)...
printf 打印格式化输出到 stdout 、文件流或缓冲区(函数)
fprintf ...
sprintf ...
snprintf (C99)...
printf_s (C11)...
fprintf_s (C11)...
sprintf_s (C11)...
snprintf_s (C11)...
vprintf 打印格式化输出到stdout、文件流或缓冲区 使用可变参数列表(函数)
vfprintf ...
vsprintf ...
vsnprintf (C99)...
vprintf_s (C11)...
vfprintf_s (C11)...
vsprintf_s (C11)...
vsnprintf_s (C11)...
//文件位置
ftell 返回当前的文件位置指示值(函数)
fgetpos 获取文件位置指示器(函数)
fseek 将文件位置指示符移动到文件中的指定位置(函数)
fsetpos 将文件位置指示器移动到文件中的指定位置(函数)
rewind 将文件位置指示器移动到文件首(函数)
//错误处理
clearerr 清除错误(函数)
feof 检查文件结尾(函数)
ferror 检查文件错误(函数)
perror 显示对应当前错误的字符串到 stderr(函数)
//文件操作
remove 删除文件(函数)
rename 重命名文件(函数)
tmpfile 返回指向临时文件的指针(函数)
tmpfile_s (C11) ...
tmpnam 返回唯一的文件名(函数)
tmpnam_s (C11) ...
//宏常量
EOF int 类型的负值整数常量表达式(宏常量)
FOPEN_MAX 能同时打开的文件数(宏常量)
FILENAME_MAX 保有最长受支持文件名所需的 char 数组大小(宏常量)
BUFSIZ setbuf() 所用的缓冲区大小(宏常量)
_IOFBF 指示全缓冲 I/O 的 setvbuf() 参数(宏常量)
_IOLBF 指示行缓冲 I/O 的 setvbuf() 参数(宏常量)
_IONBF 指示无缓冲 I/O 的 setvbuf() 参数(宏常量)
SEEK_SET 指示从文件首开始寻位的 fseek() 参数(宏常量)
SEEK_CUR 指示从文件当前位置开始寻位的 fseek() 参数(宏常量)
SEEK_END 指示从文件尾开始寻位的 fseek() 参数(宏常量)
TMP_MAX tmpnam 所能生成的最大独有文件数(宏常量)
TMP_MAX_S (C11)tmpnam_s 所能生成的最大独有文件数(宏常量)
L_tmpnam 保有 tmpnam 结果所需的 char 数组大小(宏常量)
L_tmpnam_s (C11)保有 tmpnam_s 结果所需的 char 数组大小(宏常量)
二、文件操作IO
一般来说,文件操作有以下步骤:
- 定义文件指针,并打开文件;
- 通过文件指针进行读写操作;
- 关闭文件。
以下是一个简单的例子,演示如何实现文件的输入输出操作:
//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char ch, filename[10];
printf("请输入文件名:");
scanf("%s", filename);
fp = fopen(filename, "w"); // 以写入方式打开文件,如果文件不存在则新建文件
if (fp == NULL)
{
printf("无法打开文件\n");
exit(0);
}
printf("请输入内容:\n");
while ((ch = getchar()) != EOF) // 从键盘读取字符,直到EOF结束
{
fputc(ch, fp); // 将字符写入到文件中
}
fclose(fp); // 关闭文件
printf("写入成功\n");
fp = fopen(filename, "r"); // 以读取方式打开文件
if (fp == NULL)
{
printf("无法打开文件\n");
exit(0);
}
printf("读取内容:\n");
while ((ch = fgetc(fp)) != EOF) // 从文件中读取字符,直到EOF结束
{
putchar(ch); // 将字符输出到屏幕
}
fclose(fp); // 关闭文件
return 0;
}
该代码会提示用户输入文件名,然后以写入方式打开文件,将用户从键盘输入的内容写入到文件中。接着,以读取方式打开同一个文件,将文件中的内容读取并输出到屏幕上。可以通过运行该程序,查看文件的输入输出是否成功。
三、字符串流(内存流)IO
C语言中没有内置的字符串流(string stream)功能,但是可以通过以下方法手动模拟:
1.创建一个缓冲区作为字符串流的输出源
char buffer[1024]; // 创建一个大小为1024的缓冲区
2.使用sprintf将需要输出的数据格式化到缓冲区中
int x = 10;
float y = 3.14;
char str[] = "hello";
sprintf(buffer, "x=%d, y=%.2f, str=%s", x, y, str);
3.从缓冲区中读取字符串流数据
char result[1024];
strcpy(result, buffer);
以上是一种基本的手动模拟字符串流的方式。如果你需要更多类似C++中字符串流的高级功能,比如重载运算符、自定义输入/输出运算符等,可以使用C++编写。
四、设备抽象IO
C语言的设备抽象IO主要就是与命令窗口的交互,主要是通过预定义标准流来实现的,
stdin 与标准输入流关联的 FILE* 类型表达式
stdout 与标准输出流关联的 FILE* 类型表达式
stderr 与标准错误输出流关联的 FILE* 类型表达式
预定义标准流本质上就是FILE*指针操作,可以使用标准库中的stdio.h头文件提供的函数来进行屏幕输入/输出操作,常用的有printf函数、scanf函数等。
printf函数可以输出格式化的文本,用于向屏幕输出内容:
//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>
int main(void) {
printf("Hello, world!\n");
return 0;
}
而fprintf可以将全局stdout、stderr 等FILE*类型指定输出
//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>
int main(void) {
fprintf(stdout,"Hello, world!\n");
return 0;
}
scanf函数可以读取从屏幕输入的数据,并将数据存储到变量中:
//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>
int main(void) {
int num;
printf("Enter a number: ");
scanf("%d", &num);
printf("You entered: %d\n", num);
return 0;
}
当然,类似地,fscanf可以从全局stdin等FILE*类型指定输入
//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>
int main(void) {
int num;
printf("Enter a number: ");
fscanf(stdin,"%d", &num);
printf("You entered: %d\n", num);
return 0;
}
除了以上两个函数,C语言还提供了很多其他的屏幕输入/输出函数,比如puts函数、gets函数、fgets函数、puts函数等,可以根据具体的需求选择使用。
而对于屏幕输入输出适用的函数对于文件操作就更适用了,比较屏幕输入输出本质上就FILE*类型的操作。