fgetc和fputc 函数
fgetc
和fputc
是C语言中用于文件操作的函数,分别用于从文件中读取字符和向文件中写入字符。以下是这两个函数的详细原型和说明:
fgetc函数原型
int fgetc(FILE *stream);
参数说明:
FILE *stream
:一个指向FILE
对象的指针,该对象指定了一个文件流。这个流应该是已经打开的,以便进行读取。
返回值:
- 如果读取成功,返回读取的字符(以
unsigned char
强制转换为int
的形式)。 - 如果到达文件末尾或发生错误,返回
EOF
(通常定义为-1)。
fputc函数原型
int fputc(int character, FILE *stream);
参数说明:
int character
:需要写入的字符。虽然传入参数定义为int
类型,实际上它只会使用该int
参数的低8位,将其当作无符号字符来处理。FILE *stream
:要写入字符的文件流。可以是用标准库函数fopen
打开的文件,也可以是类似stdin
、stdout
、stderr
之类的预定义文件流。
返回值:
- 如果写入成功,返回写入的字符(作为
unsigned char
类型转换为int
类型)。 - 如果写入失败,返回
EOF
(通常定义为-1)。
总结
fgetc
函数用于从指定的文件流中读取下一个字符。fputc
函数用于将指定的字符写入到指定的文件流中。
这两个函数在处理文件时非常有用,可以单独使用或结合其他文件操作函数一起使用。它们通常用于处理二进制文件和文本文件。
简单应用
**题目:**打开一个名为"a.txt"的源文件以读取数据,然后打开(或创建)一个名为"b.txt"的目标文件以写入数据。
题目解析:
- 使用一个
while
循环,在循环中,使用fgetc
函数从源文件中读取一个字符,并检查是否读取到了文件结束符(EOF)。如果没有读取到EOF,我们就使用fputc
函数将该字符写入到目标文件中。 - 最后,我们关闭两个文件,并输出一条消息表示文件复制完成。
代码实现:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *sourceFile, *targetFile;
char ch;
// 打开源文件
sourceFile = fopen("a.txt", "r");
if (sourceFile == NULL) {
perror("Error opening source file");
return EXIT_FAILURE;
}
// 打开目标文件(如果文件不存在,将创建它)
targetFile = fopen("b.txt", "w");
if (targetFile == NULL) {
perror("Error opening target file");
fclose(sourceFile); // 关闭已打开的源文件
return EXIT_FAILURE;
}
// 使用fgetc从源文件中读取字符,并使用fputc写入到目标文件中
while ((ch = fgetc(sourceFile)) != EOF) {
fputc(ch, targetFile);
}
// 关闭文件
fclose(sourceFile);
fclose(targetFile);
printf("File copy complete!\n");
return 0;
}
a文件内容 | 复制后b文件内容 |
---|---|
fgets和fputs函数
fgets
和fputs
是C语言中用于文件操作的函数,分别用于从文件中读取一行字符串和向文件中写入一个字符串。以下是这两个函数的详细原型和说明:
fgets函数原型
char *fgets(char *str, int n, FILE *stream);
参数说明:
char *str
:指向一个字符数组的指针,用于存储从文件读取的字符串。int n
:要读取的最大字符数(包括最后的空字符\0
)。FILE *stream
:指向FILE
对象的指针,标识了要从中读取字符的文件流。
返回值:
- 如果成功,返回指向读取的字符串的指针(即
str
参数的值)。 - 如果到达文件末尾或发生错误,返回
NULL
。
fputs函数原型
int fputs(const char *s, FILE *stream);
参数说明:
const char *s
:指向要写入的字符串的指针。FILE *stream
:指向FILE
对象的指针,指定了要将字符串写入的文件流。
返回值:
- 如果成功,返回非负整数。
- 如果发生错误,返回
EOF
(一个定义在stdio.h中的特殊值,通常为-1)。
总结
fgets
函数用于从指定的文件流中读取一行字符串,直到遇到换行符、文件结束或读取了n-1
个字符。fputs
函数用于将一个字符串写入到指定的文件流中,不包括字符串的终止空字符\0
。
这两个函数在处理文本文件时特别有用,fgets
常用于按行读取文本内容,而fputs
则用于将字符串写入文件。注意,使用这两个函数时应确保文件流已正确打开,且在使用完毕后应关闭文件流以避免资源泄漏。
简单应用
题目:使用fgets
函数从文件aa.txt中读取内容,并使用fputs
函数将内容写入另一个文件bb.txt中。
题目解析:
- 首先定义了源文件和目标文件的文件名(这里分别为"aa.txt"和"bb.txt"),然后定义了一个用于暂存读取内容的字符数组
buffer
,并指定了其大小为1024字节。 - 接着,我们使用
fopen
函数以只读模式(“r”)打开源文件,并以写入模式(“w”)打开目标文件。如果文件打开失败,程序将输出错误消息并退出。 - 然后,我们使用
fgets
函数从源文件中读取内容到buffer
中,并使用fputs
函数将内容写入到目标文件中。这个操作在一个循环中进行,直到源文件的所有内容都被读取并写入到目标文件中。 - 最后,我们使用
fclose
函数关闭源文件和目标文件,并输出一条消息表示文件复制完成。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 1024 // 缓冲区大小
int main() {
FILE *sourceFile, *targetFile;
char buffer[BUFFER_SIZE];
// 打开源文件
sourceFile = fopen("aa.txt", "r");
if (sourceFile == NULL) { //打开失败判断
perror("Error opening source file");
return EXIT_FAILURE;
}
// 打开目标文件(如果文件不存在,将创建它)
targetFile = fopen("bb.txt", "w");
if (targetFile == NULL) {
perror("Error opening target file");
fclose(sourceFile); // 关闭已打开的源文件
return EXIT_FAILURE;
}
// 使用fgets循环读取源文件内容存放在buffer数组中
while ((fgets(buffer, BUFFER_SIZE, sourceFile)) != NULL) {
// 使用fputs将读取的内容(即buffer的内容)写入目标文件
fputs(buffer, targetFile);
}
// 关闭文件
fclose(sourceFile);
fclose(targetFile);
printf("File copy complete!\n");
return 0;
}
运行结果:
aa.txt原来的内容 | 复制后bb.txt的内容 |
---|---|
fread 和fwrite 函数
fread
和fwrite
是C语言中用于文件操作的重要函数,它们分别用于从文件中读取数据块和向文件中写入数据块。以下是这两个函数的详细原型和说明:
fread 函数原型
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
参数说明:
void *ptr
:这是一个指向内存空间的指针,该内存空间用于储存从文件中读取的数据块。由于ptr
是void *
类型,它可以指向任何数据类型。size_t size
:这指定了每个从文件读取的数据项的字节大小。size_t
是一个无符号整数类型,通常用于表示对象的大小。size_t count
:这指定了从文件读取的数据项的个数。FILE *stream
:这是一个指向FILE
类型结构的指针,它指定了fread
函数要读取的文件流,该值通常是fopen
函数的返回值。
返回值:
- 如果成功,
fread
函数返回实际读取的数据项个数(以size_t
类型返回)。 - 如果读取到文件末尾或发生错误,返回值可能小于
count
。
fwrite 函数原型
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
参数说明:
const void *ptr
:这是一个指向内存空间的指针,该内存空间中储存有待写入文件的数据块。由于ptr
是const void *
类型,它可以指向任何数据类型的常量。size_t size
:这指定了每个待写入文件的数据项的字节大小。size_t count
:这指定了待写入文件的数据项的个数。FILE *stream
:这是一个指向FILE
类型结构的指针,它指定了fwrite
函数要写入的文件流。
返回值:
- 如果成功,
fwrite
函数返回实际写入的数据项个数(以size_t
类型返回)。 - 如果写入过程中发生错误,返回值可能小于
count
。
总结
fread
和fwrite
函数都用于处理二进制文件,可以读写任意类型的数据。- 这两个函数都使用
size_t
类型来表示数据项的大小和数量,确保可以处理大文件。 - 在使用这两个函数时,需要注意文件指针
stream
必须已经被正确打开,并且具有适当的读写权限。 - 这两个函数都是块操作,比逐个字符操作的
fgetc
和fputc
函数在处理大文件时更加高效。
函数应用
若使用同样的案例,那么只要修改代码为
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 1024 // 缓冲区大小
int main() {
FILE *sourceFile, *targetFile;
char buffer[BUFFER_SIZE];
size_t bytesRead;
// 打开源文件
sourceFile = fopen("aa.txt", "rb"); // 使用二进制模式读取
if (sourceFile == NULL) {
perror("Error opening source file");
return EXIT_FAILURE;
}
// 打开目标文件(如果文件不存在,将创建它)
targetFile = fopen("bb.txt", "wb"); // 使用二进制模式写入
if (targetFile == NULL) {
perror("Error opening target file");
fclose(sourceFile); // 关闭已打开的源文件
return EXIT_FAILURE;
}
// 使用fread从源文件中读取数据块,并使用fwrite写入到目标文件中
while ((bytesRead = fread(buffer, sizeof(char), BUFFER_SIZE, sourceFile)) > 0) {
fwrite(buffer, sizeof(char), bytesRead, targetFile);
}
// 关闭文件
fclose(sourceFile);
fclose(targetFile);
printf("File copy complete!\n");
return EXIT_SUCCESS;
}
注意,这里我们使用了二进制模式(“rb"和"wb”)来打开文件,这允许我们处理任何类型的数据,包括文本和二进制数据。
fscanf和fprintf函数
fscanf
和fprintf
是C语言中用于文件操作的重要函数,分别用于从文件中读取格式化的输入和向文件中写入格式化的输出。以下是这两个函数的详细原型和说明:
fscanf 函数原型
int fscanf(FILE *stream, const char *format, ...);
参数说明:
FILE *stream
:这是一个指向FILE
对象的指针,该对象标识了要从中读取数据的文件流。const char *format
:这是一个C字符串,包含了要被读取的数据的格式。这个字符串可以包含普通字符(这些字符会被简单地复制到输出流中)和格式控制符(这些字符指定了如何从输入流中读取和解释数据)。...
:这是一个可变参数列表,包含了指向要存储读取数据的变量的指针。这些变量的类型和数量由format
字符串中的格式控制符决定。
返回值:
- 如果成功,
fscanf
函数返回成功读取并赋值的参数数量。 - 如果在读取过程中遇到文件结束或发生错误,则返回
EOF
(通常定义为-1)。
fprintf 函数原型
int fprintf(FILE *stream, const char *format, ...);
参数说明:
FILE *stream
:这是一个指向FILE
对象的指针,该对象标识了要将数据写入其中的文件流。const char *format
:这是一个C字符串,包含了要被写入到流stream
中的文本。它可以包含嵌入的格式标签,这些标签会被随后的附加参数中指定的值替换,并按需进行格式化。...
:这是一个可变参数列表,包含了要写入文件的数据。这些数据的类型和数量由format
字符串中的格式控制符决定。
返回值:
- 如果成功,
fprintf
函数返回写入的字符数(不包括字符串结束符\0
)。 - 如果发生错误,返回一个负值。
总结
fscanf
和fprintf
函数都使用FILE
指针来指定操作的文件流。- 这两个函数都接受一个格式字符串,该字符串定义了如何读取或写入数据。
- 这两个函数都接受可变数量的参数,这些参数的类型和数量由格式字符串中的格式控制符决定。
fscanf
用于从文件中读取格式化的数据,而fprintf
用于向文件中写入格式化的数据。
注意:这两个函数在处理文件时都依赖于文件的当前位置。如果你需要从文件的特定位置开始读取或写入,你需要使用fseek
函数来设置文件的位置指针。
应用示例
学生成绩管理系统
项目描述:
这个简单的项目将模拟一个学生成绩管理系统的部分功能。它从一个名为input.txt
的文本文件中读取学生的姓名和成绩,然后输出每个学生的姓名和成绩到控制台。之后,它将这些信息写入到另一个名为output.txt
的文本文件中。
文本文件(input.txt)格式:
张三 90
李四 85
王五 92
赵六 78
每行包含学生的姓名和成绩,用空格分隔。
代码实现:
#include <stdio.h>
#include <stdlib.h>
#define MAX_LINE_LENGTH 100
int main() {
FILE *inputFile, *outputFile;
char line[MAX_LINE_LENGTH];
char name[50];
int score;
// 打开输入文件
inputFile = fopen("input.txt", "r");
if (inputFile == NULL) {
printf("Error opening input file"); //或者perror
return 1;
}
// 打开输出文件
outputFile = fopen("output.txt", "w");
if (outputFile == NULL) {
printf("Error opening output file");
fclose(inputFile); // 不要忘记关闭已打开的文件
return 1;
}
// 读取并处理文件内容
while (fscanf(inputFile, "%49s %d", name, &score) == 2) {
// 在控制台输出学生姓名和成绩
printf("Name: %s, Score: %d\n", name, score);
// 将学生姓名和成绩写入到输出文件
fprintf(outputFile, "Name: %s, Score: %d\n", name, score);
}
// 关闭文件
fclose(inputFile);
fclose(outputFile);
printf("Data processing completed successfully.\n");
return 0;
}
运行后:output.txt中的文本内容
注意事项:
-
在使用
fscanf
时,我们指定了%49s
来读取学生的姓名,这是为了防止输入过长导致缓冲区溢出。49
是因为我们为name
数组预留了一个位置给字符串结束符\0
。 -
我们检查
fscanf
的返回值是否为2
,以确保我们成功读取了一个姓名和一个成绩。 -
使用
printf
(或perror)函数来输出打开文件时发生的错误。 -
始终在不再需要文件时关闭它,以避免资源泄露。
fclose(inputFile);
fclose(outputFile); -
考虑到错误处理,如果无法打开文件,则程序会输出一个错误消息并返回非零值。