c语言中double sper是什么意思啊,C语言的文件操作的使用

知识点回顾

变量、数组、结构体都是存储数据的方式

结构体是一种变量的模板,相对于变量、它可以存储多项数据,相对于数组,结构体中成员的数据类型可以不同。

#include

#include

struct staff

{

char FullName[64];//一个汉字占用两个字节

char Gender;//字符型变量可以存储整数 1--男 2--女 char类型范围:-127~128

char ID[18];

};

/*

除了使用(struct 结构体名 变量名)这种方式声明结构体变量以外,

还可以使用typedef语句来基于结构体声明数据类型

这个语句的作用就是将结构体 Staff 定义为新的数据类型 STAFF

*/

typedef struct staff STAFF;

int main()

{

//定义完结构体后,就可以基于结构体 声明结构体变量

STAFF s;

//struct staff s;

s.Gender = 1; //为结构体成员变量赋值

scanf("%s", s.FullName);

printf("%s\r\n", s.FullName);

return 0;

}

通过结构体将多个不同类型的数据结构成员整合在一起,可以方便的多项数据进项操作。

文件操作

在C语言中之前使用过的变量、数组都是存储在内存(RAM)中的,这些数据所占用的内存在程序结束以后会被操作系统回收,内存中的数也就会随之丢失。因此我们就需要将数据保存到外部存储器上(通常指硬盘),方便其下次使用。

在一些较为底层的语言里,你可以直接访问硬盘的某个扇区并进行数读写,但这种返回时除了效率比较低外还存在较大的安全隐患,不恰当的磁盘访问可能会引起严重的故障,比如操作系统崩溃或数丢失。所以这种方式是不推荐的。

因此我们就需要通过文件来访问磁盘上的数据,文件系统由操作系统管理,程序员通过这种操作系统可以间接地访问磁盘上地数据,不恰当地访问就可能会被操作系统阻止(例如文件被其它程序占用、或者程序没有访问这个文件的权限),这样一来就会安全得多,同时操作系统也会采取一些机制来提高文件的访问效率。

使用fopen()函数

fopen()函数可以打开或创建文件,想要将数据存储到磁盘上,首先我们就需要在磁盘上创建一个文件;如果这个文件已经创建,那么我们就需要打开它即可(可以直接打开,也可以进行覆盖,具体操作取决于你打开文件的方式)。在C语言中创建和打开文件都使用一个函数,fopen()函数,该函数的原型为:

FILE* fopen(const char* filename, const char* mode);

/*

该函数的2个参数都是字符串常量

参数1:要打开或创建文件的具体路径

参数2:打开或创建文件的具体方式

*/

使用fwrite()函数将读取到对应货币的数据写入到指定路径的文件中:

#include

#include

#pragma comment(lib, "D:/CR37/Data/libs/BOCRates/BOCRates.lib")

int main()

{

ExchangeRate r; //定义一个结构体变量

//使用ReadBOCRatesByCode函数读取指定货币对应的值到 &r 所指向的结构体中

ReadBOCRatesByCode("USD", &r);

//以二进制形式打开或创建指定路径下的Rates.txt文件

FILE* fp = fopen("D:\\CR37\\Data\\Rates.txt", "wb");

//做判断

if (fp == NULL)

{

printf("文件打开失败!\r\n");

}

else

{

printf("文件打开成功,文件的信息存储在一个结构体中,指针fp指向了这个结构体\r\n");

//将内存中&r地址中的数据值 读取sizeof(ExchangeRate)大小的字节 保存到fp指向的文件内

fwrite(&r, sizeof(ExchangeRate), 1, fp);

//使用后要记得关闭文件

fclose(fp);

}

return 0;

}

20200319144905085851.png

使用fread()函数将指定路径的文件中的数据读出来:

#include

#include

#pragma comment(lib, "D:/CR37/Data/libs/BOCRates/BOCRates.lib")

int main()

