一.笔记
1. 有关系统时间的函数
1> 有关时间的函数
#include <time.h>
time_t time(time_t *tloc);
功能:获取系统时间,从1970年1月1日0时0分0秒,到目前累计的秒数
参数:用于接收的秒数
返回值:秒数使用方式:
1、time_t sys_time = time(NULL);
2、time_t sys_time = 0; time(&sys_time);
struct tm *localtime(const time_t *timep);
功能:将time_t 秒数,转换为时间类型的结构体
参数:time_t 类型的时间秒数
返回值:时间结构体
struct tm {
int tm_sec; /* 秒数 */
int tm_min; /* 分钟 (0-59) */
int tm_hour; /* 小时 (0-23) */
int tm_mday; /* 月中天数 (1-31) */
int tm_mon; /* 月份+1 (0-11) */
int tm_year; /* 年 + 1900 */
int tm_wday; /* 周中天数 (0-6, Sunday = 0) */
int tm_yday; /* 年中天数 (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};
2. sprintf\snprintf:将格式串转换为字符串
int sprintf(char *str, const char *format, ...);
功能:将格式串转换为字符串放入字符数组中
参数1:存放格式串的字符数组
参数2:格式串,可以包含格式控制符
参数3:可变参数,根据参数2中的格式控制符个数确定
返回值:成功返回转换的字符个数,失败返回-1
int snprintf(char *str, size_t size, const char *format, ...);
该函数比sprintf更加安全,因为多了一个size的限制
3. fprintf\fscanf:格式化读写函数
int fprintf(FILE *stream, const char *format, ...);
功能:向指定文件中写入一个格式串
参数1:文件指针
参数2:格式串,可以包含格式控制符
参数3:可变参数,根据参数2而定
返回值:成功返回写入文件的字符实际个数,失败返回-1
int fscanf(FILE *stream, const char *format, ...);
功能:将从文件中读取一些数据,放入到程序中来
参数1:文件指针
参数2:格式控制串
参数3:根据参数2而定
返回值:成功返回读取数据的个数,失败返回EOF并置位错误码
4. fprintf\fscanf:格式化读写函数
int fprintf(FILE *stream, const char *format, ...);
功能:向指定文件中写入一个格式串
参数1:文件指针
参数2:格式串,可以包含格式控制符
参数3:可变参数,根据参数2而定
返回值:成功返回写入文件的字符实际个数,失败返回-1
int fscanf(FILE *stream, const char *format, ...);
功能:将从文件中读取一些数据,放入到程序中来
参数1:文件指针
参数2:格式控制串
参数3:根据参数2而定
返回值:成功返回读取数据的个数,失败返回EOF并置位错误码
5.fread\fwrite:模块化读写
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:对文件进行模块化读写操作
参数1:要写入(存放数据)数据的起始地址
参数2:每一项的大小
参数3:总的项数
参数4:文件指针
返回值:成返回读取的项数值,失败返回小于项数的值
注意:fread并不能区分是文件结束了,还是因为出现错误了,需要使用feof或ferror来区分
6.关于文件光标的函数
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
功能:对文件光标进行偏移
参数1:文件指针
参数2:偏移量 >0:表示向后偏移 =0:表示不偏移 <0:表示向前偏移
参数3:偏移位置
SEEK_SET:文件开头
SEEK_END:文件结束
SEEK_CUR:当前位置
返回值:成功返回0,失败返回-1并置位错误码
long ftell(FILE *stream);
功能:返回文件当前位置(就是当前位置相对于文件起始位置的偏移字节数) 参数:文件指针 返回值:偏移字节数
常用:fseek(fp, 0, SEEK_END);
ftell(fp); //文件大小
void rewind(FILE *stream);
功能:将光标定位到开头 类似于 fseek(fp, 0, SEEK_SET)
参数:文件指针
返回值:无
6. 思考:
使用a或者a+的形式打开文件是,对文件光标进行偏移时是否效果?
答:对于a而言,不能进行偏移其写光标,总是在结尾写
对于a+而言,其写光标不能偏移,但是读光标可以偏移
二.作业
1> 写一个日志文件,将程序启动后,每一秒的时间写入到文件中
#include <myhead.h>
int main(int argc, char const *argv[])
{
FILE *fp=NULL;
if ((fp=fopen("./time1.txt","a"))==NULL)
{
perror("fopen error\n");
return -1;
}
char buf1[128]="";
char buf2[128]="";
time_t sys_time;
struct tm*time_ptr;
int count=0;
while (1)
{
sys_time=time(NULL);
time_ptr=localtime(&sys_time);
sprintf(buf1,"%4d-%2d-%2d %2d:%2d:%2d\n",\
time_ptr->tm_year+1900,\
time_ptr->tm_mon+1,\
time_ptr->tm_mday,\
time_ptr->tm_hour,\
time_ptr->tm_min,\
time_ptr->tm_sec);
if (strcmp(buf2,buf1))
{
count++;
fgets(buf1,128,fp);
fprintf(fp,"%d->",count);
fputs(buf1,fp);
strcpy(buf2,buf1);
}
}
fclose(fp);
return 0;
}
2> 使用fread、fwrite完成两个文件的拷贝
不允许只读写一次
#include <myhead.h>
int main(int argc, char const *argv[])
{
if (argc!=3)
{
printf("input file error!!!\n");
printf("usage:./a.out filename\n");
return -1;
}
FILE*fp1=NULL;
FILE*fp2=NULL;
if (NULL==(fp1=fopen(argv[1],"r"))||NULL==(fp2=fopen(argv[2],"w")))
{
printf("拷贝失败\n");
return -1;
}
char buf[1]="";
while (1)
{
int res=fread(buf,1,1,fp1);//从fp1中读取文件
if (res<=0)//表示文件读取数据结束
{
break;
}
fwrite(buf,1,1,fp2);
}
fclose(fp1);
fclose(fp2);
printf("拷贝成功\n");
}
3> 实现对bmp图像的读写操作
#include<myhead.h>
int main(int argc, const char *argv[])
{
//定义文件指针
FILE *fp = NULL;
if((fp = fopen("./gg.bmp", "r+")) == NULL)
{
perror("fopen error");
return -1;
}
//获取文件大小
int img_size = 0;
//将文件光标偏移2个字节
fseek(fp, 2, SEEK_SET);
//读取4字节的内容
fread(&img_size, sizeof(img_size), 1, fp);
printf("size = %d\n", img_size); //图像大小
//从头向后偏移54字节后,就是图像数据
fseek(fp, 54, SEEK_SET);
//定义一个像素
unsigned char color[3] = {0, 0, 255}; //正红色
for(int i=0; i<960/2; i++) //外行
{
for(int j=0;j<1280; j++) //内列
{
fwrite(color, sizeof(color), 1, fp);
}
}
//关闭文件
fclose(fp);
return 0;
}