目录
fopen/fclose打开关闭文件函数
FILE *fopen(const char *pathname, const char *mode);
功能:使用标准IO接口打开文件
参数:
pathname:文件的路径和名字
mode:打开文件的方式
r 以只读的方式打开文件,将光标定位到文件的开头
r+ 以读写的方式打开文件,将光标定位到文件的开头
w 以只写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空文件,
将光标定位到文件的开头
w+ 以读写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空文件,
将光标定位到文件的开头
a 以追加的方式打开文件,如果文件不存在就创建文件,如果文件存在就结尾写,将光标
定位到文件的结尾。
a+ 以读和追加的方式打开文件,如果文件不存在就创建文件,如果文件存在不会清空。
如果读是从开头读,如写从结尾写
返回值:成功返回FILE指针,失败返回NULL,置位错误码
int fclose(FILE *stream);
功能:关闭文件
参数:
stream:文件指针
返回值:成功返回0,失败返回EOF置位错误码
fseek光标操作函数
int fseek(FILE *stream, long offset, int whence);
功能:用来设置光标的位置
参数:
stream:文件指针
offset:设置到哪里(偏移)
大于0的值 向后偏移
等于0的值 不偏移
小于0的值 向前偏移
whence:从哪里开始设置
SEEK_SET:开头
SEEK_CUR:当前位置
SEEK_END :结尾
返回值:成功返回0,失败返回-1置位错误码
fread/fwrite函数
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件中读取数据到ptr中
参数:
ptr:用来存储读取到的数据的地址
size:每一项的大小
nmemb:项目的个数
stream:文件指针
返回值:成功返回读取到的项目的个数,
如果size是1,返回的项目的个数就是字节的个数
失败返回小于项目的个数或者是0
如果是失败需要通过ferror或者feof判断是那种错误
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
功能:将ptr中的数据写入到文件中
参数:
ptr:写数据的首地址
size:每一项的大小
nmemb:项目的个数
stream:文件指针
返回值:成功返回写入项目的个数,
失败或者到文件结尾了返回小于项目的个数或者是0
定义图片信息的结构体变量
typedef struct picture {
unsigned int size; //图像大小,单位字节
unsigned int offset; //图像头大小,单位字节
unsigned int width; //图像宽度,单位像素
unsigned int high; //图像高度,单位像素
unsigned short pix;//
} p_t;
定义某像素点颜色的结构体
typedef struct {
unsigned char B; //蓝
unsigned char G; //绿
unsigned char R; //红
} RGB_t;
获取图片信息函数
void get_picture_head_info(FILE* fp, p_t* info)
{
fseek(fp, 2, SEEK_SET);
fread(&info->size, 4, 1, fp);
fseek(fp, 10, SEEK_SET);
fread(&info->offset, 4, 1, fp);
fseek(fp, 18, SEEK_SET);
fread(&info->width, 4, 1, fp);
fread(&info->high, 4, 1, fp);
fseek(fp, 2, SEEK_CUR);
fread(&info->pix, 2, 1, fp);
}
通过双循环改变图片某一区间的颜色
memset(&rgb, 0, sizeof(rgb));
rgb.G = 0; // 黑色
rgb.R = 0;
rgb.B = 0;
int wide = 30;
int heigh = 30;
fseek(fp, 54 + 899538, SEEK_SET);
for (int j = 0; j < heigh; j++) {
for (int i = 0; i < wide; i++) {
fwrite(&rgb, 3, 1, fp);
}
fseek(fp, (info.width - wide) * 3, SEEK_CUR);
}
程序完整代码
//使用标准IO对图片数据操作
#include <head.h>
typedef struct picture {
unsigned int size; //图像大小,单位字节
unsigned int offset; //图像头大小,单位字节
unsigned int width; //图像宽度,单位像素
unsigned int high; //图像高度,单位像素
unsigned short pix; //
} p_t;
typedef struct {
unsigned char B; //蓝
unsigned char G; //绿
unsigned char R; //红
} RGB_t;
void get_picture_head_info(FILE* fp, p_t* info)
{
fseek(fp, 2, SEEK_SET);
fread(&info->size, 4, 1, fp);
fseek(fp, 10, SEEK_SET);
fread(&info->offset, 4, 1, fp);
fseek(fp, 18, SEEK_SET);
fread(&info->width, 4, 1, fp);
fread(&info->high, 4, 1, fp);
fseek(fp, 2, SEEK_CUR);
fread(&info->pix, 2, 1, fp);
}
int main(int argc, const char* argv[])
{
FILE* fp;
p_t info;
RGB_t rgb;
if (argc != 2) {
fprintf(stderr, "input error,try again\n");
fprintf(stderr, "usage:./a.out picturename\n");
return -1;
}
if ((fp = fopen(argv[1], "r+")) == NULL)
PRINT_ERR("fopen error");
get_picture_head_info(fp, &info);
fseek(fp, 54, SEEK_SET);
fread(&rgb, 3, 1, fp);
memset(&rgb, 0, sizeof(rgb));
rgb.G = 0; // 黑色
rgb.R = 0;
rgb.B = 0;
int wide = 30;
int heigh = 30;
fseek(fp, 54 + 899538, SEEK_SET);
for (int j = 0; j < heigh; j++) {
for (int i = 0; i < wide; i++) {
fwrite(&rgb, 3, 1, fp);
}
fseek(fp, (info.width - wide) * 3, SEEK_CUR);
}
fclose(fp);
return 0;
}