{

//定义一个结构体变量

ExchangeRate r;

//以只读的方式打开对应路径下的文件

FILE* fp = fopen("D:\\CR37\\Data\\Rates.txt", "r");

//从fp 指向的位置 读取sizeof(ExchangeRate)字节的数据 送到&r所指向的位置

fread(&r, sizeof(ExchangeRate), 1, fp);

//打印对应的值

printf("%s\t", r.CurrencyCode);

printf("%s\t", r.CurrencyName);

printf("%s\t", r.PublishTime);

printf("%f\t", r.BuyingRate);

printf("%f\t", r.SellingRate);

printf("%f\t", r.CashBuyingRate);

printf("%f\t", r.CashSellingRate);

printf("%f\t\n", r.MiddleRate);

fclose(fp);

return 0;

}

程序运行的结果:

20200319144905565361.png

通过自定义函数实现和main()中相同的功能

避免main()函数中的语句过于繁琐,更具有模块化,以及程序的可修改性,所以我们需要进行自定义函数,实现文件写入和读取操作等功能:

1、写入(保存)函数:int SaveRates(ExchangeRate r);

2、读取函数:void LoadRatesFromFile(ExchangeRate* r);

3、显示数据:void DisplayRates(ExchangeRate r);

Visual 1:

#include

#include

#pragma comment(lib, "D:/CR37/Data/libs/BOCRates/BOCRates.lib")

/*

在联网的基础上将从API上读取指定货币的数据保存到磁盘上

在保存数据时,只需要将结构体变量的值传递进去就可以了,此时无需使用指针

*/

int SaveRates(ExchangeRate r)

{

FILE* fp = fopen("D:\\CR37\\Data\\Rates.txt", "wb");

if (fp == NULL)

{

printf("文件打开失败!\r\n");

return -1;

}

else

{

printf("文件打开成功!文件的信息存储在一个结构体中,指针指向了这个结构体\r\n");

fwrite(&r, sizeof(ExchangeRate), 1, fp);

fclose(fp);

return 0;

}

}

/*

这里传递结构体变量指针是因为要从磁盘中读取已保存的数据

*/

void LoadRatesFromFile(ExchangeRate* r)

{

FILE* fp = fopen("D:\\CR37\\Data\\Rates.txt", "r");

fread(r, sizeof(ExchangeRate), 1, fp);

fclose(fp);

}

//输出结构体成员对应的数值

void DispalyRates(ExchangeRate r)

{

printf("%s\t", r.CurrencyCode);

printf("%s\t", r.CurrencyName);

printf("%s\t", r.PublishTime);

printf("%f\t", r.BuyingRate);

printf("%f\t", r.SellingRate);

printf("%f\t", r.CashBuyingRate);

printf("%f\t", r.CashSellingRate);

printf("%f\t\n", r.MiddleRate);

}

int main()

{

//声明一个结构体变量

ExchangeRate r;

//调用ReadBOCRatesCode()函数,获取指定货币的数据

ReadBOCRatesByCode("JPY", &r);

//将其获取指定货币的数据保存到指定路径的文件内

SaveRates(r);

//调用LoadRatesFromFile()函数将指定路径的文件内的数据读取出来到对应的结构体成员中

LoadRatesFromFile(&r);

//调用DispalyRates()函数,打印对应的结构体成员的数值

DispalyRates(r);

return 0;

}

Visual 2:

#include

#include

#pragma comment(lib, "D:/CR37/Data/libs/BOCRates/BOCRates.lib")

/*

在联网的基础上将从API上读取指定货币的数据保存到磁盘上

在保存数据时,只需要将结构体变量的值传递进去就可以了,此时无需使用指针

*/

int SaveRates(ExchangeRate r)

{

FILE* fp = fopen("D:\\CR37\\Data\\Rates.txt", "wb");

if (fp == NULL)

{

printf("文件打开失败!\r\n");

return -1;

}

else

{

printf("文件打开成功!文件的信息存储在一个结构体中,指针指向了这个结构体\r\n");

fwrite(&r, sizeof(ExchangeRate), 1, fp);

fclose(fp);

return 0;

}

}

