总体概述
流:
C程序针对文件,画面,键盘等数据输入输出操作都是通过流操作的
-
标准输入 (
stdin
):- 表示从键盘输入的数据。
- 通常用于接收用户输入。
-
标准输出 (
stdout
):- 表示向屏幕输出的数据。
- 通常用于显示程序结果。
-
标准错误输出 (
stderr
):- 专门用于输出错误信息。
- 通常与标准输出分开,以便错误信息可以被单独处理或记录。
文件指针FILE*:
文件指针是一个指向FILE
结构体的指针。FILE
结构体包含了文件的相关信息,如文件的当前位置、缓冲区状态等。文件指针允许程序对文件进行各种操作,如打开、读取、写入、关闭等。
1字符输入输出函数
1.fputc:
向流中写入单个字符(流:所有流包括文件,屏幕):
2.fgetc:
从流中读取一个字符(!所有流)
2.文本输入输出函数
1.fgets:
用于从文件或其他输入流中读取一行文本(即直到遇到换行符 \n
或达到指定的最大字符数为止)。
int main() {
// 打开文件
FILE *pf = fopen("test.txt", "r");
if (pf == NULL) {
perror("fopen:");
return 1;
}
// 操作文件
char str[100]; // 定义一个足够大的缓冲区
// 从文件 pf 流中读取文本(10个字符)
if (fgets(str, 10, pf) == NULL) {
perror("fgets (from file):");
fclose(pf);
return 1;
}
// 从标准输入流中读取文本(1个字符)
if (fgets(str, 1, stdin) == NULL) {
perror("fgets (from stdin):");
fclose(pf);
return 1;
}
// 输出读取的文本
printf("%s", str);
// 关闭文件
if (fclose(pf) != 0) {
perror("fclose:");
return 1;
}
pf = NULL; // 可选,但有助于避免后续代码中误用已关闭的文件指针
return 0;
}
2.fputs:
用于将一个字符串写入到一个输出流中。这个函数通常用于向文件或其他输出流逐行写入数据。
3.格式化输入输出函数
1.fscanf
用于从输入流中格式化读取数据。它类似于 scanf
函数,但是用于从文件或其他输入流中读取数据。
2.fprintf
用于向输出流中格式化写入数据。它类似于 printf
函数,但是用于向文件或其他输出流中写入数据。
#include <stdio.h>
int main() {
// 打开文件
FILE *file = fopen("output.txt", "w");
if (file == NULL) {
perror("fopen:");
return 1;
}
int number = 42;
double value = 3.14159;
char name[] = "John Doe";
// 向文件写入格式化数据
if (fprintf(file, "Number: %d\nValue: %.2f\nName: %s\n", number, value, name) < 0) {
perror("fprintf:");
fclose(file);
return 1;
}
// 关闭文件
if (fclose(file) != 0) {
perror("fclose:");
return 1;
}
return 0;
}
3.scanf
用于从标准输入流(通常是键盘输入)中格式化读取数据。它与 fscanf
类似,但 scanf
特别用于从标准输入流 stdin
读取数据。
#include <stdio.h>
int main() {
int number;
char name[50];
// 提示用户输入数据
printf("Enter an integer and a string separated by space: ");
// 从标准输入读取整数和字符串
if (scanf("%d %s", &number, name) != 2) {
printf("Invalid input. Please enter an integer followed by a string.\n");
return 1;
}
// 输出读取的数据
printf("Number: %d\n", number);
printf("Name: %s\n", name);
return 0;
}
4.sprintf
用于将格式化的字符串写入到一个字符数组中。它类似于 printf
函数,但 sprintf
的输出不是发送到标准输出流(如屏幕),而是写入到一个字符数组中。
#include <stdio.h>
#include <string.h>
int main() {
int number = 42;
char name[] = "John Doe";
char buffer[100];
// 使用 sprintf 将格式化的字符串写入到字符数组 buffer 中
if (sprintf(buffer, "Number: %d\nName: %s\n", number, name) < 0) {
perror("sprintf:");
return 1;
}
// 输出格式化的字符串
printf("%s", buffer);
return 0;
}
4.二进制输入输出函数
1.fread
用于从文件或其他输入流中读取固定大小的数据块。与 fgetc
或 fgets
等逐字符或逐行读取不同,fread
允许一次性读取任意数量的元素,每个元素可以有不同的大小。
#include <stdio.h>
int main() {
// 打开文件
FILE *file = fopen("data.bin", "rb");
if (file == NULL) {
perror("fopen:");
return 1;
}
int numbers[5];
// 使用 fread 读取整数数组
size_t count = fread(numbers, sizeof(int), 5, file);
if (count != 5) {
perror("fread:");
fclose(file);
return 1;
}
// 输出读取的数据
for (int i = 0; i < 5; ++i) {
printf("%d ", numbers[i]);
}
printf("\n");
// 关闭文件
if (fclose(file) != 0) {
perror("fclose:");
return 1;
}
return 0;
}
2.fwrite
用于将固定大小的数据块写入到文件或其他输出流中。与 fprintf
或 printf
等格式化输出不同,fwrite
允许一次性写入任意数量的元素,每个元素可以有不同的大小。
#include <stdio.h>
int main() {
// 打开文件
FILE *file = fopen("data.bin", "wb");
if (file == NULL) {
perror("fopen:");
return 1;
}
int numbers[] = {1, 2, 3, 4, 5};
int length = sizeof(numbers) / sizeof(numbers[0]);
// 使用 fwrite 将整数数组写入文件
size_t count = fwrite(numbers, sizeof(int), length, file);
if (count != length) {
perror("fwrite:");
fclose(file);
return 1;
}
// 关闭文件
if (fclose(file) != 0) {
perror("fclose:");
return 1;
}
return 0;
}
5.文件读取结束标志
-
1.feof:遇到文件末尾正常结束
-
2.ferror:发生读取错误结束读取
-
3.EOF:正常返回字符ASCII值,读取异常2返回EOF,文件读取结束
总结
-
fread
和fwrite
:适合用于处理二进制数据,尤其是结构体和固定大小的数据块。 -
fscanf
和fprintf
:适合用于格式化读写文件或其他输入输出流。 -
scanf
和printf
:适合用于格式化读写标准输入输出流。 -
sprintf
和snprintf
:适合用于在内存中构建格式化的字符串,尤其是需要考虑安全性的场景。