VoI*_*oId 2 c++ time c++-chrono
我对 C++ 并不陌生,但我大多只使用最基本的标准库功能,如<iostream>、<vector>、<map>等。
现在,我正在开发一个简单的游戏,并且正在开发一个记录器类,但我一直在获取当前时间。
不要误会我的意思,我在 StackOverflow 和 Google 上见过很多获得时间的方法,但根据 Visual Studio 的说法,它们都不是“安全的”。例如,当我使用asctime()or时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或类似的东西,使用“安全”方法。
现代 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';
}
Run Code Online (Sandbox Code Playgroud)
这可以通过多种方式使用,包括(如图所示)输出日期的字符串表示形式。我意识到对于这个简单的情况来说这不是必需的,但建议您转到<chrono>,但如果您不想被称为 C+ 编码员,我们(a)。
如果您可以使用 C++20,则尤其如此,因为该迭代包括日历功能(用于日期)和时间功能(用于将自午夜以来的持续时间拆分为单独的组件,例如小时、分钟和秒)。
如果您可以开始使用它们,您将永远不再需要遗留的 C 东西:-)
关于这是否不安全,我认为微软在做出这个决定时经常损害编码员的利益。我实际上关闭了这些警告,因为我知道其中涉及的风险,并且知道如何避免问题。
无论如何,我相信我在某些时候读到的内容是为了安全而不是安全,因为如果您将错误的长度传递给s某些替换函数,那么它们是不安全的:
char dest[10];
strcpy_s(dest, 100, "13 characters");
Run Code Online (Sandbox Code Playgroud)
现在毫无疑问,有些人会说这是编码员的错,因为他们应该知道自己在做什么,但同样的论点也可以针对所谓的现在毫无疑问,有些人会说这是编码员的错,因为他们应该知道自己在做什么,但对于所谓的不安全。
具体问题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';
}
Run Code Online (Sandbox Code Playgroud)
尽管您可能需要考虑使用strftime,以便更好地控制输出格式(例如“yyyy-mm-dd hh:mm:ss”),从而保证生成的字符串适合缓冲区)。
(a)那个奇怪的品种从未完全从 C 完全过渡到 C++ :-)