/*

这里传递结构体变量指针是因为要从磁盘中读取已保存的数据

*/

void LoadRatesFromFile(ExchangeRate* r)

{

FILE* fp = fopen("D:\\CR37\\Data\\Rates.txt", "r");

fread(r, sizeof(ExchangeRate), 1, fp);

fclose(fp);

printf("\r\n");

}

//输出结构体成员对应的数值

void DispalyRates(ExchangeRate r)

{

printf("%s\t", r.CurrencyCode);

printf("%s\t", r.CurrencyName);

printf("%s\t", r.PublishTime);

printf("%f\t", r.BuyingRate);

printf("%f\t", r.SellingRate);

printf("%f\t", r.CashBuyingRate);

printf("%f\t", r.CashSellingRate);

printf("%f\t\r\n", r.MiddleRate);

}

int main()

{

//声明一个结构体变量

ExchangeRate rates;

if (ReadBOCRatesByCode("JPY", &rates) == 1)

{

//条件为真,将读取到的对应数值保存到指定路径文件内

SaveRates(rates);

}

else

{

//如果上面的条件失败,就把本地保存的数读取出来

LoadRatesFromFile(&rates);

}

DispalyRates(rates);

return 0;

}

程序运行结果:

20200319144905989206.png

使用文件操作打印BMP格式的图片

说明

现在使用的图片主要为位图和矢量图:

矢量图形:是计算机图形学中用点、直线或者多边形等基于数学方程的几何图元表示图像。矢量图形与使用像素表示图像的位图不同。

位图(Bitmap):又称栅格图(英语:Raster graphics)或点阵图,是使用像素阵列(Pixel-array/Dot-matrix点阵)来表示的图像。

转换.bmp格式

需要提前将.png、.jpg等格式的图片通过画图工具转换成.bmp,转换的文件类型需要为24位位图,如下图所示:

20200319144906730445.png

位图(.bmp格式)图片的字节数计算方法:

20200319144908271520.png

20200319144908429729.png

使用WinHex工具以十六进制的方式查看.bmp图,可以看出第一、二字节所表示的字符分别为:‘B‘、‘M‘

20200319144908591845.png

代码实现

Visual 1:读取图片信息

#include

int main()

{

FILE* fp = fopen("D:\\CR37\\Data\\imgs\\computer1.bmp","rb");

char tag[2];//定义一个字符数组

fread(tag, 2, 1, fp);//字符数组的名称可以隐式的转换成数组的首地址,参数1无需添 加 & 运算符

if (tag[0] != 'B' || tag[1] != 'M')

{

printf("这张图片不是一张\".bmp\"图片!\r\n");

return -1;

}

else

{

printf("这张图片是一张\".bmp\"图片!\r\n");

}

//输出图片文件的字节大小

//BMPd文件的第3~6字节保存了图片的字节数

int filesize = 0;

fread(&filesize, 4, 1, fp);

printf("这张图片的字节大小为:%d 字节\r\n", filesize);

fclose(fp);

return 0;

}

程序运行结果:

20200319144908686575.png

BMP文件头信息头的结构体定义:

//header C结构体

typedef struct {

unsigned short int type; //文件格式 占用2Bytes,必须为"BM"

unsigned int size; //文件大小,占用4字节

unsigned short int reserved1, reserved2; //保留区 默认设置为0

unsigned int offset;//文件头到图像数据信息偏移字节数

} HEADER;

//infoheader 结构体

typedef struct {

unsigned int size; //文件部分size大小

int width; //图像宽

int height; //图像高

unsigned short int planes; // 位面数 总为1

unsigned short int bits; //素位深

unsigned int compression; //缩类型

unsigned int imagesize; //像大小(字节)

int xresolution,yresolution; //率(水平,垂直

unsigned int ncolours; //所用颜色索引数目

unsigned int importantcolours; //像显示有重要影响的颜色索引数

} INFOHEADER;

