嵌入式学习(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;
}