FILE文件流的中fopen、fread、fseek、fclose的使用

本文详细介绍了文件流操作的四个关键函数:fopen、fread、fseek、fclose的功能、参数和使用注意事项。通过实例展示了如何使用这些函数从文件中快速获取所需数据。

原文链接:http://www.cnblogs.com/Romi/archive/2012/02/29/2374769.html

FILE文件流用于对文件的快速操作,主要的操作函数有fopen、fseek、fread、fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满足编程中的需要。以下分别进行说明,还有他们使用时的注意事项

fopen

函数原型    FILE * fopen(const char *path,cost char *mode)

作用:打开一个文件,返回指向该文件的指针

参数说明:第一个参数为欲打开文件的文件路径及文件名,第二个参数表示对文件的打开方式

注:mode有以下值:

r:只读方式打开,文件必须存在

r+:可读写,必须存在

rb+:打开二进制文件,可以读写

rt+:打开文本文件,可读写

w:只写,文件存在则文件长度清0,文件不存在则建立该文件

w+:可读写,文件存在则文件长度清0,文件不存在则建立该文件

a:附加方式打开只写,不存在建立该文件,存在写入的数据加到文件尾,EOF符保留

a+:附加方式打开可读写,不存在建立该文件,存在写入的数据加到文件尾,EOF符不保留

wb:打开二进制文件,只写

wb+:打开或建立二进制文件,可读写

wt+:打开或建立文本文件,可读写

at+:打开文本文件,可读写,写的数据加在文本末尾

ab+:打开二进制文件,可读写,写的数据加在文件末尾

由mode字符可知,上述如r、w、a在其后都可以加一个b,表示以二进制形式打开文件

返回值:文件打开了,返回一个指向该打开文件的指针(FILE结构);文件打开失败,错误上存error code(错误代码)

注意:在fopen操作后要进行判断,是否文件打开,文件真正打开了才能进行后面的读或写操作,如有错误要进行错误处理

例:FILE *pfile=fopen(const char *filename,"rb");

打开文件流还有一个支持宽字符的函数,如下

FILE *_wfopen(const wchar_t *filename,const wchar_t *mode)

fread

函数原型:size_t fread(void* buff,size_t size,size_t count,FILE* stream)

作用:从文件中读入数据到指定的地址中

参数:第一个参数为接收数据的指针(buff),也即数据存储的地址

第二个参数为单个元素的大小,即由指针写入地址的数据大小,注意单位是字节

第三个参数为元素个数,即要读取的数据大小为size的元素个素

第四个参数为提供数据的文件指针,该指针指向文件内部数据

返回值:读取的总数据元素个数

例:

int  num,count;

int* pr=new int[num*count];

fread(pr, num*4, count, stream);   // stream为fopen中返回的FILE指针

要将数据写入pr中,必须为pr分配内存,一个int为4个字节,所以要x4

fseek

函数原型:int fseek(FILE *stream,long offset,int framewhere)

作用:重定位文件内部的指针

参数:第一个为文件指针,第二个是指针的偏移量,第三个是指针偏移起始位置

返回值:重定位成功返回0,否则返回非零值

需要注意的是该函数不是重定位文件指针,而是重定位文件内部的指针,让指向文件内部数据的指针移到文件中我们感兴趣的数据上,重定位主要是这个目的

说明:执行成功,则stream指向以fromwhere为基准,偏移offset个字节的位置。执行失败(比方说offset偏移的位置超出了文件大小),则保留原来stream的位置不变

fclose

函数原型:int fclose(FILE *stream)

功能:关闭一个文件流,使用fclose就可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区

熟练使用以上四个函数可以从文件中获取对我们有用的数据型,前提对于文件格式很了解,比如,对于一个DIB位图文件,就可以读取出他的文件中的头信息和像素点信息。