Visual 2:定于结构体,获取BMP图片的一些信息

#include

#include

#include

/*

BMP头文件54字节的结构体声明

使用typedef()为struct BitMapHeader结构体定义别名:BIT_MAP_HEADER

*/

typedef struct BitMapHeader

{

long Size;//文件大小

short Reserved1;//保留字,不考虑

short Reserved2;//保留字,同上

long OffBits;//实际位图数据的偏移字节数,即前三个部分长度之和

}BIT_MAP_HEADER;

/*

BMP信息头,也是一个结构体,其定义了BMP图片的具体参数信息

使用typedef()为struct BitMapInfo结构体定义别名:BIT_MAP_INFO

*/

typedef struct BitMapInfo

{

long Size;//指定此结构体的长度,为40

long Width;//位图宽

long Height;//位图高

short Planes;//平面数,为1

short BitCount;//采用颜色位数,可以是1,2,4,8,16,24,新的可以是32

long Compression;//压缩方式,可以是0,1,2,其中0表示不压缩

long SizeImage;//实际位图数据占用的字节数

long XPelsPerMeter;//X方向分辨率

long YPelsPerMeter;//Y方向分辨率

long ClrUsed;//使用的颜色数,如果为0,则表示默认值(2^颜色位数)

long ClrImportant;//重要颜色数,如果为0,则表示所有颜色都是重要的

}BIT_MAP_INFO;

int main()

{

FILE* fp = fopen("D:\\CR37\\Data\\imgs\\computer1.bmp","rb");

char tag[2];//定义一个字符数组

fread(tag, 2, 1, fp);//字符数组的名称可以隐式的转换成数组的首地址,参数1无需添 加 & 运算符

if (tag[0] != 'B' || tag[1] != 'M')

{

printf("这张图片不是一张\".bmp\"图片!\r\n");

return -1;

}

else

{

printf("这张图片是一张\".bmp\"图片!\r\n");

//为BMP头文件结构体声明变量

BIT_MAP_HEADER bmpHeader;

fread(&bmpHeader, sizeof(bmpHeader), 1, fp);

//为BMP信息头结构体声明变量

BIT_MAP_INFO bmpInfo;

fread(&bmpInfo, sizeof(bmpInfo), 1, fp);

printf("这张BMP图片的宽度为:%d\r\n", bmpInfo.Width);

printf("这张BMP图片的高度为:%d\r\n", bmpInfo.height);

}

fclose(fp);

return 0;

}

程序运行结果:

20200319144908776422.png

20200319144910378046.png

根据上面使用结构体获取的BMP图片信息,使用initgraph()函数就可以初始化一个对应大小像素的窗口

initgraph(bmpInfo.Width, bmpInfo.Height);

_getch();

运行结果如下:

20200319144910909317.png

给初始化的绘图窗口填充颜色:

initgraph(bmpInfo.Width, bmpInfo.Height);

for (int x = 0; x <= bmpInfo.Width; x++)

{

for (int y = 0; y <= bmpInfo.Height; y++)

{

putpixel(x, y, RGB(0, 0, 255));

}

}

程序运行结果:

20200319144912104675.png

从fp读取对应像素点的RGB数值:

initgraph(bmpInfo.Width, bmpInfo.Height);

//位图每个像素点的RGB值占用3个字节

char data[3];//存储像素点的RGB值

for (int x = 0; x <= bmpInfo.Width; x++)

{

for (int y = 0; y <= bmpInfo.Height; y++)

{

//从fp读取数据到data里

fread(data, 3, 1, fp);

//字符型数据可以转换成整型

int r = data[0];

int g = data[1];

int b = data[2];

putpixel(i, j, RGB(r, g, b));

}

}

程序运行结果(可以看出结果并不是我们想要的,多以找bug):

20200319144915225889.png

由于位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。所以需要更改循环条件:

