平台:x86/Debian Linux/gcc
编程读写一个文件test.txt,每隔1s向文件中写入一行记录,类似于这样:
1 2009-7-30 15:16:42 2 2009-7-30 15:16:43 |
该程序应该是无限循环,直到按Ctrl + C终止。下次再启动程序时再test.txt文件末尾追加记录,并且序号能够持续上次的序号,比如:
1 2009-7-30 15:16:42 2 2009-7-30 15:16:43 3 2009-7-30 15:19:02 4 2009-7-30 15:19:03 5 2009-7-30 15:19:04 |
/* Filename: out_date_and_time.c * Brife: Output date and time to time.txt one by one second * Date: 2014.8.7 Thursday * Author: One fish */ #include <time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> //------------Maro------------------ #define EPOCH_YEAR 1900 #define EPOCH_MONTH 1 #define EPOCH_DAY 1 #define OUT_FILE "time.txt" //------------Function decalre------- void get_localtime(unsigned long int file_num); unsigned long int find_file_end(const char *file); //----------Golbal varibles---------- FILE *fp = NULL; int main(void) { unsigned long int file_num = 0; file_num = find_file_end(OUT_FILE); printf("line number: %d\n", file_num); while( 1 ){ get_localtime( file_num + 1 ); sleep(1); } return 0; } /*@Brife: Open file and find file end line number *@Arg: file is the opened file *@Rel: Return the file number */ unsigned long int find_file_end(const char *file) { char buf[30]; int file_num = 0; fp = fopen(file, "a+"); if(NULL != fp){ //File is empty if( NULL == fgets(buf, 30, fp) ) return 0; //Move fp to the start of the last line of the file fseek(fp, -strlen(buf), SEEK_END); fgets(buf, 30, fp); //Or line number bigger than long long int scope if(1 != sscanf(buf, "%d", &file_num) ){ printf("*.txt format is not correct\n"); return 0; } return file_num; }else{ printf("Open %s failed\n", OUT_FILE); } } /*@Brife: Get current date and output to time.txt * Should be called after find_file_end() *@Arg: File_num, the line number should be printed */ void get_localtime(unsigned long int file_num) { time_t *t = NULL; static unsigned long int num = 0; if(num <= file_num){ num = file_num; } t = (time_t *)malloc(sizeof(time_t)); if(NULL != t){ struct tm *ptm = NULL; //Get the time as the number of seconds since the Epoch, 1970-01-01 00:00 + 0000(UTC) //Translate calendar time to broken-down time time(t); ptm = localtime(t); if(NULL != fp){ fprintf(fp, "%d %d-%d-%d\t", num, EPOCH_YEAR + ptm->tm_year, EPOCH_MONTH + ptm->tm_mon, EPOCH_MONTH + ptm->tm_mday); fprintf(fp, "%d:%d:%d\n", ptm->tm_hour, ptm->tm_min, ptm->tm_sec); fflush(fp); ++num; }else{ printf("%s Not found\n", OUT_FILE); } } free(t); }
编译程序:gcc -o out_date_and_time out_date_and_time.c
第一次运行程序一小会后按Ctrl + C终止程序,隔一小会再运行程序。time.txt文件内容如下:
1 2014-8-9 14:40:41 2 2014-8-9 14:40:42 3 2014-8-9 14:40:43 4 2014-8-9 14:40:44 5 2014-8-9 14:40:48 6 2014-8-9 14:40:49 7 2014-8-9 14:40:50 |
原型:char *fgets(char *s, int size, FILE *stream)
原型:int fseek(FILE *stream, long offset, int whence)
对以下两个不同文件内容:
文件1只有1行数据(1 2014-8-9 15:15:55)并手动输入回车跳到文件1的第二行。文件2的每行内容是由fprintf输出的,行尾带回车。文件1和文件2每行数据长度相同为len,使fp指向文件1时,fseek(fp, -len, SEEK_END)时fp指向1后面的空格。fp指向文件2时,用fseek(fp, -len,SEEK_END)时fp指向第七行(黄色数字为行号)的数字7。
用以上代码中time()和localtime()联用,由后者返回struct tm后,加上起始时间后tm_mday比实际时间多一天。
原型:fflush(FILE *stream)
因为fprintf属C标准库I/O库函数,stream指向的文件属常规文件(标准输入输出可能为行缓冲),其缓冲类型为全缓冲类型。故而在缓冲区满或程序正常结束前fprintf输出的内容全在缓冲区,在缓冲区未满时按Ctrl + C 后exit()函数没有得到运行,没有得到flush操作,故而stream指向的文件中无内容输出。所以要在每个fprintf函数后面添加ffush()函数,强制进入内核将内容输出到文件中。CBNote Over.