fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能
按块从文件读取数据,从文件中读 nmemb 个、每个 size 字节的元素,存入 ptr 指向的内存。
参数
– ptr :存储读取数据的内存首地址(需提前分配足够空间,如定义数组、用 malloc 申请堆内存 )。
– size :单个元素的字节数(同 fwrite ,需和写入时的 size 一致,否则数据会错位 )。
– nmemb :希望读取的元素个数(尝试读 size * nmemb 字节,实际读多少看文件内容 )。
– stream :文件流指针(通过 fopen 打开,需以可读模式如 "r+" 等打开 )。
返回值
– 成功:返回实际读到的元素个数(等于 nmemb 表示读满;若文件末尾不够 nmemb 个元素,返回实际读到的数量 )。
– 文件末尾:返回 0 (可用来判断是否读完文件 )。
#include<stdio.h>
struct stu
{
int id;
char name[100];
int score;
};
int main(int argc,const char*argv[])
{
FILE*fp = fopen("./1.txt","r");
if(NULL == fp)
{
printf("fopen error\\n");
return -1;
}
struct stu s;
struct stu ss[10];
size_t cnt = fread(&s,sizeof(struct stu),1,fp);
printf("cnt = %ld\\n",cnt);
printf("%d %s %d\\n",s.id,s.name,s.score);
cnt = fread(ss,sizeof(struct stu),10,fp);
printf("cnt = %ld\\n",cnt);
for(int i = 0;i < cnt;i++)
{
printf("%d %s %d\\n",ss[i].id,ss[i].name,ss[i].score);
}
fclose(fp);
}
fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能
按块向文件写入数据,把 ptr 指向的内存数据,以「 size 字节/元素 、共 nmemb 个元素」的形式写入文件。
参数
– ptr :要写入数据的内存首地址(常搭配数组、结构体等,传递 &变量 或数组名)。
– size :单个元素的字节数(如 sizeof(int) 表示 int 类型占 4 字节)。
– nmemb :要写入的元素个数(需和 size 匹配,总写入字节 = size * nmemb )。
– stream :文件流指针(通过 fopen 打开文件获得,需确保以可写模式如 "wb" 、 "a+" 等打开 )。
返回值
– 成功:返回实际写入的元素个数(正常应等于 nmemb ;若磁盘满、权限不足等,可能小于)。
#include<stdio.h>
struct stu
{
int id;
char name[100];
int score;
};
int main(int argc,const char*argv[])
{
FILE*fp = fopen("./1.txt","w");
if(NULL == fp)
{
printf("fopen error\\n");
return -1;
}
struct stu ss[5] = {{1,"zahngsan",99},{2,"lisi",90},{3,"wangwu",98},{4,"maliu",67},{5,"wanger",100}};
size_t cnt = fwrite(ss,sizeof(struct stu),5,fp);
printf("cnt = %ld\\n",cnt);
fclose(fp);
}
bmp
#pragma pack(1)
//bmp文件相关信息
typedef struct tagBITMAPFILEHEADER {
short bfType; // 文件类型标志
int bfSize; // 文件大小,单位为字节
short bfReserved1; // 保留字节
short bfReserved2; // 保留字节
int bfOffBits; // 数据偏移量,即实际图像数据开始的位置
}Bmp_file_head_t;
//bmp图像信息
typedef struct tagBITMAPINFOHEADER {
int biSize; // BITMAPINFOHEADER的大小,单位为字节
int biWidth; // 位图的宽度,单位为像素
int biHeight; // 位图的高度,单位为像素
short biPlanes; // 目标设备的位平面数,必须为1
short biBitCount; // 每像素位数(颜色深度)
int biCompression; // 图像压缩类型
int biSizeImage; // 图像大小,单位为字节
int biXPelsPerMeter;// 水平分辨率,单位为像素/米
int biYPelsPerMeter;// 垂直分辨率,单位为像素/米
int biClrUsed; // 实际使用颜色数
int biClrImportant; // 重要颜色数
}Bmp_info_t;
#pragma pack()
int get_bmp_head_info(const char *bmpname, Bmp_file_head_t *pheadinfo, Bmp_info_t *pbmpinfo)
{
FILE *fp = fopen(bmpname, "r");
if (NULL == fp)
{
printf("fopen error\\n");
return -1;
}
fread(pheadinfo, sizeof(Bmp_file_head_t), 1, fp);
fread(pbmpinfo, sizeof(Bmp_info_t), 1, fp);
fclose(fp);
return 0;
}
int main(int argc, const char *argv[])
{
Bmp_file_head_t headinfo;
Bmp_info_t bmpinfo;
get_bmp_head_info("./3.bmp", &headinfo, &bmpinfo);
printf("sizeof(Bmp_file_head_t) = %ld\\n", sizeof(Bmp_file_head_t));
printf("sizeof(Bmp_info_t) = %ld\\n", sizeof(Bmp_info_t));
printf("biWidth = %d, biHeight = %d, biBitCount = %d\\n", bmpinfo.biWidth, bmpinfo.biHeight, bmpinfo.biBitCount);
return 0;
}
流定位相关接口
fseek
int fseek(FILE *stream, long offset, int whence);
功能
实现文件流的重新定位,用于调整文件内部指针的位置,决定后续读写操作从文件的哪个位置开始。
参数
– stream :需要进行定位操作的文件流指针,由 fopen 等函数打开文件后获得。
– offset :偏移量,用于指定相对于 whence 位置移动的字节数,可正(向后移动 )、可负(向前移动 ,但需注意不能越界 )。
– whence :定位的相对基准位置,有以下宏定义可选:
– SEEK_SET :以文件开头为基准进行偏移, offset 为相对于文件开头的偏移字节数。
– SEEK_CUR :以文件当前读写位置为基准进行偏移, offset 是相对于当前位置的偏移量。
– SEEK_END :以文件末尾为基准进行偏移, offset 常搭配负数,实现从末尾往前定位(如 fseek(stream, -10, SEEK_END) 表示定位到文件末尾向前 10 字节处 )。
返回值
– 成功:返回 当前偏移量。
– 失败:返回 -1 ,常见失败情况如偏移量导致越界(如 SEEK_SET 时 offset 为负数 )、文件流异常等。
rewind(fp) ==>fseek(fp,0,SEEK_SET)
ftell
long ftell(FILE *stream);
功能
获取文件流当前位置到文件开头的偏移量,即返回当前文件指针距离文件起始位置的字节数,可用于判断文件大小、辅助 fseek 定位等场景。
返回值
偏移量:byte
练习
#include<stdio.h>
#include<stdlib.h>
struct stu
{
int id;
char name[100];
int score;
};
int main(int argc,const char*argv[])
{
FILE*fp = fopen("./1.txt","w+");
if(NULL == fp)
{
printf("fopen error\\n");
return -1;
}
struct stu ss[5] = {{1,"zahngsan",99},{2,"lisi",90},{3,"wangwu",98},{4,"maliu",67},{5,"wanger",100}};
fwrite(ss,sizeof(struct stu),5,fp);
fseek(fp,0,SEEK_END);
long len = ftell(fp);
rewind(fp);
FILE*fp1 = fopen("./2.txt","w");
if(NULL == fp1)
{
printf("fopen error\\n");
return -1;
}
//空洞文件
fseek(fp1,len – 1,SEEK_SET);
int ret = fputc('\\0',fp1);
if(EOF == ret)
{
printf("磁盘空间不足\\n");
return -1;
}
fseek(fp1,0,SEEK_SET);
char *buff = malloc(len);
fread(buff,1,len,fp);
fwrite(buff,1,len,fp1);
free(buff);
fclose(fp);
fclose(fp1);
}
strtok
char *strtok(char *str, const char *delim);
功能
按分隔符截取字符串,从 str 中逐个提取由 delim 分隔的子串。首次调用需传入待分割的完整字符串 str ,后续调用传入 NULL 即可继续分割剩余部分(内部会维护静态指针记录位置 )。
参数
– str :
– 首次调用:传入待分割的原始字符串(会被函数修改,分割后原字符串会被分隔符替换为 \\0 ,用于标记子串结束 )。
– 后续调用:传入 NULL ,函数会基于内部静态指针,继续分割剩余未处理的部分。
– delim :
传入分隔符字符串(如 ",-" 表示逗号、减号都可作为分隔符 ),只要遇到 delim 中任意字符,就会停止当前子串截取。
返回值
– 成功:返回当前截取到的子串首地址(如分割 "a,b,c" ,首次返回 "a" 的地址,后续依次返回 "b" 、 "c" )。
– 失败/结束:返回 NULL (当没有可分割的子串时触发 )。
练习
实现一个单词查询软件: 用户从终端输入一个单词,查找该单词的意思并打印; 若用户输入".quit",则退出该软件。
#include<stdio.h>
#include <string.h>
int main(int argc,const char*argv[])
{
FILE*fp = fopen("./dict.txt","r");
if(NULL == fp)
{
printf("fopen error\\n");
return -1;
}
rewind(fp);
char s[1024];
printf("输入单词\\n");
scanf("%s",s);
char buff[1024] = {0};
if(0 == strcmp(".quit",s))
{
return 0;
}
char *p = fgets(buff,sizeof(buff),fp);
while(p != NULL)
{
char *b = strtok(buff," ");
if(0 == strcmp(b,s))
{
b = strtok(NULL,"\\r");
printf("%s%s\\n",s,b);
break;
}
p = fgets(buff,sizeof(buff),fp);
}
if(p == NULL)
{
printf("not find\\n");
return 0;
}
fclose(fp);
}
评论前必须登录!
注册