initgraph(bmpInfo.Width, bmpInfo.Height);

//位图每个像素点的RGB值占用3个字节

char data[3];//存储像素点的RGB值

for (int y = bmpInfo.Height - 1; y >= 0; y--)

{

for (int x =0 ; x <= bmpInfo.Width -1; x++)

{

//从fp读取数据到data里

fread(data, 3, 1, fp);

//字符型数据可以转换成整型

int r = data[0];

int g = data[1];

int b = data[2];

putpixel(i, j, RGB(r, g, b));

}

}

程序运行结果:

20200319144915974941.png

还可以修改for()循环里的条件:

for (int y = bmpInfo.Height - 1; y >= 0; y--)

{

//修改这里的循环条件

for (int x =bmpInfo.Width -1 ; x >= 0; x--)

{

//从fp读取数据到data里

fread(data, 3, 1, fp);

//字符型数据可以转换成整型

int r = data[0];

int g = data[1];

int b = data[2];

putpixel(i, j, RGB(r, g, b));

}

}

程序运行结果:

20200319144916345072.png

Visual 3:完整代码

#include

#include

#include

/*

BMP头文件54字节的结构体声明

使用typedef()为struct BitMapHeader结构体定义别名:BIT_MAP_HEADER

*/

typedef struct BitMapHeader

{

long Size;//文件大小

short Reserved1;//保留字,不考虑

short Reserved2;//保留字,同上

long OffBits;//实际位图数据的偏移字节数,即前三个部分长度之和

}BIT_MAP_HEADER;

/*

BMP信息头,也是一个结构体,其定义了BMP图片的具体参数信息

使用typedef()为struct BitMapInfo结构体定义别名:BIT_MAP_INFO

*/

typedef struct BitMapInfo

{

long Size;//指定此结构体的长度,为40

long Width;//位图宽

long Height;//位图高

short Planes;//平面数,为1

short BitCount;//采用颜色位数,可以是1,2,4,8,16,24,新的可以是32

long Compression;//压缩方式,可以是0,1,2,其中0表示不压缩

long SizeImage;//实际位图数据占用的字节数

long XPelsPerMeter;//X方向分辨率

long YPelsPerMeter;//Y方向分辨率

long ClrUsed;//使用的颜色数,如果为0,则表示默认值(2^颜色位数)

long ClrImportant;//重要颜色数,如果为0,则表示所有颜色都是重要的

}BIT_MAP_INFO;

int main()

{

FILE* fp = fopen("D:\\CR37\\Data\\imgs\\computer1.bmp","rb");

char tag[2];//定义一个字符数组

fread(tag, 2, 1, fp);//字符数组的名称可以隐式的转换成数组的首地址,参数1无需添 加 & 运算符

if (tag[0] != 'B' || tag[1] != 'M')

{

printf("这张图片不是一张\".bmp\"图片!\r\n");

return -1;

}

else

{

printf("这张图片是一张\".bmp\"图片!\r\n");

//为BMP头文件结构体声明变量

BIT_MAP_HEADER bmpHeader;

fread(&bmpHeader, sizeof(bmpHeader), 1, fp);

//为BMP信息头结构体声明变量

BIT_MAP_INFO bmpInfo;

fread(&bmpInfo, sizeof(bmpInfo), 1, fp);

initgraph(bmpInfo.Width, bmpInfo.Height);

//位图每个像素点的RGB值占用3个字节

char data[3];//存储像素点的RGB值

for (int y = bmpInfo.Height - 1; y >= 0; y--)

{

for (int x =0 ; x <= bmpInfo.Width -1; x++)

{

//从fp读取数据到data里

fread(data, 3, 1, fp);

//字符型数据可以转换成整型

int r = data[0];

int g = data[1];

int b = data[2];

putpixel(i, j, RGB(r, g, b));

_getch();

closegraph();

}

}

}

fclose(fp);

return 0;

}

原文:https://www.cnblogs.com/ileemi/p/12523893.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值