目次
一、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 数组大小(宏常量)
2. ファイル操作 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;
}
このコードは、ユーザーにファイル名の入力を求め、書き込み用にファイルを開き、ユーザーのキーボード入力をファイルに書き込みます。次に、同じファイルを読み込み用に開き、ファイルの内容を読み込んで画面に出力します。プログラムを実行すると、ファイルの入出力が成功したかどうかを確認できます。
3. 文字列ストリーム(メモリストリーム)IO
C 言語には組み込みの文字列ストリーム関数はありませんが、次の方法で手動でシミュレートできます。
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++ を使用して記述できます。
4. デバイスの抽象化 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;
}
上記の 2 つの関数に加えて、C 言語には、puts 関数、gets 関数、fgets 関数、puts 関数など、他の多くの画面入出力関数も用意されており、特定のニーズに応じて選択して使用できます。
画面の入出力に適用できる関数は、ファイル操作に適用できます. 画面の入力と出力を比較することは、基本的に FILE* タイプの操作です.