fprintf和fscanf
fprintf
int printf(const char *format, ...);
把数据输出到终端
int fprintf(FILE *stream, const char *format, ...);
功能:
将format字符串中的内容,输出到stream文件流指针指向的文件中去,想要将数据以何种形式输出到文件中,只需在format中选择合适的占位符即可。
int sprintf(char *str, const char *format, ...);
功能:
将format字符串中的内容,输出到str所指向的字符数组中。(把任意类型的数据转换为字符串类型数据)
fscanf
int scanf(const char *format, ...);
从终端读取数据,把数据写入到format中格式占位符代表的变量的地址上
int fscanf(FILE *stream, const char *format, ...);
功能:
从stream文件流指针的指向的文件中读取匹配数量的数据(根据文件中数据的类型以及格式占位符的类型进行匹配),遇到不匹配的数据则不吸收,然后将吸收到的数据写入format中格式占位符所代表的地址上去。*%c可以吸收任意数据包括空格,回车等
返回值:成功吸收数据返回成功吸收的数据的项数(其实就是指格式占位符的数量)
*fscanf是格式化读取文件的函数,需要精准的把控文件中的数据是什么格式,然后使用对应的格式去读取,除非用%c一个字节一个字节的读取。
int sscanf(const char *str, const char *format, ...);
功能:
从str所指向的字符串或字符串数组中读取数据,写入format所代表的地址上。(将字符串类型转换成任意类型的数据)
练习
typedef struct student
{
char name[20];
int c;
int m;
int e;
int p;
int ch;
int b;
}stu;
stu str[3]={};
编写两个.c文件:save.c和load.c
save.c负责使用fprintf把三个学生的数据保存到文件中
load.c负责读取文件中的学生信息,将读取到的数据,存到数组中,并输出数组中的内容
fputs和fgets
fputs
int fputs(const char *s, FILE *stream);
调用形式
fputs(想要写入文件中的字符串,文件流指针);
功能:
把字符串写入文件留指针所指向的文件中去
s:想要写入的字符串或字符数组
stream:文件流指针
返回值:写入失败返回EOF,成功返回非0数(大概率是写入的字符数量)
fgets(可吸收空格)
char *fgets(char *s, int size, FILE *stream);
调用形式
char* a=fgets(用来存放吸收数据的字符数组,最多从终端吸收的数据的个数,文件流指针)
功能描述:
从文件流指针指向文件中,吸收最多size-1个字符,并将吸收到的数据存放到s指向的数组,在读取到EOF或‘\n’时,读取也会结束(读取到的EOF或‘\n’也会写入数组)
返回值:
成功读取返回第一个参数s,读取失败或者读取到文件结束的时候,返回NULL(判断是否读取到文件结束符的依据)
fgets读取结束的情况有三种
- 获取的数据达到size-1(最大读取上限)
- 读取到回车
- 读取到EOF
练习
使用fgets和fputs实现文件的拷贝
fwrite和fread
fwrite和fread使用数据流读写,之前的所有读写函数采用文件流读写
当读写对象为字符串或字符时,二进制数据为本身,其他数据的二进制数据位乱码
文件流:
所有类型的数据都会转换为字符串类型,再保存到文件中
数据流:
任意的数据都会以数据本身的二进制形式保存到文件中去
fwrite和fread一定要配合使用
fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
调用形式
fwrite(想要写入的数据的地址,单个数据的大小,多少个数据,文件流指针);
功能描述:
将ptr指向的内存上面, 总共nmemb项数据,每一项数据size大小,总共nmemb*size个字节的数据,写入 stream指向的文件中去,注意是以数据流的形式去写的
参数 ptr:指向想要写入文件中的数据
参数 size:每一个数据的大小
参数 nmemb:总共多少个数据
参数 stream;文件流指针
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
调用形式:
int a=fread(存放读取到的数据的地址,读取到的单个数据的大小,读取数据个数,文件流指针);
功能:
读取文件流指针所指向的文件中nmemb个数据,每个数据大小为size,总共读取nmemb*size个字节的数据,然后将读取到的数据写入ptr指向的内存中
参数 ptr:指向用来存放读取到的数据的指针
参数 size:每一个读取到的数据的大小
参数 nmemb:读取多少个数据
参数 stream:文件流指针
返回值:成功读取,返回读取到的数据的项数,也就是第三个参数,读取失败或者读取到文件末尾则返回0。
练习
使用fwrite和fread实现文件的拷贝
fseek文件流指针偏移函数
实现文件的光标定位问题
int fseek(FILE *stream, long offset, int whence);
调用形式
fseek(fp,1,SEEK_SET)
fseek(fp,-1,SEEK_END)
fseek(fp,5,SEEK_CUR)
功能:
定位文件流指针对应的文件的光标,从whence出开始偏移,偏移offset个字节
参数whence:光标偏移的起点
参数offset:光标偏移量,+表示从左往右,-表示从右往左
SEEK_SET:从文件开头位置开始偏移
SEEK_CUR:从文件当前光标位置开始偏移
SEEK_END:从文件结束符开始偏移
读取bmp文件的信息
练习
把bmp文件转换为全红
练习
寻找一个bmp图片,输出这张bmp图片的第一个像素点和最后一个像素点的bgr的值
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
int main(int argc, const char *argv[])
{
FILE* fp=fopen("./rising_freedom (copy).bmp","r");
int size=0,w=0,h=0;
fseek(fp,2,SEEK_SET);
fread(&size,4,1,fp);
printf("%d\n",size);
fseek(fp,18,SEEK_SET);
fread(&w,4,1,fp);
fread(&h,4,1,fp);
printf("%d %d\n",w,h);
unsigned char bgr[3]={0};
fseek(fp,54,SEEK_SET);
for(int i=0;i<h;i++)
{
for(int j=0;j<w;j++)
{
if(i==0&&j==0)
{
fread(bgr,3,1,fp);
for(int q=0;q<3;q++)
{
printf("%d ",bgr[q]);
}
putchar(10);
continue;
}
if(i==h-1&&j==w-1)
{
fread(bgr,3,1,fp);
for(int q=0;q<3;q++)
{
printf("%d ",bgr[q]);
}
putchar(10);
}
}
}
fclose(fp);
return 0;
}
修改一张bmp图像的大小,让它的宽度*2,高度*2,也就是最终像素点的数量*4,最后使用黑色像素点填充图片扩大部分(补要求效果,只要求代码)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
int main(int argc, const char *argv[])
{
FILE* fp=fopen("./rising_freedom (3rd copy).bmp","r");
int size=0,w=0,h=0;
fseek(fp,2,SEEK_SET);
fread(&size,4,1,fp);
printf("%d\n",size);
fseek(fp,18,SEEK_SET);
fread(&w,4,1,fp);
fread(&h,4,1,fp);
printf("%d %d\n",w,h);
fclose(fp);
fp=fopen("./rising_freedom (3rd copy).bmp","r+");
w*=2;
h*=2;
fseek(fp,18,SEEK_SET);
fwrite(&w,4,1,fp);
fwrite(&h,4,1,fp);
fseek(fp,18,SEEK_SET);
fread(&w,4,1,fp);
fread(&h,4,1,fp);
printf("%d %d\n",w,h);
size*=4;
fseek(fp,2,SEEK_SET);
fwrite(&size,4,1,fp);
fseek(fp,2,SEEK_SET);
fread(&size,4,1,fp);
printf("%d\n",size);
unsigned char bgr_black[3]={0,0,0};
unsigned char bgr[3]={};
int len=(w/2)*(h/2)*3;
fseek(fp,54,SEEK_SET);
fseek(fp,len,SEEK_CUR);
while(1)
{
int i=fread(bgr,3,1,fp);
if(0==i)
break;
fwrite(bgr_black,3,1,fp);
}
fclose(fp);
return 0;
}
将一张bmp图片修改为德国国旗
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
int main(int argc, const char *argv[])
{
FILE* fp=fopen("./rising_freedom (copy).bmp","r");
int size=0,w=0,h=0;
fseek(fp,2,SEEK_SET);
fread(&size,4,1,fp);
printf("%d\n",size);
fseek(fp,18,SEEK_SET);
fread(&w,4,1,fp);
fread(&h,4,1,fp);
printf("%d %d\n",w,h);
fclose(fp);
fp=fopen("./rising_freedom (copy).bmp","r+");
unsigned char bgr_black[3]={0,0,0};
unsigned char bgr_red[3]={0,0,255};
unsigned char bgr_yellow[3]={0,255,255};
fseek(fp,54,SEEK_SET);
for(int i=0;i<h;i++)
{
for(int j=0;j<w/3;j++)
{
fwrite(bgr_yellow,3,1,fp);
}
}
for(int i=0;i<h;i++)
{
for(int j=w/3;j<w*2/3;j++)
{
fwrite(bgr_red,3,1,fp);
}
}
for(int i=0;i<h;i++)
{
for(int j=w*2%3;j<w;j++)
{
fwrite(bgr_black,3,1,fp);
}
}
fclose(fp);
return 0;
}