目录
调试用的宏
有关系统时间的函数
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 */
};
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的限制
#include<myhead.h>
#include<time.h>
int main(int argc, const char *argv[])
{
//定义变量存储秒数
time_t sys_time = time(NULL);
//将秒数转换为结构体
struct tm *time_ptr = localtime(&sys_time);
char buf[128] = ""; //存放转变后的字符串
sprintf( buf,"%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);
printf("buf = %s\n", buf);
return 0;
}
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并置位错误码
#include<myhead.h>
int main(int argc, const char *argv[])
{
//定义文件指针
FILE *fp = NULL;
if((fp = fopen("./file.txt", "w")) == NULL)
{
perror("fopen error");
return -1;
}
//定义要存储的数据
int num = 18; //整形数据
printf("num = %d\n", num); //向终端输出
fprintf(fp ,"%d\n", num); //向fp指向的文件中输出
//关闭文件
fclose(fp);
//以只读的形式打开文件
if((fp = fopen("./file.txt", "r")) == NULL)
{
perror("fopen error");
return -1;
}
int key = 0;
fscanf(fp, "%d", &key); //从文件中读取一个数据
printf("key = %d\n", key);
//关闭文件
fclose(fp);
return 0;
}
fprintf/fscanf 登录注册
#include<myhead.h>
//定义登录函数
int do_login()
{
//定义变量接受登录账号和密码
char login_name[20] = "";
char login_pwd[20] = "";
printf("请输入登录账号:");
fgets(login_name, sizeof(login_name), stdin);
login_name[strlen(login_name)-1] = '\0'; //将换行换成'\0'
printf("请输入登录密码:");
fgets(login_pwd, sizeof(login_pwd), stdin);
login_pwd[strlen(login_pwd)-1] = 0;
//打开文件读取数据
FILE *fp = NULL;
if((fp = fopen("./usr.txt", "r")) == NULL)
{
perror("fopen error");
return -1;
}
//定义接收文件中的变量
char name[20] = "";
char pwd[20] = "";
while(1)
{
//读取数据
int res = fscanf(fp, "%s %s", name, pwd);
if(res != 2)
{
break;
}
//判断是否登录成功
if(strcmp(login_name,name)==0 && strcmp(login_pwd,pwd)==0)
{
printf("登录成功\n");
fclose(fp);
return 0;
}
}
//关闭文件
fclose(fp);
return -1;
}
//定义注册函数
void do_regist()
{
//定义变量接受注册账号和密码
char regist_name[20] = "";
char regist_pwd[20] = "";
printf("请输入注册账号:");
fgets(regist_name, sizeof(regist_name), stdin);
regist_name[strlen(regist_name)-1] = '\0'; //将换行换成'\0'
printf("请输入注册密码:");
fgets(regist_pwd, sizeof(regist_pwd), stdin);
regist_pwd[strlen(regist_pwd)-1] = 0;
//将上述内容写入文件
FILE *fp = NULL;
if((fp = fopen("./usr.txt", "a")) == NULL)
{
perror("fopen error");
return;
}
//将数据写入文件
fprintf(fp, "%s %s\n", regist_name, regist_pwd);
//关闭文件
fclose(fp);
printf("注册成功\n");
}
/************************主程序************************/
int main(int argc, const char *argv[])
{
//制作菜单
int menu = 0; //选项
while(1)
{
//调用函数执行shell指令
system("clear");
printf("\t\t======XXX 登录系统======\n");
printf("\t\t======1、 登录======\n");
printf("\t\t======2、 注册======\n");
printf("\t\t======0、 退出======\n");
printf("请输入功能:");
fscanf(stdin, "%d", &menu);
while(getchar() !='\n'); //吸收垃圾字符
//对菜单多分支选择
switch(menu)
{
case 1:
{
//do_login();
int res = do_login();
if(res == 0)
{
//执行相关功能
}else
{
printf("登录失败\n");
}
}
break;
case 2:
{
do_regist();
}
break;
case 0:goto END;
default:fprintf(stdout, "您输入的功能有误,请重新输入!!\n");
}
printf("请输入任意键,按回车结束\n");
while(getchar() != '\n');
}
END:
return 0;
}
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来区分
使用fread、fwrite读写字符串
#include <myhead.h>
int main(int argc, char const *argv[])
{
FILE *fp = NULL;
fp = fopen("./usr.txt","w");
char buf[] = "hello a\n";
fwrite(buf,1,strlen(buf),fp); //单字符写入
fwrite(buf,strlen(buf),1,fp); //单字串写入
fclose(fp);
fp = fopen("./usr.txt","r");
char rbuf[128] = "";
fread(rbuf,1,strlen(buf),fp); //strlen(buf)-1 手动预留一个位置放‘\0’
// printf("rbuf = %s\n",rbuf); //fread 读取字符串不会预留一个位置放‘\0’,如果字符数组大小 小于等于 读取的大小,用%s输出会出现乱码
fwrite(buf,1,strlen(buf),stdout); //向标准输出写入内容 则不受影响
fclose(fp);
return 0;
}
使用fread、fwrite读写字符串
#include <myhead.h>
int main(int argc, char const *argv[])
{
FILE *fp = NULL;
fp = fopen("./usr.txt","w");
int num = 18;
fwrite(&num,sizeof(num),1,fp); //整型写入 存储的是十六进制数
fclose(fp);
fp = fopen("./usr.txt","r");
int key = 0;
fread(&key,sizeof(key),1,fp);
printf("key = %d\n",key); // key = 18
fclose(fp);
return 0;
}
直接打开存储文件
使用fread、fwrite读写结构体
#include <myhead.h>
typedef struct
{
int numb;
char name[20];
int age;
double score;
}Stu;
int main(int argc, char const *argv[])
{
FILE *fp = NULL;
fp = fopen("./usr.txt","w");
Stu s[3] = {{1001,"lisi",30,98},{1002,"zs",25,100},{1003,"ww",23,80}};
fwrite(s,sizeof(Stu),3,fp);
fclose(fp);
fp = fopen("./usr.txt","r");
Stu temp;
fread(&temp,sizeof(temp),1,fp);
printf("学号%d 姓名%s 年龄%d 成绩%.2lf\n",temp.numb,temp.name,temp.age,temp.score);
fread(&temp,sizeof(temp),1,fp);
printf("学号%d 姓名%s 年龄%d 成绩%.2lf\n",temp.numb,temp.name,temp.age,temp.score);
fclose(fp);
return 0;
}
光标移动函数 fseek
#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)
参数:文件指针
返回值:无
#include<myhead.h>
//定义结构体类型
typedef struct
{
int numb; //学号
char name[20]; //姓名
int age; //年龄
double score; //成绩
}Stu;
/**********************主程序*********************/
int main(int argc, const char *argv[])
{
//定义文件指针
FILE *fp = NULL;
if((fp = fopen("./usr.txt", "w")) == NULL)
{
perror("fopen error");
return -1;
}
//定义三个学生
Stu s[3] = {{1001, "大狗", 30, 98}, \
{1002, "二狗", 25, 100}, \
{1003, "天明", 23, 80}};
//将这三名学生信息写入文件中
fwrite(s, sizeof(Stu), 3, fp);
//关闭文件
fclose(fp);
//以只读的形式打开文件
if((fp = fopen("./usr.txt", "r")) == NULL)
{
perror("fopen error");
return -1;
}
//定义接收取出的学生
Stu temp;
fread(&temp, sizeof(temp), 1, fp);
fread(&temp, sizeof(temp), 1, fp);
//此时,光标已经定位在第三个学生的开头
//目的:将光标定位到“大狗”前面
//fseek(fp, 0, SEEK_SET);
fseek(fp, -(sizeof(Stu)*2), SEEK_CUR);
fread(&temp, sizeof(temp), 1, fp);
printf("学号:%d, 姓名:%s,年龄:%d,成绩%.2lf\n",\
temp.numb, temp.name, temp.age, temp.score);
//关闭文件
fclose(fp);
return 0;
}
使用标准IO完成对图像的操作
bmp图的资料链接:https://blog.csdn.netXYK0318/article/details/105123197/
./gg.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;
}
作业
1、写一个日志文件,将出现启动后,每一秒的时间写入文件中
1、2024- 7-29 10:31:19
2、2024- 7-29 10:31:20
3、2024- 7-29 10:31:21
ctrl+c:停止程序
./a.out
4、2024- 7-29 10:35:06
5、2024- 7-29 10:35:07
6、2024- 7-29 10:35:08
代码
#include <myhead.h>
int main(int argc, char const *argv[])
{
FILE *fp = fopen("./00.log", "a+");
fseek(fp,0,SEEK_SET);
char buf[128] = "";
char buf1[128] = {"1"};
char buf2[128] = "";
int n = 1;
while (1)
{
// printf("n1 = %d\n",n);
if ((fgets(buf2, sizeof(buf2), fp)) != NULL)
{
n++;
// printf("n2 = %d\n",n);
}
else
{
break;
}
}
fseek(fp,0,SEEK_END);
time_t sys_time = time(NULL); // 定义及重置
struct tm *time_ptr = localtime(&sys_time);
while (1)
{
sys_time = time(NULL); // 定义及重置
time_ptr = localtime(&sys_time);
sprintf(buf, "%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(buf, buf1) != 0)
{
printf("n = %d\n", n);
fprintf(fp, "%d %s", n, buf);
strcpy(buf1, buf);
fflush(stdin);
fflush(fp);
n++;
}
}
return 0;
}
终端执行命令
效果图
2、使用fread、fwrite完成两个文件的拷贝
不允许只读写一次
代码
#include <myhead.h>
int main(int argc, char const *argv[])
{
FILE *fp = NULL;
FILE *fq = NULL;
fp = fopen("./06.c", "r");
fq = fopen("./06.txt", "w");
char temp[10] = "";
while (fread(temp, sizeof(temp), 1, fp))
{
fwrite(temp, sizeof(temp), 1, fq);
bzero(temp,sizeof(temp));
}
fwrite(temp, strlen(temp), 1, fq);
fclose(fp);
fclose(fq);
return 0;
}
效果图
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, 0}; // bgr
// unsigned char color[3] = {255, 255, 255}; // bgr
for (int i = 0; i < 960; i++) // 外行
{
for (int j = 0; j < 1280; j++) // 内列
{
if (i > 570 && i < 630 && j>350 && j<620||i > 590 && i < 650 && j>720 && j<1000)
{
fwrite(color, sizeof(color), 1, fp);
}
else
{
fseek(fp, sizeof(color), SEEK_CUR);
}
}
}
// 关闭文件
fclose(fp);
return 0;
}
效果图: