0## 1.获得当前时间
# include <stdio.h>
#include <stdlib.h>
#include <time.h>int main()
{struct tm* ptm;time_t sec = time(NULL);ptm = localtime(&sec);printf("%d-%d-%d %d:%d:%d\n",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
}
2 .枚举
可以直接定义枚举变量,结构体也可以
3 封装日志模块
要点
1.对于多个全局变量直接用结构体封装到头文件中
2.学会使用枚举,用枚举数据类型接收来的是数字,一般创建一个字符串数组,传过来的枚举成员作下标,如下。
*******c文件*****************
#include "log.h"
#include <sys/stat.h>
#include <sys/types.h>log_s log_g;//全局结构体变量
int init_log()//初始化函数
{struct tm *ptm = NULL;time_t sec = time(NULL);ptm = localtime(&sec);log_g.time = *ptm;char filename[256] = {0};//村名字进去不能用char*mkdir("LOG",0777);//创建目录sprintf(filename,"./LOG/log%d-%02d-%02d%.txt",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday);//在LOG目录下创建文件log_g.fp = fopen(filename,"a");if(log_g.fp == NULL){printf("fopen fail!\n");return -1;}return 0;}int write_log(log_lev lev,char *str)
{time_t sec = time(NULL);struct tm *ptm = NULL;ptm = localtime(&sec);if(ptm->tm_mday != log_g.time.tm_mday)// if(ptm->tm_min != log_g.time.tm_min){deinit_log();init_log();}char *leves[3] = {"LOG_INFO","LOG_WARN","LOG_ERR"};//由于枚举成员本质是整数,传递不了他代表的字符串,创建字符串数组,用枚举常量表示下标;fprintf(log_g.fp,"[%d-%d-%d %d:%d;%d][%s]%s\n",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec,leves[lev],str);fflush(log_g.fp);return 0;
}void deinit_log()
{fclose(log_g.fp);
}
*****h文件
#ifndef __LOG_H__
#define __LOG_H__
#include<stdio.h>
#include<time.h>typedef enum
{LOG_INFO,LOG_WARN,LOG_ERR,
}log_lev;typedef struct //多个全局变量直接在.h文件中构建结构体
{FILE *fp;struct tm time;
}log_s;
extern int init_log();
extern int write_log(log_lev lev , char *str);
extern void deinit_log();
#endif
main函数
#include "log.h"
#include <stdio.h>
#include<unistd.h>//sleepint main(int argc , const char *grgv[])
{init_log();write_log(LOG_INFO,"日志模块初始化成功!");while(1){write_log(LOG_ERR,"XXX文件打开失败!");sleep(1);write_log(LOG_WARN,"XXX文件为空!");sleep(1);}deinit_log();return 0;}
4 打印出错信息
1.strerror(errno)
2.perror
3 error
error可以给出更详细的错误信息哪一个文件哪个函数哪一行。
例
目录IO
目录文件 ----> 目录流指针 ----> 提供给相关函数操作 01-打开目录 --opendir
02-读目录 --readdir
03-关闭目录 --closedir 1.opendir
DIR *opendir(const char *name);
功能:打开一个目录获得一个目录流指针
参数:name:目录名
返回值:成功返回目录流指针失败返回NULL2.readdir
struct dirent *readdir(DIR *dirp);
功能:从目录流中读取文件信息并将保存信息的结构体地址返回
参数:dirp:目录流指针
返回值:包含文件信息的结构体出错或者读到目录流末尾返回NULLOn Linux, the dirent structure is defined as follows:struct dirent {ino_t d_ino; /* inode number */off_t d_off; /* offset to the next dirent */unsigned short d_reclen; /* length of this record */unsigned char d_type; /* type of file;not supportedby all file system types */char d_name[256]; /* filename */};3、关闭目录 int closedir(DIR *dirp);功能:关闭之前已经打开的目录流对象参数:opendir的返回结果中目录流对象返回值:成功 0失败 -1;
会读目录。一般目录下有隐藏文件
多文件管理
makefilemakefile文件用于管理和组织代码工程的编译和链接,被make工具解析并完成相关动作make:工程管理工具
make makefileMakefile 语法:要生成的文件:依赖的所有文件生成方式app:main.c add.c sub.cgcc main.c add.c sub.c -o app -I./include -lm 变量:1.自定义变量OBJ=OBJ+=SRC=CC=OBJ=app SRC=main.c SRC+=add.c SRC+=sub.cCC=gccINCLUDE=./includeFLAG=-lm$(OBJ):$(SRC)$(CC) $(SRC) -o $(OBJ) -I$(INCLUDE) $(FLAG)2.系统变量$@:要生成的文件名(目标文件) a.out$^:所有依赖的文件 xxx.c$<:第一个依赖的文件$(OBJ):$(SRC)$(CC) $^ -o $@ -I$(INCLUDE).PHONY:clean:rm $(OBJ)make:生成目标文件make clean:删除目标文件(或者多余文件)3.时间戳:编译文件时,时间戳更新的文件需要重新加入编译,时间戳没有改变的不需要重新编译 1)预处理:gcc -E test.c -o test.i 对预编译指令都做相应的处理2)编译:gcc -S test.i -o test.s 编译成汇编指令代码3)汇编:gcc -c test.s -o test.o 将汇编指令代码转化为目标文件4)链接:gcc test.o -o test 将目标文件与库文件(静态库或动态库)链接得到可执行文件。gcc -c test.c -o test.o 将源代码转化为目标文件gcc -c main.c -o main.ogcc main.o test.o -o appOBJ=appSRC=main.o add.oCC=gcc$(OBJ):$(SRC)$(CC) $^ -o $@main.o:main.c$(CC) -c $^ -o $@ add.o:add.c$(CC) -c $^ -o $@clean:rm $(OBJ) $(SRC)======>%.o:%.c$(CC) -c $^ -o $@