目录
《小菜狗 C 语言入门 + 进阶笔记》目录:《小菜狗 C 语言入门 + 进阶笔记》(0)简介
1、以字符形式读写文件
在进行文件操作的时候,我们需要向文件中写入单个字符
,从文件中读取单个字符
,这时就可以使用 fgetc 和 fputc 来完成任务。
1.1、 fgetc 函数
函数定义:
int fgetc(FILE* stream);
功能:
函数用于从指定的文件流中读取单个字符,并将其返回为⼀个无符号字符。
参数:
指向 FILE 类型结构体的指针,指定了要读取字符的文件流。
返回值:
返回读取的字符,返回的是字符的 ASCII 码值。如果到达文件末尾或者发生错误,返回 EOF ,即 (-1) 。
使用注意事项:
- 需要包含 <stdio.h> 头文件。
- 在使用 fgetc() 之前,需要
确保文件已经以可读方式打开
。 - 返回的字符是以 unsigned char 形式返回,但是它会被转换为 int 类型以⽀持特殊值 EOF 。
- 文件指针会随着每次读取的调用而向前移动。
代码举例:
#include <stdio.h>
int main()
{
FILE *fp;
int c;
// (1)打开文件
fp = fopen("test.txt", "r");
// (2)检查文件是否成功打开
if (fp == NULL)
{
perror("fopen");
return -1;
}
// (3)读取文件中的每个字符
while ((c = fgetc(fp)) != EOF)
{
printf("%c", c);
}
// (4)关闭文件
fclose(fp);
return 0;
}
1.2、 fputc 函数
函数定义:
int fputc(int c, FILE* stream);
功能:
函数用于向指定的文件流中写入⼀个字符。
参数:
- c :要写入的字符,以整数形式给出。
- stream :指向 FILE 类型结构体的指针,指定了要写入字符的流。
返回值:
如果成功写入字符,则返回写入的字符,以无符号字符表⽰。如果发生错误,返回 EOF ,即 (-1)。
使用注意事项:
- 需要包含 <stdio.h> 头文件。
- 在使用 fputc() 之前,需要确保文件已经以可写方式打开。
- 文件指针会随着每次写入的调用而向前移动。
代码举例:
#include <stdio.h>
int main()
{
FILE *fp;
int c;
// (1)打开文件
fp = fopen("test.txt", "w");
// (2)检查文件是否成功打开
if (fp == NULL)
{
perror("fopen");
return -1;
}
// (3)写入字符到文件中
for (c = 'A'; c <= 'Z'; ++c)
{
if (fputc(c, fp) == EOF)
{
perror("Error writing to file");
return -1;
}
}
// (4)关闭文件
fclose(fp);
return 0;
}
2、以字符串形式读写文件
在进行文件操作的时候,我们需要向文件中写入⼀行字符
,从文件中读取⼀行字符
,这时就可以使用 fgets 和 fputs 来完成任务。
2.1、 fgets 函数
函数定义:
char* fgets(char* str, int n, FILE * stream);
功能:
函数用于从指定的文件流中读取⼀行文本,并将其存储为⼀个字符串。
参数:
- str :指向⼀个字符数组的指针,用于存储读取的文本内容。该数组必须⾜够大以容纳最大⻓度为 n-1 的字符串,因为函数会在末尾添加⼀个 \0 终止符。
- n :要读取的最大字符数,包括末尾的 \0 终止符。如果读取的行超过 n-1 个字符,则剩余的字符会被截断。
- stream :指向 FILE 类型结构体的指针,指定了要读取的文件流。
返回值:
char * :如果成功读取到⼀行文本,则返回 str 参数的值。如果到达文件末尾或者发生错误,则返回 NULL 。
使用注意事项:
- 需要包含 <stdio.h> 头文件。
- 在使用 fgets() 之前,需要确保文件已经以可读方式打开。
- 函数会将包括换行符在内的整行文本读取到 str 指向的缓冲区中,但会在末尾添加 \0 终止符。
- 如果⼀行文本的字符数不超过 n-1 ,则整行文本以及末尾的换行符都会被读取并存储。
- 如果⼀行文本的字符数超过 n-1 ,则前 n-1 个字符会被读取并存储,剩余字符会被截断。
- 如果文件中没有更多的行可读,则 fgets() 返回 NULL。
代码举例:
#include <stdio.h>
int main()
{
FILE *fp;
char buffer[255];
fp = fopen("test.txt", "r");
if (fp == NULL) {
perror("fopen");
return -1;
}
// 读取文件中的每⼀行并打印
while (fgets(buffer, 255, fp) != NULL) {
printf("%s", buffer);
}
fclose(fp);
return 0;
}
2.2、 fputs 函数
函数定义:
int fputs(const char *str, FILE *stream);
功能:
函数用于将⼀个字符串写入到指定的文件流中,直到遇到 \0 为止。
参数:
• str :要写入的字符串
• stream :指向 FILE 类型结构体的指针,指定了要写入字符串的文件流。
返回值:
int :如果成功写入字符串,则返回⾮负值(通常为 0)。如果发生错误,返回 EOF ,即 (-1) 。
使用注意事项:
- 需要包含 <stdio.h> 头文件。
- 在使用 fputs() 之前,需要确保文件已经以可写方式打开。
- fputs() 写入的字符串不会自动添加换行符,需要⼿动添加 \n 如果需要。
代码举例:
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("test.txt", "w");
if (fp == NULL) {
perror("Error opening file");
return -1;
}
// 写入字符串到文件中
if (fputs("Hello, world!", fp) == EOF) {
perror("fputs");
return -1;
}
fclose(fp);
return 0;
}
3、以数据块形式读写文件
3.1、 fwrite 函数
函数定义:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
函数用于将数据块写入文件流中,是以 2 进制的形式写入的。
参数:
- ptr :指向要写入的数据块的指针。
- size :要写入的每个数据项的大小(以字节为单位)。
- nmemb :要写入的数据项的数量。
- stream :指向 FILE 类型结构体的指针,指定了要写入数据的文件流。
返回值:
返回实际写入的数据项数量。如果发生错误,则返回值可能小于 nmemb 。
使用注意事项:
- 需要包含 <stdio.h> 头文件。
- 在使用 fwrite() 之前,需要确保文件已经以二进制可写方式打开。
- fwrite() 通常用于二进制数据的写入,如果写入文本数据,请谨慎处理换行符和编码等问题。
代码举例:
假设要将⼀组整数写入到文件"data.bin"中:
#include <stdio.h>
int main() {
FILE *fp;
int data[] = {1, 2, 3, 4, 5};
fp = fopen("data.bin", "wb");
if (fp == NULL) {
perror("fopen");
return -1;
}
// 将数据写入文件
if (fwrite(data, sizeof(int), 5, fp) != 5) {
perror("fwrite");
return -1;
}
fclose(fp);
pf = NULL;
return 0;
}
3.2、 fread 函数
函数定义:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
函数用于从文件中读取数据块,并将其存储到内存缓冲区中。
参数:
- ptr :指向内存区域的指针,用于存储从文件中读取的数据。
- size :要读取的每个数据块的大小(以字节为单位)。
- nmemb :要读取的数据块的数量。
- stream :指向 FILE 类型结构体的指针,指定了要从中读取数据的文件流。
返回值:
返回实际读取的数据块数量。
使用注意事项:
- 需要包含 <stdio.h> 头文件。
- 在使用 fread() 之前,需要确保文件已经以二进制可读方式打开。
- ptr 指向的内存区域必须⾜够大,以便存储指定数量和大小的数据块。
- 如果 fread() 成功读取了指定数量的数据块,则返回值等于 nmemb ;如果读取数量少于 nmemb ,则可能已经到达文件结尾或者发生了错误。
- 在二进制文件读取时, fread() 是常用的函数,但对于文本文件读取,通常使用 fgets() 或 fscanf() 。
代码举例:
假设有⼀个二进制文件"data.bin",包含⼀些整数数据,我们将使用 fread() 函数读取这些数据:
#include <stdio.h>
int main()
{
FILE *fp;
int data[5]; // 假设文件中包含 5 个整数数据
fp = fopen("data.bin", "rb");
if (fp == NULL) {
perror("fopen");
return -1;
}
// 从文件中读取整数数据块
size_t num_read = fread(data, sizeof(int), 5, fp);
// 检查读取是否成功
if (num_read != 5) {
if (feof(fp))
printf("Reached end of file\n");
else if (ferror(fp))
printf("Error reading file\n");
} else {
// 输出读取的数据
for (int i = 0; i < 5; i++) {
printf("Data[%d]: %d\n", i, data[i]);
}
}
fclose(fp);
return 0;
}
4、格式化读写文件
如果我们需要向文件中写入和读取的不仅仅是字符,而是有其他类型的文本数据
,那就得考虑 fscanf 函数和 fprintf 函数了。
4.1、 fscanf 函数
函数定义:
int fscanf(FILE *stream, const char *format, ...);
功能:
函数用于从指定流中读取格式化输入,并根据指定的格式化字符串将输入数据解析为相应的数据类型。
参数:
- stream :指向 FILE 类型结构体的指针,指定了要读取的文件流。
- format :格式化字符串,指定了要读取的输入数据的格式,类似于 scanf() 中的格式化字符串。
- … :可变数量的参数,根据 format 字符串中指定的格式,用于接收解析后的数据。
返回值:
int :返回成功读取和匹配的参数个数。如果达到文件结尾或者发生读取错误,则返回 EOF ,即(-1) 。
使用注意事项:
- 需要包含 <stdio.h> 头文件。
- 在使用 fscanf() 之前,需要确保文件已经以可读方式打开。
- format 字符串中可以包含各种格式标识符,如 %d (整数)、%f (浮点数)、%s (字符串)等。
- 与 scanf() 不同, fscanf() 是从指定的流中读取数据,可以是标准输入流,也可以是文件流。
代码举例:
假设有⼀个包含⼀些数据的文件"data.txt",内容如下:
John 25 1.7
Emily 23 1.6
zhangsan 28 2.1
代码如下:
#include <stdio.h>
int main() {
FILE *fp;
char name[20];
int age;
float height;
fp = fopen("data.txt", "r");
if (fp == NULL) {
perror("Error opening file");
return -1;
}
// 从文件中读取数据
while (fscanf(fp, "%s %d %f", name, &age, &height) != EOF) {
printf("Name: %s, Age: %d, Height: %.1f\n", name, age, height);
}
fclose(fp);
return 0;
}
4.2、 fprintf 函数
函数定义:
int fprintf(FILE *stream, const char *format, ...);
功能:
fprintf() 函数用于将格式化数据写入到指定的流中。
参数:
- stream :指向 FILE 类型结构体的指针,指定了要写入的流。
- format :格式化字符串,指定了要写入的输出数据的格式,类似于 printf() 中的格式化字符串。
- … :可变数量的参数,根据 format 字符串中指定的格式,用于提供要写入的数据。
返回值:
int :返回写入的字符数。如果发生错误,返回负值。
使用注意事项:
- 需要包含 <stdio.h> 头文件。
- 在使用 fprintf() 之前,需要确保文件已经以可写方式打开。
- format 字符串中可以包含各种格式标识符,如 %d (整数)、 %f (浮点数)、 %s (字符串)等。
- fprintf() 将输出写入到指定的件流中,可以是标准输出流,也可以是文件流。
代码举例:
#include <stdio.h>
int main()
{
FILE *fp;
int num1 = 10;
float num2 = 3.14;
char str[] = "Hello, world!";
fp = fopen("output.txt", "w");
if (fp == NULL) {
perror("Error opening file");
return -1;
}
// 将数据写入文件
fprintf(fp, "Integer: %d, Float: %.2f, String: %s\n", num1, num2, str);
fclose(fp);
return 0;
}
每日一更!
公众号、优快云等博客:小菜狗编程笔记
谢谢点赞关注哈!目前在飞书持续优化更新~
日更较慢有需要完整笔记请私我,C/C++/数据结构-算法/单片机51-STM32-GD32-ESP32/嵌入式/Linux操作系统/uboot/Linux内核-驱动-应用/硬件入门-PCB-layout/Python/后期小程序和机器学习!