C语言向txt文件写入当前系统时间(Log)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/pfdvnah/article/details/102523273

读完标题,不禁会提出两个问题:1、如何进行文件的操作呢?2、如何获取系统时间呢?

下面就这两方面进行简单说明。

一、文件操作

文件操作必须遵从的过程是:打开读写关闭

如下面的代码所示,执行的操作是:打开(如果不存在该文件,就创建)文件 file.txt,向文件中写入 “文件操作成功!”,然后关闭文件。

#include <stdio.h>

int main(void) {
	FILE* stream;// 文件指针
	errno_t err;// 错误码
	char* filename = "file.txt";// 文件名
	// 打开,以在文件末尾追加(append)数据的形式打开文件filename
	err = fopen_s(&stream, filename, "a");
	if (err == 0) {
		printf("文件 %s 打开成功\n", filename);
	} else {
		printf("文件 %s 打开失败\n", filename);
	}
	// 写入数据
	if (stream != NULL) {
		// 向文件末尾追加一段文字。
		fprintf(stream, "%s", "文件操作成功!\n");
	}
	// 关闭
	if (stream != NULL) {
		// 关闭文件指针,先要判断是否为空
		err = fclose(stream);
		if (err == 0) {
			printf("文件 %s 关闭成功\n", filename);
		} else {
			printf("文件 %s 关闭失败\n", filename);
		}
	}
}

01、fopen_s函数

功能:mode 的方式打开文件 filename ,将文件指针赋值给 *pFile

语法如下:

errno_t fopen_s( FILE** pFile, const char *filename, const char *mode );

pFile:一个指向文件指针的指针,它将接收指向打开的文件的指针。
filename:文件名。
mode:文件打开的方式,可参考 链接

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

02、fprintf函数

功能: 向文件指针 stream 指向的文件写入 format 格式的数据。

语法如下:

int fprintf( FILE *stream, const char *format [, argument ]... );

stream:文件指针。
format:格式控制字符串。
argument:可选参数。

返回值: 写入到文件的字节数,通常用不到,可忽略。

说明:

  1. 和 printf 函数非常相似,区别是第一个参数,是文件指针,而 printf 的文件指针是标准输出设备。
  2. 不止这一个函数可以写操作,还有 fwrite 函数,fputs 函数等等。

03、fclose函数

功能: 关闭文件指针 stream

语法如下:

int fclose( FILE *stream );

stream:文件指针。

返回值: 如果文件关闭成功,则返回 0,否则返回 EOF


通过上述文件操作的代码和说明,我们已经学会了如何向txt文件写入一个字符串。

那么现在要考虑的问题是 如何获取时间 并将时间转为字符串。

二、获取时间

获取时间的过程是:先获取系统时间,然后转换成本地时间。最后将时间转成字符串(方便写入文件中)。

下面代码的功能是获取当前时间并输出到标准输出设备。

代码示例:

#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("无法转换为本地时间\n");
		exit(1);
	}
	// 将时间转换为字符串,自定义格式
	strftime(timebuf, 21, "%Y/%m/%d %T%n", &today);
	printf(timebuf);
}

执行结果示例:

2019/10/16 22:46:20

01、time函数

功能: 获取系统时间保存到 time_t 型变量中。

语法如下:

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

destTime:指向时间戳的指针。

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

02、_localtime64_s函数

功能: 将时间戳转换成本地时间的结构体。后者更容易使用。

语法如下:

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

tmDest:本地时间结构体指针。
sourceTime:指向时间的存储位置的指针。

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

03、strftime函数

功能: 按照 format 指定的格式将 timeptr 指向的结构体内的数据依次填充到字符串 strDest 中。

语法如下:

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

strDest:保存时间的字符串指针。
maxsize:strDest指向的大小。
format:格式控制字符串。
timeptr:本地时间结构体。

返回值: 返回填充的字节数,如果超过了 maxsize,返回 0


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

不会也没关系,下面的代码是封装好的。复制到项目中就可以直接调用。

三、完整代码

先来看一下函数原型,这四个函数可以调用。

01、函数原型

// 功能:向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);

02、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);

03、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\n", 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, "\n");
}

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\n", 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\n", 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\n", error_close);
			exit(-1);
		}
	}
}

四、测试示例

log.jpg

- End -

猜你喜欢

转载自blog.csdn.net/pfdvnah/article/details/102523273