I/O
I/O
在这里中,你将学习如何使用 fopen、fwrite、fread、fprintf、fscanf、fgetc 和 fputc 在 C 中执行文件 I/O,包括文本和二进制。
FILE *
在 C 文件 I/O 中,你需要使用一个 FILE 指针,它将允许程序跟踪正在访问的文件。(你可以将其视为文件的内存地址或文件的位置)。
例如:
FILE *fp;fopen
要打开文件,需要使用 fopen 函数,该函数返回一个 FILE 指针。一旦打开文件,就可以使用 FILE 指针让编译器对文件执行输入和输出操作。
FILE *fopen(const char *filename, const char *mode);在文件名中,如果你使用字符串字面量作为参数,需要记住使用双反斜杠而不是单反斜杠,否则你可能会遇到转义字符,如\t。使用双反斜杠\可以转义\键,因此字符串按预期工作。当然,你的用户不需要这样做!这只是 C 和 C++中引用字符串的处理方式。
fopen 模式
fopen 允许的模式如下:
r - open for reading
w - open for writing (file need not exist)
a - open for appending (file need not exist)
r+ - open for reading and writing, start at beginning
w+ - open for reading and writing (overwrite file)
a+ - open for reading and writing (append if file exists)请注意,即使您的程序完全正确,fopen 也可能失败:您可能尝试打开用户指定的文件,而该文件可能不存在(或者可能是只读的)。在这种情况下,fopen 将返回 0,即 NULL 指针。
下面是一个使用 fopen 的简单示例:
FILE *fp;
fp=fopen("c:\\test.txt", "r");这段代码将以文本模式打开 test.txt 进行读取。要在二进制模式下打开文件,必须在模式字符串的末尾加上一个 b;例如,"rb"(对于读写模式,您可以在加号之后添加 b - "r+b" - 或在之前添加 - "rb+")
fclose
当您完成文件操作后,应该使用函数关闭它
int fclose(FILE *a_file);fclose 在文件成功关闭时返回零。
fclose 的一个例子是
fclose(fp);使用 fprintf、fscanf、fputc 和 fgetc 进行读写
要处理文本输入和输出,你使用 fprintf 和 fscanf,它们与 printf 和 scanf 类似,只是你必须将 FILE 指针作为第一个参数传递。例如:
FILE *fp;
fp=fopen("c:\\test.txt", "w");
fprintf(fp, "Testing...\n");也可以一次读取(或写入)一个字符——如果你希望执行逐字符输入(例如,如果你需要跟踪文件中的每个标点符号,那么一次读取一个字符比一次读取一个字符串更有意义)。fgetc 函数,它接受一个文件指针,并返回一个 int,将允许你从文件中读取一个字符:
int fgetc (FILE *fp);注意 fgetc 返回的是一个 int 类型。实际上这意味着当它从文件中读取一个普通字符时,返回的值适合存储在一个 unsigned char 中(基本上是一个 0 到 255 之间的数值)。另一方面,当你到达文件末尾时,无法获取字符值——在这种情况下,fgetc 将返回"EOF",这是一个表示已到达文件末尾的常量。要查看使用 fgetc 的实际完整示例,可以参考这里的示例。
fputc 函数允许你逐个字符地写入——如果你想要逐个字符地复制文件,可能会觉得这个很有用。它看起来是这样的:
int fputc( int c, FILE *fp );请注意,第一个参数应该是一个 unsigned char 范围内的值,以便它是一个有效的字符。第二个参数是要写入的文件。在成功时,fputc 将返回值 c,在失败时,它将返回 EOF。
二进制文件 I/O - fread 和 fwrite
对于二进制文件 I/O,你使用 fread 和 fwrite。
每个的声明是相似的:
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);这两个函数都处理内存块——通常是数组。因为它们接受指针,你也可以用这些函数处理其他数据结构;甚至可以将结构体写入文件或从内存中读取结构体。
让我们看一个函数来了解符号表示法是如何工作的。
fread 接受四个参数。不要被 void *ptr 的声明搞糊涂;void 表示它是一个可以用于任何类型变量的指针。第一个参数是要写入文件的数组名称或结构体的地址。第二个参数是数组每个元素的大小;它以字节为单位。例如,如果你有一个字符数组,你希望以一个字节的块来读取它,所以 size_of_elements 是 1。你可以使用 sizeof 运算符来获取各种数据类型的大小;例如,如果你有一个 int 类型的变量 x;你可以用 sizeof(x);来获取 x 的大小。这种用法对结构体或数组也适用。例如,如果你有一个名为 a_struct 的结构体类型的变量,你可以使用 sizeof(a_struct)来找出它占用了多少内存。
例如,
sizeof(int);第三个参数简单地表示你想要读取或写入的元素数量;例如,如果你传递一个包含 100 个元素的数组,你希望读取不超过 100 个元素,因此你传递 100。
最后一个参数简单地是我们一直在使用的文件指针。当使用 fread 时,在传递数组后,fread 将从文件中读取直到填满数组,并返回实际读取的元素数量。如果文件,例如,只有 30 个字节,但你尝试读取 100 个字节,它将返回它读取了 30 个字节。为了检查是否已到达文件末尾,使用 feof 函数,该函数接受一个 FILE 指针,如果已到达文件末尾,则返回 true。
fwrite 的使用方式类似,只是它将内存中的内容写入文件,而不是从内存中读取。
例如,
FILE *fp;
fp=fopen("c:\\test.bin", "wb");
char x[10]="ABCDEFGHIJ";
fwrite(x, sizeof(x[0]), sizeof(x)/sizeof(x[0]), fp);