zoukankan      html  css  js  c++  java
  • C语言向txt文件写入当前系统时间(Log)

    程序实现很简单,涉及到的只有两个知识点。

    1、文件最最基本的打开关闭;
    2、系统时间的获取。

    代码是在VS2019环境下编写的,部分函数在其他编译器中会无法识别。这个就只能需要自己去查找对应的函数简单修改即可。

    如果遇到问题,欢迎大家提出来一起讨论。

    文件操作:

    先来介绍一下 文件操作 的基本方法。
    操作文件必须遵从的过程是:打开读写关闭
    一个文件首先要知道的是 文件名,当然你也可以新建一个文件。
    如果是不同路径下的文件,还需要知道文件的路径。为了方便,本文采用同一目录下操作来说明。

    只知道文件名并没什么用处,重要的是要通过文件名得到 文件结构体 FILE 的变量,里面会保存文件的一些基本但重要的信息。然后通过它来进行下一步的读写。

    先来看一下文件操作的简单代码示例,后面再介绍函数的功能。

     1 #include <stdio.h>
     2 
     3 int main(void) {
     4     FILE* stream;// 文件指针
     5     errno_t err;// 错误码
     6     char* filename = "file.txt";// 文件名
     7     // 打开,以在文件末尾追加(append)数据的形式打开文件filename
     8     err = fopen_s(&stream, filename, "a");
     9     if (err == 0) {
    10         printf("文件 %s 打开成功
    ", filename);
    11     } else {
    12         printf("文件 %s 打开失败
    ", filename);
    13     }
    14     // 读写
    15     if (stream != NULL) {
    16         // 向文件末尾追加一段文字。
    17         fprintf(stream, "%s", "文件操作成功!
    ");
    18     }
    19     // 关闭
    20     if (stream != NULL) {
    21         // 关闭文件指针,先要判断是否为空
    22         err = fclose(stream);
    23         if (err == 0) {
    24             printf("文件 %s 关闭成功
    ", filename);
    25         } else {
    26             printf("文件 %s 关闭失败
    ", filename);
    27         }
    28     }
    29 }
    打开文件用到的是 fopen_s 函数,函数语法如下:
    errno_t fopen_s(
       FILE** pFile,			// 一个指向文件指针的指针,它将接收指向打开的文件的指针。
       const char *filename,	// 文件名
       const char *mode			// 文件打开的方式,方式有很多种,可参考上面的链接。
    );
    

    如果打开成功返回 0,否则返回相应的错误码。

    写数据用到的函数是 fprintf,语法如下:

    int fprintf(
       FILE *stream,			// 文件指针
       const char *format [,	// 格式控制字符串
       argument ]...			// 可选参数
    );
    

    类似 printf 函数,只不过多了个文件指针而已。很好理解。
    返回值是写入的字节数,通常用不到,可忽略。
    当然,不止这一个函数可以写操作,还有 fwrite 函数,fputs 函数等等。

    关闭文件用的是 fclose 函数,语法如下:

    int fclose(
       FILE *stream		// 文件指针
    );
    

    关闭成功,返回 0,错误返回 EOF

    有了上面这些知识,你就可以向文件写入一个 Hello World 了。其实还有很多内容,但是如标题所示,现在要写的是时间。是个字符串,只需要用到这些内容。其他的可参考 UCRT alphabetical function reference

    获取时间:

    现在来看看怎么获取当前时间。直接上代码,再说明函数语法(其实看注释就够了)。

    #include <stdio.h>
    #include <time.h>
    
    int main(void) {
    	char timebuf[21];// 字符串形式保存时间
    	time_t ltime;// 时间戳
    	struct tm today;// 本地时间结构体
    	errno_t err;// 错误码
    	
    	time(&ltime);// 获取系统时间
    	err = _localtime64_s(&today, &ltime);// 转换为本地时间
    	if (err != 0) {
    		printf("无法转换为本地时间
    ");
    		exit(1);
    	}
    	// 将时间转换为字符串,自定义格式
    	strftime(timebuf, 21, "%Y/%m/%d %T%n", &today);
    	printf(timebuf);
    }
    

    用到的函数有:time_localtime64_sstrftime

    time 语法如下:

    time_t time( time_t *destTime );	// 获取系统时间,参数是指向时间的存储位置的指针
    

    返回值是从 1970/01/01 00:00:00 以来经过的秒数。有错误返回 -1

    _localtime64_s 语法如下:

    errno_t _localtime64_s(
       struct tm* tmDest,				// 指向要填充的时间结构体
       __time64_t const* sourceTime		// 指向时间的存储位置的指针
    );									// 将时间转换为本地时间结构体
    

    转换成功返回 0,否则返回对应的错误码。

    strftime 语法如下:

    size_t strftime(
       char *strDest,				// 保存时间的字符串
       size_t maxsize,				// strDest指向的大小
       const char *format,			// 格式控制串,参照使用手册。
       const struct tm *timeptr		// 时间结构体
    );
    

    返回填充的字符数,如果超过了 maxsize,返回 0


    到这里差不多就已经掌握了简单的写入时间操作。可以试试自己写一写。

    不会也没关系,下面的代码是封装好的。可以直接调用。

    函数原型:

    // 功能:向txt文件filename末尾追加格式为YYYY/MM/DD HH:MM:SS的时间
    // filename是文件名,文件名本身不带双引号
    void log_time_filename(char const* filename);
    
    // 功能:向stream指向的文件末尾追加格式为YYYY/MM/DD HH:MM:SS的时间
    // stream必须打开
    void log_time_stream(FILE* stream);		// 参数是文件指针
    
    // 功能:向txt文件filename末尾追加格式为YYYY/MM/DD HH:MM:SS的时间并换行
    // filename是文件名,文件名本身不带双引号
    void log_time_line_filename(char const* filename);
    
    // 功能:向stream指向的文件末尾追加格式为YYYY/MM/DD HH:MM:SS的时间并换行
    // stream必须打开
    void log_time_line_stream(FILE* stream);
    

    log.h文件:

    将代码保存到与 调用文件 在同一级目录下的 log.h 文件中。有四个外部函数可供调用。

    /*********************************************************************
    	文件:	log.h
    	环境:	Windows 10
    	IDE:	Visual Studio 2019
    	版本:	1.5.0.1910
    	功能:	1、向 <文件名.txt> 文件末尾追加当前系统时间
    			2、向 <FILE* stream> 指向的文件末尾追加当前系统时间
    	备注:	1、目前只有默认日期格式,即YYYY/MM/DD hh:mm:ss
    			2、支持换行和不换行两种形式
    	日期:	2019年10月16日15:42:15
    	作者:	wowpH
    *********************************************************************/
    #pragma once
    #pragma message("log.h - wowpH - 1.5.0.1910")
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    // 时间格式的最大长度
    #define MAX_TIME_MODE_SIZE 21
    
    //
    //	可调用的函数
    //
    
    // 通过文件名追加时间
    void log_time_filename(char const* filename);
    
    // 通过文件指针追加时间
    void log_time_stream(FILE* stream);
    
    // 通过文件名追加时间,换行
    void log_time_line_filename(char const* filename);
    
    // 通过文件指针追加时间,换行
    void log_time_line_stream(FILE* stream);
    
    //
    // 供内部使用的函数,外部调用可能出错
    //
    
    // 向strDest写入当前时间
    void get_local_time(char* strDest);
    
    // 打开文件
    void open_file(FILE** stream, char const* filename);
    
    // 关闭文件
    void close_file(FILE* stream);
    

    log.c文件:

    将代码保存到与 调用文件 同一级目录下的 log.c 文件中。

    #include "log.h"
    
    const char* null_stream = "文件指针为空,请先打开一个文件!";
    const char* error_open = "文件打开失败!";
    const char* error_close = "文件关闭失败!";
    const char* error_to_localtime = "无法转换为本地时间!";
    
    void log_time_filename(char const* filename) {
    	FILE* stream = NULL;
    	open_file(&stream, filename);
    	log_time_stream(stream);
    	close_file(stream);
    }
    
    void log_time_stream(FILE* const stream) {
    	if (stream != NULL) {
    		char time[MAX_TIME_MODE_SIZE];
    		get_local_time(time);
    		fprintf(stream, "%s", time);
    	} else {
    		printf("%s
    ", null_stream);
    		exit(-1);
    	}
    }
    
    void log_time_line_filename(char const* filename) {
    	FILE* stream = NULL;
    	open_file(&stream, filename);
    	log_time_line_stream(stream);
    	close_file(stream);
    }
    
    void log_time_line_stream(FILE* stream) {
    	log_time_stream(stream);
    	fprintf(stream, "
    ");
    }
    
    static void get_local_time(char* strDest) {
    	time_t ltime;
    	time(&ltime);
    	struct tm today;
    	errno_t err;
    	err = _localtime64_s(&today, &ltime);
    	if (err != 0) {
    		printf("%s
    ", error_to_localtime);
    		exit(-1);
    	}
    	// 将时间转换为字符串,自定义格式
    	strftime(strDest, MAX_TIME_MODE_SIZE, "%Y/%m/%d %T", &today);
    }
    
    static void open_file(FILE** stream, char const* filename) {
    	errno_t err = 0;
    	err = fopen_s(stream, filename, "a");
    	if (err != 0) {
    		printf("%s
    ", error_open);
    		exit(-1);
    	}
    }
    
    static void close_file(FILE* stream) {
    	if (stream != NULL) {
    		errno_t err = 0;
    		err = fclose(stream);
    		if (err != 0) {
    			printf("%s
    ", error_close);
    			exit(-1);
    		}
    	}
    }
    

    执行结果:

    log.jpg

  • 相关阅读:
    重定向是否可以重定向到post接口
    ForkJoin(工作窃取)初步使用,计算偶数集合
    Dubbo服务的三种发布模式
    mysql开启慢查询日志
    Hashmap的结构,1.7和1.8有哪些区别
    idea回滚已经push的代码
    rabbitmq集群安装配置
    restful好处,表单提交put/delete
    BIO/NIO/AIO待完成
    判断一个对象是否可以被回收
  • 原文地址:https://www.cnblogs.com/wowpH/p/11687385.html
Copyright © 2011-2022 走看看