在C语言中,`fopen`、`fseek`、`ftell` 和 `fread` 是标准库 `<stdio.h>` 中用于文件操作的重要函数。它们通常组合使用来读取整个文件或文件的特定部分。下面详细说明这些函数的作用、用法,并给出一个完整的示例程序来演示如何读取文件内容。 --- ### 1. 函数说明 #### ✅ `FILE *fopen(const char *filename, const char *mode)` - **功能**:打开一个文件。 - **参数**: - `filename`:文件路径(字符串)。 - `mode`:打开模式,如 `"r"`(只读文本)、`"rb"`(只读二进制)等。 - **返回值**:成功返回指向 `FILE` 的指针;失败返回 `NULL`。 常用模式: - `"r"`:以文本方式读取。 - `"rb"`:以二进制方式读取(推荐用于任意文件,避免换行符转换问题)。 - `"w"`:写入(会清空原文件)。 - `"a"`:追加。 > 对于读取任意类型文件(包括图片、音频等),建议使用 `"rb"` 模式。 --- #### ✅ `int fseek(FILE *stream, long offset, int whence)` - **功能**:设置文件指针的位置。 - **参数**: - `stream`:文件指针。 - `offset`:偏移量(字节数)。 - `whence`:起始位置,可选: - `SEEK_SET`:从文件开头开始。 - `SEEK_CUR`:从当前位置开始。 - `SEEK_END`:从文件末尾开始。 - **返回值**:成功返回0,失败返回非零。 常用来将文件指针移到末尾以获取文件大小。 --- #### ✅ `long ftell(FILE *stream)` - **功能**:返回当前文件指针相对于文件开头的偏移(字节数)。 - **参数**:`stream` 文件指针。 - **返回值**:当前位置(字节),若出错返回 `-1L`。 常与 `fseek` 配合使用计算文件大小。 --- #### ✅ `size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)` - **功能**:从文件中读取数据块。 - **参数**: - `ptr`:指向存储数据的缓冲区(内存地址)。 - `size`:每个元素的大小(字节)。 - `nmemb`:要读取的元素个数。 - `stream`:文件指针。 - **返回值**:实际读取的元素个数(可能小于 `nmemb`)。 例如:`fread(buf, 1, 1024, fp)` 表示最多读取1024个字节,每次1字节。 --- ### ✅ 完整示例:使用 `fopen`, `fseek`, `ftell`, `fread` 读取整个文件到内存 ```c #include <stdio.h> #include <stdlib.h> #include <errno.h> int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "用法: %s <文件名>\n", argv[0]); return 1; } const char *filename = argv[1]; FILE *fp = fopen(filename, "rb"); // 以二进制方式打开 if (fp == NULL) { perror("fopen 失败"); return 1; } // 将文件指针移动到末尾 if (fseek(fp, 0, SEEK_END) != 0) { perror("fseek 失败"); fclose(fp); return 1; } // 获取当前偏移(即文件大小) long file_size = ftell(fp); if (file_size == -1L) { perror("ftell 失败"); fclose(fp); return 1; } // 回到文件开头 if (fseek(fp, 0, SEEK_SET) != 0) { perror("回到文件开头失败"); fclose(fp); return 1; } // 分配足够内存存储文件内容 char *buffer = (char *)malloc(file_size + 1); // +1 用于添加结束符(如果是文本) if (buffer == NULL) { fprintf(stderr, "内存分配失败\n"); fclose(fp); return 1; } // 读取文件内容 size_t read_size = fread(buffer, 1, file_size, fp); if (read_size != file_size) { if (ferror(fp)) { perror("fread 读取出错"); } else { fprintf(stderr, "警告: 只读取了 %zu 字节,期望 %ld 字节\n", read_size, file_size); } } // 关闭文件 fclose(fp); // (可选)如果是文本文件,添加字符串结束符 buffer[file_size] = '\0'; // 输出前100字符作为示例(防止输出太长) printf("文件前100字符:\n%.100s%s\n", buffer, file_size > 100 ? "...\n(内容被截断)" : ""); // 释放内存 free(buffer); return 0; } ``` --- ### 🔍 上述代码解释: 1. **命令行参数检查**:确保用户输入了文件名。 2. **`fopen("rb")`**:以二进制方式打开文件,适用于所有类型文件。 3. **`fseek(fp, 0, SEEK_END)` + `ftell()`**:获取文件总大小。 4. **`fseek(fp, 0, SEEK_SET)`**:重置文件指针到开头,准备读取。 5. **动态分配内存**:根据文件大小分配缓冲区。 6. **`fread`**:一次性读取全部内容。 7. **错误处理**:对 `fopen`、`fseek`、`ftell`、`fread`、`malloc` 均做了健壮性判断。 8. **安全添加 `\0`**:如果处理的是文本文件,方便打印。 9. **资源释放**:关闭文件并释放内存。 --- ### ⚠️ 注意事项 - 使用 `fseek` 和 `ftell` 计算大文件(>2GB)时,`long` 类型可能溢出。在某些系统上应使用 `fseeko` / `ftello` 配合 `off_t`。 - 文本模式下(如 `"r"`),Windows 会自动转换 `\r\n` 为 `\n`,可能导致 `ftell` 返回值不准确。因此推荐始终使用 `"rb"` 二进制模式进行精确读取。 - 不要忘记 `fclose(fp)` 和 `free(buffer)`,否则会造成资源泄漏。 --- ### ✅ 编译和运行示例 ```bash gcc -o readfile readfile.c ./readfile example.txt ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值