462 字
1 分钟
c06
文件的其他相关操作
读写指针控制
在C 语言中,文件的读写指针(文件位置指针)用于跟踪文件中的当前位置,决定了下一次读写操作的位置
FILE* fp;文件打开模式与初始指针位置
| 模式 | 描述 | 初始指针位置 |
|---|---|---|
| r | 只读 | 文件开头 |
| w | 只写(清空原内容) | 文件开头 |
| a | 追加 | 文件末尾 |
| r+ | 读写 | 文件开头 |
| w+ | 读写 (清空原内容) | 文件开头 |
| a+ | 读写(追加) | 文件末尾 |
文件指针定位置函数
设置文件位置;
int fseek(FILE *stream, long offset, int whence);whence 参数:
- SEEK_SET - 从文件开头开始
- SEEK_CUR - 从当前位置开始
- SEEK_END - 从文件末尾开始
实例:
#include <stdio.h>
int main() { FILE *fp = fopen("example.txt", "r+"); if (fp == NULL) { perror("文件打开失败"); return 1; }
// 移动到文件开头后第10个字节 fseek(fp, 10, SEEK_SET);
// 从当前位置向前移动5个字节 fseek(fp, 5, SEEK_CUR);
// 移动到文件末尾前20个字节 fseek(fp, -20, SEEK_END);
fclose(fp); return 0;}获取当前文件位置
long ftell(FILE *stream);实例:
#include <stdio.h>
int main() { FILE *fp = fopen("example.txt", "r"); if (fp == NULL) { perror("文件打开失败"); return 1; }
// 读取一些数据后获取当前位置 char buffer[100]; fread(buffer, 1, 50, fp);
long position = ftell(fp); printf("当前文件位置: %ld\n", position);
fclose(fp); return 0;}重置文件指针到开头
void rewind(FILE *stream);实例:
#include <stdio.h>
int main() { FILE *fp = fopen("example.txt", "r"); if (fp == NULL) { perror("文件打开失败"); return 1; } // 读取文件内容 char buffer[100]; fread(buffer, 1, 100, fp);
// 重置指针到开头,重新读取 rewind(fp); fread(buffer, 1, 100, fp);
fclose(fp); return 0;}结构体io和优化
当出现对于结构体的存储问题。我们可以使用 文件的二进制读写,来将结构体这一数据结构进行存储
有如下结构体
typedef struct _record{ char name[128] int age;} record;我们可以编写如下写入和读取的函数
// 写入文件sint writeRecord(FILE* fp){ record r = { 0 };
while(1) { printf("Please Input the age:\n"); scanf_s("%d", &r.age);
if(r.age == 0) { break; }
printf("Please Input the name:\n"); scanf_s("%s", &r.name, MAXLEN); fwrite(&r, sizeof(r), 1, fp); } return 0;}
// 读取文件int readRecord(FILE* fp){ while(!feof(fp)) { record r = { 0 }; int count = fread(&r, sizeof(r), 1, fp); if(count == 0) { break; } printf("age:%d, name:%s \n", r.age, r.name); } return 0;}直接将程序以二进制形式存储
有如下主程序 和如下输入
int main(void){ char* filePath = ".\\struct_bin.dat"; FILE* fp = NULL; errno_t err = fopen_s(&fp, filePath, "wb"); if(err != 0 || fp == NULL) { return -1; } writeRecord(fp);
fclose(fp);
fp = NULL; err = fopen_s(&fp, filePath, "rb"); if(err != 0 || fp == NULL) { return -1; }
readRecord(fp); fclose(fp); return 0;}18XiaoMing
17XiaoMei
19ZhangSan
0可以发现成功实现了程序的读写,但是通过观察生成的文件 struct_bin.dat 发现

文件中有大量的 00 空白区,分析发现是结构体中的 name 有128字节的空间,其中大量的字节没有使用造成的浪费 所以我们可以 尝试改变结构体的存储方式,改为 名字长度 + 名字 + 年龄 的形式 比如8XiaoMing18
所以修改读取文件为如下代码
int optwriteRecord(FILE* fp){ while(1) { record r = { 0 }; printf("Please Input the age:\n"); scanf_s("%d", &r.age); if(r.age == 0) { break; } printf("Please Input the age:\n"); scanf_s("%s", &r.name, MAXLEN);
size_t len = strlen(r.name); fwrite(&len, sizeof(len), 1, fp); fwrite(r.name, len, 1, fp); fwrite(&r.age, sizeof(r.age), 1, fp); } return 0;}
int optreadRecord(FILE* fp){ while(!feof(fp)) { record r = { 0 }; int len = 0;
int cnt = fread(&len, sizeof(len), 1, fp); if(cnt == 0) { break; } fread(r.name, len, 1, fp); fread(&r.age, sizeof(r.age), 1, fp);
printf("age:%d, name:%s \n", r.age, r.name); } return 0;}优化后的 struct_bin.dat 文件结构如图

明显发现占用空间减小
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐










