嵌入式学习(Day24)fread/fwrite - 指南

1、fgets补充:

fgets:

(1)从指定的已打开文件中读取最多一行数据(遇\n停止读取)

(2)fgets保留\n字符并在字符串末尾添加\0

(3)fgets最多读取size-1个字符,最后一个位置存放\0

gets:

(1)指定从终端设备读取数据

(2)gets会将终端读到的\n字符替换成\0

(3)gets是危险的,因为在读取时,没有大小的限制,可能造成内存越界

2、Linux系统默认打开的三个文件:

FILE *-->stdin 标准输入流  ----》标准输入设备:键盘

FILE *-->stdout 标准输出流 ---》标准输出设备:显示屏

FILE *-->stderr 标准出错流 ---》标准出错流(用于输出错误信息) 标准出错设备:显示器

3、size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

功能: 向文件中写入 nmemb 个大小是 size 的数据到文件中。

参数:

  • ptr:要写入的数据的首地址。
  • size:每个元素的字节数。
  • nmemb:要写入的元素个数。
  • stream:要写入的文件流指针。

返回值:

  • 成功:返回实际写入的元素个数。

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

功能: 从文件中读取 nmemb 个大小是 size 的元素。

参数:

  • ptr:存储读取到数据的首地址。
  • size:每个元素的大小。
  • nmemb:希望从文件中读取的元素个数。
  • stream:要读的文件流指针。

返回值:

  • 成功:实际读到的元素个数。
  • 读到文件末尾:0。

例:读取一个bmp文件头部,打印该bmp文件分辨率和像素深度

#include
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER
{
short bfType;          // 19778,必须是BM字符串,对应的十六进制为0x4d42,十进制为19778,否则不是bmp格式文件
int   bfsize;           // 文件大小 以字节为单位(2-5字节)
short bfReserved1;     // 保留,必须设置为0 (6-7字节)
short bfReserved2;     // 保留,必须设置为0 (8-9字节)
int   bfoffBits;        // 从文件头到像素数据的偏移  (10-13字节)
}Bmp_file_head_t;
typedef struct tagBITMAPINFOHEADER
{
int biSize;             // 此结构体的大小 (14-17字节)
int        biWidth;            // 图像的宽  (18-21字节)
int           biHeight;        // 图像的高  (22-25字节)
short  biPlanes;        // 表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1 (26-27字节)
short  biBitCount;      // 一像素所占的位数,一般为24   (28-29字节)
int    biCompression;   // 说明图象数据压缩的类型,0为不压缩。 (30-33字节)
int    biSizeImage;     // 像素数据所占大小, 这个值应该等于上面文件头结构中bfSize-bfOffBits (34-37字节)
int            biXPelsPerMeter; // 说明水平分辨率,用象素/米表示。一般为0 (38-41字节)
int           biYPelsPerMeter; // 说明垂直分辨率,用象素/米表示。一般为0 (42-45字节)
int    biClrUsed;       // 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。 (46-49字节)
int    biClrImportant;  // 说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。(50-53字节)
}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;
}

4、流定位相关接口

(1)int fseek(FILE *stream, long offset, int whence);

功能: 实现文件流重新定位。

参数:

  • stream:需要定位的文件流指针。
  • offset:偏移量。
  • whence:定位的相对位置:
    • SEEK_SET:从头进行偏移。
    • SEEK_CUR:从当前位置开始偏移。
    • SEEK_END:从文件末尾偏移。

返回值:

  • 成功:返回当前的偏移量。
  • 失败:-1

(2)long ftell(FILE *stream);

功能: 获取流的当前位置到文件开头的偏移量。

参数:

  • stream:文件流。

返回:

  • 偏移量(以字节为单位)。

(3)void rewind(FILE *stream);

功能: 流复位函数(复位到开头)。

                fseek(fp, 0, SEEK_SET);

例:模拟迅雷下载:

#include
#include
int main(int argc,const char *argv[])
{
if(argc  ");
return -1;
}
FILE *fpsrc = fopen(argv[1],"r");
if(NULL ==fpsrc)
{
printf("fopen error\n");
return -1;
}
//获取源文件大小
fseek(fpsrc,0,SEEK_END);
long len = ftell(fpsrc);
rewind(fpsrc);
//抢占目标文件磁盘空间
FILE *fpdst = fopen(argv[2],"w");
if(NULL == fpdst)
{
printf("fopen error\n");
return -1;
}
fseek(fpdst,len - 1,SEEK_SET);
int ret = fputc('\0',fpdst);
if(EOF == ret)
{
printf("磁盘空间不足\n");
fclose(fpsrc);
fclose(fpdst);
return -1;
}
rewind(fpdst);//复位
//数据拷贝
char *buff = malloc(len);
fread(buff,len,1,fpsrc);
fwrite(buff,len,1,fpdst);
free(buff);
fclose(fpsrc);
fclose(fpdst);
/*
//3、数据拷贝
char buff[1024] = {0};
while (1)
{
size_t cnt = fread(buff, 1, sizeof(buff), fpsrc);
if (0 == cnt)
{
break;
}
fwrite(buff, 1, cnt, fpdst);
}
fclose(fpsrc);
fclose(fpdst); */
return 0;
}

posted @ 2025-08-12 09:27  yjbjingcha  阅读(7)  评论(0)    收藏  举报