云计算百科
云计算领域专业知识百科平台

Linux学习-应用软件编程(fread/fwrite,流定义相关接口)

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);

}

 

赞(0)
未经允许不得转载:网硕互联帮助中心 » Linux学习-应用软件编程(fread/fwrite,流定义相关接口)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!