当前位置: 首页 > news >正文

Linux文件编程——标准库函数fopen、fread、fwrite等函数

1. fopen — 打开文件

函数原型:
FILE *fopen(const char *filename, const char *mode);
参数:
  • filename:要打开的文件名,可以是相对路径或绝对路径。

  • mode:文件打开模式,表示文件的操作方式(如只读、写入、追加等)。

常见的打开模式:
  • "r":只读模式,文件必须存在。

  • "w":只写模式,如果文件存在会清空文件,不存在则创建。

  • "a":追加模式,文件不存在则创建,写入时数据会追加到文件末尾。

  • "r+":读写模式,文件必须存在。

  • "w+":读写模式,文件存在则清空,不存在则创建。

  • "a+":读写模式,文件不存在则创建,数据追加到文件末尾。

返回值:
  • 如果成功,返回一个指向文件的指针(FILE *)。

  • 如果失败,返回 NULL,通常使用 perror()errno 获取错误信息。

示例:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {perror("无法打开文件");return 1;
}
注意事项:
  • fopen 只支持文本文件和二进制文件的打开,打开方式非常灵活,可以通过不同的模式选择合适的文件操作。

  • 打开文件后,应确保及时关闭文件,使用 fclose()

  • fopen 函数会自动创建文件指针,并为文件分配缓冲区。


2. fread — 从文件读取数据

函数原型:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
参数:
  • ptr:指向要存储读取数据的内存缓冲区。

  • size:每个元素的字节数(通常为 sizeof(type))。

  • count:要读取的元素数量。

  • stream:文件指针,表示要读取的文件。

返回值:
  • 返回实际读取的元素数量。如果返回值小于 count,表示可能发生了错误或到达了文件末尾(EOF)。

示例:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {perror("无法打开文件");return 1;
}char buffer[100];
size_t bytesRead = fread(buffer, sizeof(char), sizeof(buffer), fp);
if (bytesRead > 0) {printf("读取到的内容: %s\n", buffer);
}
fclose(fp);
注意事项:
  • fread 是基于缓冲区的读取,性能较高,适合读取大块数据。

  • 读取时要确保 ptr 的内存空间足够容纳读取的数据。

  • fread 适用于二进制数据的读取。如果是读取文本数据,最好使用 fgets

  • fread 读取时并不会自动添加字符串终止符 \0,如果读取的是字符串,需手动添加。


3. fwrite — 向文件写入数据

函数原型:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
参数:
  • ptr:指向要写入的数据的内存缓冲区。

  • size:每个元素的字节数(通常为 sizeof(type))。

  • count:要写入的元素数量。

  • stream:文件指针,表示要写入的文件。

返回值:
  • 返回实际写入的元素数量。如果返回值小于 count,表示可能发生了错误。

示例:
FILE *fp = fopen("output.txt", "w");
if (fp == NULL) {perror("无法打开文件");return 1;
}const char *data = "Hello, World!";
size_t bytesWritten = fwrite(data, sizeof(char), strlen(data), fp);
if (bytesWritten != strlen(data)) {perror("写入文件失败");
}
fclose(fp);
注意事项:
  • fwrite 会自动使用缓冲区,提高性能。

  • 使用 fwrite 时应确保数据类型和缓冲区大小正确。通常用于写入二进制数据。

  • fwrite 也不会在写入的数据末尾自动添加字符串结束符 \0,需根据实际需求手动处理。


4. fseek — 设置文件指针的位置

函数原型:
int fseek(FILE *stream, long int offset, int whence);
参数:
  • stream:文件指针。

  • offset:从 whence 指定的起始位置开始的偏移量。

  • whence:起始位置的标志,常用的值包括:

    • SEEK_SET:文件开头。

    • SEEK_CUR:当前位置。

    • SEEK_END:文件末尾。

返回值:
  • 成功时返回 0,失败时返回非零值。

