C知识扫盲------文件的基本操作

1.文件的打开 (fopen)

1.1 基本介绍

在C语言中,所有的文件操作都是通过文件指针 (FILE *) 来进行的。要对文件进行操作,首先需要用 fopen 函数打开文件 ,并指定文件的路径和操作模式

c 复制代码
FILE* fopen(const char *filename, const char *mode);
  • filename : 要打开的文件名(可以包含路径,如 "C:\data\file.txt" 或者 "./file.txt")。
  • mode : 文件打开模式,决定了你如何访问文件。

1.2 mode:文件打开模式

r 以只读模式打开文件。如果文件不存在,则返回 NULL。
a 以追加模式打开文件。如果文件不存在,则创建新文件;如果文件存在,则将数据写入到文件的末尾。
w 以写入模式打开文件。如果文件不存在,则创建新文件;如果文件存在,则清空文件内容。
r+ 以读写模式打开文件。文件必须存在,不会创建新文件。
w+ 以读写模式打开文件。如果文件不存在,则创建新文件;如果文件存在,则清空文件内容。
a+ 以读写模式打开文件。如果文件不存在,则创建新文件;如果文件存在,将写入的数据添加到文件末尾。

注意

  • "r+" 可以进行读写操作,但不会创建新文件。
  • "w+" 会创建新文件或清空已有文件,然后进行读写操作。
  • "a+" 不会清空文件,可以在文件末尾添加数据,同时可以读取文件内容。

1.3 示例代码

c 复制代码
FILE* fp = fopen("example.txt", "r");
if (fp == NULL) 
{
    perror("打开文件错误");
    return -1;
}

fopen : 尝试以只读模式打开 "example.txt" 文件。

如果文件不存在或无法打开,fopen 返回 NULL,并打印错误信息。

1.4 错误处理

在打开文件时,建议立即检查返回值,以确保文件成功打开。

c 复制代码
if (fp == NULL) 
{
    perror("打开文件错误");
    return -1;
}

perror : 打印描述错误原因的消息,常用在 fopen、fread 等文件操作函数失败的情况下。

2. 文件的读取

读取文件内容有多种方式,可以根据文件内容的格式选择适合的方法。

2.1 使用 fscanf 读取格式化数据

fscanf 函数用于从文件中读取格式化数据 ,类似于 scanf,只是它从文件读取而非标准输入

c 复制代码
int fscanf(FILE *stream, const char *format, ...);
  • stream: 文件指针(即 fopen 返回的 FILE*)。
  • format : 格式字符串,用于指定要读取的数据类型

示例:

c 复制代码
int age;
double salary;
fscanf(fp, "%d %lf", &age, &salary);

上述代码将从文件中读取一个整数和一个浮点数,并分别存储到 age 和 salary 变量中。

2.2 使用 fgets 读取一行文本

fgets 函数用于从文件中读取一行文本。 它读取到换行符或到达最大长度,或到文件末尾为止。

c 复制代码
char* fgets(char *str, int n, FILE *stream);
  • str: 用于存储读取的字符串的字符数组。
  • n: 最大读取字符数(包括终止符 \0)。
  • stream: 文件指针。

示例:

c 复制代码
char buffer[100];
if (fgets(buffer, 100, fp) != NULL) 
{
    printf("读入: %s", buffer);
}

该代码会读取文件中的一行内容,并将其存储在 buffer 中。

2.3 使用 fread 读取二进制数据

fread 用于从文件中读取二进制数据。它一次性读取多个元素,并将其存储在内存中。

c 复制代码
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
  • ptr: 指向内存缓冲区的指针,用于存储读取的数据。
  • size: 每个元素的大小(以字节为单位)。
  • count: 要读取的元素数量。
  • stream: 文件指针。

示例

c 复制代码
char data[20];
size_t bytesRead = fread(data, sizeof(char), 20, fp);
if (bytesRead < 20) 
{
    if (feof(fp)) 
    {
        printf("已到达文件末尾。\n");
    } 
    else if (ferror(fp)) 
    {
        printf("在到达文件末尾之前发生错误。\n");
    }
}

上述代码从文件中读取20个字节的数据到 data 数组中。之后会检查是否达到文件末尾读取过程中是否出现错误

2.4 检查文件结束 (feof)

feof 函数用于检查是否到达了文件的末尾

c 复制代码
int feof(FILE *stream);
  • stream : 文件指针。
    返回值为非零值表示文件已到达末尾。

3. 文件的写入

与读取类似,写入文件也有多种方式,根据数据的格式选择合适的方法。

3.1 使用 fprintf 写入格式化数据

fprintf 用于将格式化数据写入文件 ,类似于 printf,但它输出到文件而不是标准输出。

c 复制代码
int fprintf(FILE *stream, const char *format, ...);
  • stream: 文件指针。
  • format: 格式字符串,类似 printf 的格式控制。

示例:

c 复制代码
int age = 30;
double salary = 50000.75;
fprintf(fp, "Age: %d, Salary: %.2f\n", age, salary);

该代码将 age 和 salary 以格式化的方式写入文件。

3.2 使用 fputs 写入字符串

fputs 函数将字符串写入文件,不包含终止符 \0。

c 复制代码
int fputs(const char *str, FILE *stream);
  • str: 要写入的字符串。
  • stream: 文件指针。

示例:

c 复制代码
fputs("Hello, World!\n", fp);

该代码将 "Hello, World!" 写入文件。

3.3 使用 fwrite 写入二进制数据

fwrite 函数用于将二进制数据写入文件。

c 复制代码
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
  • ptr: 指向要写入的内存区域。
  • size: 每个元素的大小(以字节为单位)。
  • count: 要写入的元素数量。
  • stream: 文件指针。

示例:

c 复制代码
char data[20] = "example data";
fwrite(data, sizeof(char), strlen(data), fp);

该代码将字符串 "example data" 写入文件(不包括终止符 \0)。

4. 关闭文件 (fclose)

文件操作完成后,必须使用 fclose 关闭文件,以确保数据正确写入并释放资源。

c 复制代码
int fclose(FILE *stream);
  • stream: 文件指针。

示例:

c 复制代码
fclose(fp);

该代码关闭之前打开的文件。

5. 错误处理

文件操作过程中可能会遇到各种错误,常见的错误处理方式包括检查 fopen、fread、fwrite、fprintf 等函数的返回值

5.1 fopen 错误处理

fopen 如果无法打开文件,返回 NULL。 可以使用 perror 打印错误原因。

c 复制代码
FILE* fp = fopen("example.txt", "r");
if (fp == NULL) 
{
    perror("打开文件错误");
    return -1;
}

5.2 fread 和 fwrite 错误处理

检查 fread 和 fwrite 的返回值以确认是否读取/写入了预期数量的数据。

c 复制代码
size_t bytesRead = fread(buffer, sizeof(char), size, fp);
if (bytesRead < size) 
{
    if (feof(fp)) 
    {
        printf("已到文件末尾\n");
    } 
    else if (ferror(fp)) 
    {
        perror("读取文件错误\n");
    }
}

6. 文件指针操作 (fseek, ftell, rewind)

文件指针表示当前文件中的读写位置 ,通过操作文件指针可以定位到文件的任意位置。

6.1 fseek 函数

fseek 用于移动文件指针到指定的位置。

c 复制代码
int fseek(FILE *stream, long int offset, int origin);
  • offset: 偏移量,以字节为单位。
  • origin: 起始位置:
  • SEEK_SET: 从文件开头算起。
  • SEEK_CUR: 从当前指针位置算起。
  • SEEK_END: 从文件末尾算起。

示例:

c 复制代码
fseek(fp, 0, SEEK_SET); // 移动到文件开头
fseek(fp, 0, SEEK_END); // 移动到文件末尾
fseek(fp, 10, SEEK_CUR); // 从当前位置前移10字节

6.2 ftell 函数

ftell 返回当前文件指针的位置(相对于文件开头的字节偏移量)。

c 复制代码
long int ftell(FILE *stream);

示例:

c 复制代码
long int position = ftell(fp);
printf("当前位置: %ld\n", position);

6.3 rewind 函数

rewind 将文件指针重置到文件开头 ,功能类似 fseek(fp, 0, SEEK_SET),但 rewind 还会清除文件的错误标志(如果有的话)。

c 复制代码
void rewind(FILE *stream);

示例:

c 复制代码
rewind(fp); // 重置文件指针到文件开头

7. 文件缓冲区管理 (fflush)

fflush 函数用于刷新文件流的输出缓冲区,确保所有缓冲区的数据都写入到文件中。

c 复制代码
int fflush(FILE *stream);
  • stream: 文件指针。如果 stream 为 NULL,则刷新所有打开的输出流。

示例:

c 复制代码
fflush(fp);

fflush 通常用于在程序结束前或希望立即写入数据时,确保所有数据都写入文件。

8. 文件状态和错误检查 (ferror, clearerr)

8.1 ferror 函数

ferror 用于检查文件流是否发生了错误

c 复制代码
int ferror(FILE *stream);
  • stream: 文件指针。

如果发生错误,返回一个非零值。

示例

c 复制代码
if (ferror(fp)) 
{
    printf("文件出现错误\n");
}

8.2 clearerr 函数

clearerr 用于清除文件流中的错误和 EOF 状态。

c 复制代码
void clearerr(FILE *stream);

示例:

c 复制代码
clearerr(fp);

clearerr 通常在处理错误后调用,以便重新尝试文件操作。

相关推荐
罗伯特祥1 小时前
C调用gnuplot绘图的方法
c语言·plot
嵌入式科普2 小时前
嵌入式科普(24)从SPI和CAN通信重新理解“全双工”
c语言·stm32·can·spi·全双工·ra6m5
lqqjuly3 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++
2401_858286114 小时前
115.【C语言】数据结构之排序(希尔排序)
c语言·开发语言·数据结构·算法·排序算法
2401_858286115 小时前
109.【C语言】数据结构之求二叉树的高度
c语言·开发语言·数据结构·算法
KevinRay_6 小时前
Linux系统编程深度解析:C语言实战指南
linux·c语言·mfc·gdb
灵槐梦6 小时前
【速成51单片机】2.点亮LED
c语言·开发语言·经验分享·笔记·单片机·51单片机
LittleStone83977 小时前
C语言实现旋转一个HWC的图像
c语言
stm 学习ing9 小时前
HDLBits训练5
c语言·fpga开发·fpga·eda·hdlbits·pld·hdl语言
就爱学编程10 小时前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法