如何以" Safe "的方式获取 C++ 中的当前时间
How to get the current time in c++ in a " Safe " way
我对C++并不陌生,但我大多只使用最基本的标准库功能,如<iostream>
、<vector>
、<map>
等。
现在,我正在开发一个简单的游戏,我正在研究一个记录器类,但我坚持获取当前时间。
不要误会我的意思,我已经看到了很多方法可以在StackOverflow和Google中获取时间,但根据Visual Studio的说法,它们都不是"安全的"。 例如,当我使用asctime()
或ctime()
时,我收到此错误:
['ctime':此函数或变量可能不安全。请考虑改用ctime_s。要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。有关详细信息,请参阅联机帮助]。
但是当我尝试以好的方式做到这一点并使用安全版本时,我发现它们更加复杂,例如这是ctime()
函数:
ctime(const time_t *const_time)
与ctime_s()
相比:
ctime_s(char *const _Buffer, const size_t _SizeinBytes,const time_t *const _Time)
再次在互联网上查找对我没有帮助,所以我在这里,询问你们如何获取当前时间,我的意思是使用"安全"方法10:20
或类似的东西。
Modern C++ 具有用于时间提取和操作目的的<chrono>
标头,一旦你理解了它,它就比传统的 C 东西好得多:
#include <iostream>
#include <chrono>
#include <ctime>
int main() {
auto start = std::chrono::system_clock::now();
auto legacyStart = std::chrono::system_clock::to_time_t(start);
std::cout << std::ctime(&legacyStart) << 'n';
}
这可以通过多种方式使用,包括(如图所示(输出日期的字符串表示形式。我意识到对于这个简单的案例来说,这不是必需的,但如果你不想被称为 C+ 编码员(a(,建议您搬到<chrono>
。
如果您可以使用 C++20,则尤其如此,因为该迭代包括日历功能(用于日期(和时间功能(用于将自午夜以来的持续时间拆分为小时、分钟和秒等单个组件(。
如果你可以开始使用它们,你将永远不再需要传统的C东西:-(
关于这是否不安全,我认为Microsoft经常对编码人员做出这个决定造成伤害。我实际上关闭了这些警告,因为我知道所涉及的风险,并且知道如何避免问题。
无论如何,我相信我在某个时候读到s
是为了安全而不是安全,因为例如,如果您将错误的长度传递给它们,某些替换功能是不安全的:
char dest[10];
strcpy_s(dest, 100, "13 characters");
毫无疑问,有些人会说这是编码人员的错,因为他们应该知道自己在做什么,但对于所谓的不安全功能,也可以提出同样的论点。
ctime()
的具体问题是允许它返回内部缓冲区的地址,该地址可能会在下次调用时被覆盖(这也可能包括在您完成之前调用它的另一个线程(。
如果您知道自己的使用模式(包括您使用的任何第三方内容(,则可以轻松使用ctime()
而不会出现问题。
但是,在这种情况下,使用更安全的变体并不难
,例如:#include <iostream>
#include <chrono>
#include <ctime>
int main() {
auto start = std::chrono::system_clock::now();
auto legacyStart = std::chrono::system_clock::to_time_t(start);
char tmBuff[30];
ctime_s(tmBuff, sizeof(tmBuff), &legacyStart);
std::cout << tmBuff << 'n';
}
尽管您可能需要考虑使用strftime
以便更好地控制输出格式(例如"yyyy-mm-dd hh:mm:ss"(,从而保证生成的字符串适合缓冲区(。
(a(那个奇怪的品种,从来没有完全从C过渡到C++:-(
asctime()
和ctime()
函数是"不安全的",因为它们返回指向静态缓冲区的指针,这些缓冲区可能是线程安全的,也可能不是线程安全的,具体取决于实现,如果它们不是线程安全的,那么它们可能会在您有机会使用它们之前被其他线程覆盖。
"更安全"的asctime_s()
和ctime_s()
函数写入您必须提供的预分配缓冲区,例如:
time_t now = time(NULL);
//char *str = asctime(localtime(&now));
tm now_tm = {};
char str[26] = {};
localtime_s(&now_tm, &now);
asctime_s(str, 26, &now_tm);
// use str as needed...
time_t now = time(NULL);
//char *str = ctime(&now);
char str[26] = {};
ctime_s(str, 26, &now);
// use str as needed...
- C++为构建时间获取QDateTime的可靠方法
- 从持续时间构造std::chrono::system_clock::time_point
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- while循环中while循环的时间复杂度是多少
- 使用简单类型列表实现的指数编译时间.为什么
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在已经使用Git的情况下减少编译时间
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 从文本文件中读取时钟时间和事件时间并进行处理
- 具有未知值时的时间复杂性
- 如何减少花费的时间
- C++在变量给定的指定时间内关闭电脑
- rcpp函数中的清理时间很长
- C++:floor unix时间戳到UTC月份
- 如何在c++中录制具有精确帧时间戳的视频
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- KMP算法和LPS表构造的运行时间
- 为什么std::互斥需要很长的、非常不规则的时间来共享
- 使用Boost Interprocess创建托管共享内存需要很长时间