示例:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {perror("无法打开文件");return 1;
}fseek(fp, 0, SEEK_END);  // 定位到文件末尾
long fileSize = ftell(fp);  // 获取文件大小
printf("文件大小: %ld 字节\n", fileSize);fseek(fp, 0, SEEK_SET);  // 重置文件指针到文件开头
fclose(fp);
注意事项:
  • fseek 可以改变文件指针的位置,在读取或写入时可以灵活地控制文件位置。

  • fseekftell 配合使用,能够实现文件大小的获取。

  • 使用时要注意文件是否已正确打开,并且文件指针的偏移量是否合理。


5. fclose — 关闭文件

函数原型:
int fclose(FILE *stream);
参数:
  • stream:要关闭的文件指针。

返回值:
  • 成功时返回 0,失败时返回 EOF。

示例:
FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {perror("无法打开文件");return 1;
}fclose(fp);  // 关闭文件
注意事项:
  • 必须关闭文件:每次打开文件后,使用完文件后必须调用 fclose() 关闭文件,释放资源。

  • fclose() 会刷新文件的缓冲区,如果有未写入的数据,会被强制写入文件。

  • 在程序结束时忘记关闭文件可能会导致内存泄漏或资源占用。


6. fputc — 向文件写入一个字符

函数原型:
int fputc(int character, FILE *stream);
参数:
  • character:要写入的字符。注意,这里传入的是一个整数类型(通常是 char 的 ASCII 值),而不是字符本身,因此需要使用字符类型转换。

  • stream:文件指针,指向目标文件。

返回值:
  • 如果写入成功,返回写入的字符(转换为 unsigned char)。

  • 如果写入失败,返回 EOF

示例:
#include <stdio.h>int main() {FILE *fp = fopen("example.txt", "w");if (fp == NULL) {perror("无法打开文件");return 1;}fputc('H', fp);  // 向文件中写入字符 'H'fputc('i', fp);  // 向文件中写入字符 'i'fclose(fp);  // 关闭文件return 0;
}
注意事项:
  • fputc 只能写入单个字符。写入多个字符时,需要多次调用 fputc

  • fputc 写入时不会自动添加换行符,必须手动写入(如 fputc('\n', fp))。

  • 如果写入过程中发生错误,fputc 返回 EOF,可以通过 perror 或检查文件指针的状态进行处理。


7. fgetc — 从文件读取一个字符

函数原型:
int fgetc(FILE *stream);
参数:
  • stream:文件指针,指向要读取的文件。

返回值:
  • 成功时,返回读取的字符(以 unsigned char 形式返回,但作为 int 类型)。

  • 如果读取到文件结束符(EOF),返回 EOF

  • 如果发生读取错误,也会返回 EOF

示例:
#include <stdio.h>int main() {FILE *fp = fopen("example.txt", "r");if (fp == NULL) {perror("无法打开文件");return 1;}int ch;while ((ch = fgetc(fp)) != EOF) {  // 逐个字符读取文件内容putchar(ch);  // 输出字符}fclose(fp);  // 关闭文件return 0;
}
注意事项:
  • fgetc 一次读取一个字符,适用于逐字符读取文件。

  • 在读取时,fgetc 会返回字符的 ASCII 值。如果遇到文件结束符(EOF),则停止读取。

  • 使用 fgetc 时要注意检查返回值,EOF 可能意味着文件结束或读取错误,因此应及时检查并处理。


8. feof — 检查是否到达文件末尾

函数原型:
int feof(FILE *stream);
参数:
  • stream:文件指针,指向要检查的文件。

返回值:
  • 如果文件指针已到达文件末尾,返回非零值(通常是 1)。

  • 如果文件指针尚未到达文件末尾,返回 0

示例:
#include <stdio.h>int main() {FILE *fp = fopen("example.txt", "r");if (fp == NULL) {perror("无法打开文件");return 1;}int ch;while ((ch = fgetc(fp)) != EOF) {putchar(ch);  // 输出字符}if (feof(fp)) {printf("\n已到达文件末尾。\n");}fclose(fp);  // 关闭文件return 0;
}
注意事项:
  • feof 在文件读取时用来检查是否已到达文件末尾,它不会主动读取文件内容,因此最好在文件读取后使用(如通过 fgetcfread 等函数)。

  • 不要在 fgetcfread 等读取函数调用前检查 feof,因为 feof 只能判断是否到达文件末尾,而不是预测读取是否成功。正确的做法是在读取失败或读取结束后再检查 feof

总结

  • fopen:用于打开文件,返回文件指针,可以设置文件的打开模式。

  • fread:用于从文件中读取数据,适用于读取二进制数据。

  • fwrite:用于将数据写入文件,适用于写入二进制数据。

  • fseek:用于设置文件指针的位置,可以在文件内部进行定位。

  • fclose:关闭文件,释放资源,确保数据写入完成。

  • fputc:用于写入单个字符,适合逐个字符地写入文件。如果要写入多个字符,可以多次调用 fputc,或者使用 fwrite

  • fgetc:用于读取单个字符。返回值是一个 int 类型,用于区分普通字符与 EOF(文件结束符)。

  • feof:用于检查文件是否已到达末尾,但不能在读取文件时直接判断文件是否结束。通常在文件读取结束后,检查 feof 是否为真,来判断是否到达文件末尾。

使用注意事项:

  1. 每次打开文件后,必须使用 fclose() 关闭文件,防止资源泄漏。

  2. freadfwrite 操作时不会自动添加字符串结束符 \0,需要手动处理。

  3. 对于文本文件,使用 fopenfreadfwrite 等标准库函数进行文件操作,适用于大多数应用场景;对于高效、底层的文件操作,可以使用 openreadwrite 等系统调用。

  4. 调用 fseek 时要确保文件指针在有效范围内。

  5. fgetc读取文件时,要根据返回值判断是否读取到文件结束。

  6. feof 仅用于检测文件末尾,而不是读取是否成功。建议在 fgetcfread 读取后检查 feof

http://www.xdnf.cn/news/427627.html

相关文章:

  • Confusion2(Python反序列化+JWT)
  • MySQL——八、SQL优化
  • 【deekseek】P2P通信路由过程
  • 测试报告--博客系统
  • --openssl-legacy-provider is not allowed in NODE_OPTIONS 报错的处理方式
  • 栈与乘积 / 栈
  • rk3576--- HDMI CEC唤醒
  • TCP核心机制
  • 机器学习第八讲:向量/矩阵 → 数据表格的数学表达,如Excel表格转数字阵列
  • 已情感分析入门学习大模型-初级篇
  • MCP-RAG 服务器:完整设置和使用指南
  • Java 集合与 MyBatis 动态 SQL 实战教程
  • 普通项目与 FreeRTOS 项目的异同
  • 【NLP 72、Prompt、Agent、MCP、function calling】
  • 全景系统监控利器:Glances 使用介绍与实战指南
  • 【数据结构】双向链表
  • 开发与AI融合的Windsurf编辑器
  • 屏幕与触摸调试
  • Retrofit vs Feign: 介绍、对比及示例
  • 关于 javax.validation.constraints的详细说明
  • Visual Studio 项目 .gitignore 文件指南
  • 如何界定合法收集数据?
  • 【C++】【设计模式】生产者-消费者模型
  • EDR与XDR如何选择适合您的网络安全解决方案
  • 自我奖励语言模型:突破人类反馈瓶颈
  • WebGIS开发面试题:前端篇(六)
  • 【递归、搜索与回溯】专题一:递归(二)
  • electron 基础知识
  • 软考软件评测师——计算机组成与体系结构(分级存储架构)
  • 当三维地理信息遇上气象预警:电网安全如何实现“先知先觉”?