如何在C++中以“安全”的方式获取当前时间 我不是C++新手,但我主要是使用最基本的标准库函数,比如,等等。

如何在C++中以“安全”的方式获取当前时间 我不是C++新手,但我主要是使用最基本的标准库函数,比如,等等。,c++,time,chrono,C++,Time,Chrono,现在,我正在做一个简单的游戏,我正在做一个日志类,但我一直在获取当前时间 别误会我的意思,我在StackOverflow和Google中看到了很多获得时间的方法,但根据VisualStudio的说法,没有一种是安全的。例如,当我使用asctime或ctime时,会出现以下错误: [ cTime]:此函数或变量可能不安全。请考虑使用cTimeSs。禁用DestRebug,使用O.CRTySeCURURIONNOI警告。参见详细信息的联机帮助]。 但是,当我尝试以良好的方式使用安全版本时,我发现它

现在,我正在做一个简单的游戏,我正在做一个日志类,但我一直在获取当前时间

别误会我的意思,我在StackOverflow和Google中看到了很多获得时间的方法,但根据VisualStudio的说法,没有一种是安全的。例如,当我使用asctime或ctime时,会出现以下错误:

[ cTime]:此函数或变量可能不安全。请考虑使用cTimeSs。禁用DestRebug,使用O.CRTySeCURURIONNOI警告。参见详细信息的联机帮助]。

但是,当我尝试以良好的方式使用安全版本时,我发现它们更加复杂,例如,这是ctime函数:

ctimeconst时间*常数时间

与ctime_s相比:

ctime schar*常量缓冲区、常量大小大小字节、常量时间*常量时间

再次查看互联网对我没有帮助,所以我在这里,问你们如何获取当前时间,并且我的时间是指类似10:20或类似的东西,使用安全的方法。< /P> < P>现代的C++有用于时间提取和操作的标题,一旦你理解了它,它比传统的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';
}
毫无疑问,有些人会说这是编码人员的错,因为他们应该知道自己在做什么,但对于那些被认为不安全的函数,也可以提出同样的观点

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';
}

尽管您可能想考虑使用STFFETH,这样您可以更好地控制输出格式,例如“YYYY MM DD HH:MM:SS”,因此保证所得到的字符串适合于缓冲区。 <>一个奇怪的品种,它从未完全从C到C++过渡:-< /P> < P>现代C++有一个用于时间提取和操作的头,一旦你理解了它,它就比传统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';
}
毫无疑问,有些人会说这是编码人员的错,因为他们应该知道自己在做什么,但对于那些被认为不安全的函数,也可以提出同样的观点

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';
}

尽管您可能想考虑使用STFFETH,这样您可以更好地控制输出格式,例如“YYYY MM DD HH:MM:SS”,因此保证所得到的字符串适合于缓冲区。

一个奇怪的品种,它从来没有完全从C到C++过渡:-< /P> < P> ActhTimes和cTimes函数是不安全的,因为它们返回一个指针,这些静态缓冲区可能取决于实现,或者可能不是线程安全的,如果它们不是线程安全的,那么在您有机会使用它们之前,它们可能会被其他线程覆盖

更安全的asctime和ctime函数写入您必须提供的预分配缓冲区,例如:

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...
asctime和ctime函数是不安全的,因为它们返回指向静态缓冲区的指针,这些缓冲区可能是线程安全的,也可能不是线程安全的,这取决于实现,如果它们不是线程安全的,那么在您有机会使用它们之前,它们可能会被其他线程覆盖

更安全的asctime和ctime函数写入您必须提供的预分配缓冲区,例如:

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...

微软的一些警告和弃用信息引起了一些争议,但任何涉及到指向内存指针的内容都值得避免。@KennyOstrom这并没有回答我的问题我不想要计时器我想要获取当前时间,所以我的日志将像[当前时间][日志类型][消息]或者类似的UTC时间足够了,或者你需要当地时间吗?@HowardHinnant我更喜欢当地时间对于微软的一些警告和反对消息有一些争议,但任何涉及指向内存指针的操作都是值得避免的。@KennyOstrom这并不能回答我的问题我不想要计时器我想要获取当前时间,所以我的记录器会像[当前时间][日志类型][消息]或类似的东西UTC时间足够,或者你需要本地时间吗?@HowardHinnant我更喜欢l
本地时间但是我怎么才能显示那个时间呢?我不能在这上面调用std::cout。无论如何,我可以将其转换为适合cout?@VoId std::ctime返回一个char*,只需将其分配给std::string并根据需要使用它。如果您不喜欢这样,您可以改用,或者使用@Remy,如果在存储到内部缓冲区和构造字符串之间发生线程切换,则将其转换为字符串可能没有帮助-内部缓冲区仍然可能损坏,尽管可能性不大。你对代码的看法是对的,我从两个不同的来源提取了代码,希望它现在已经修复。@paxdiablo是的,这就是为什么ctime是不安全的,而ctime_是首选的。但是我如何才能显示我不能在这个问题上调用std::cout的时间呢。无论如何,我可以将其转换为适合cout?@VoId std::ctime返回一个char*,只需将其分配给std::string并根据需要使用它。如果您不喜欢这样,您可以改用,或者使用@Remy,如果在存储到内部缓冲区和构造字符串之间发生线程切换,则将其转换为字符串可能没有帮助-内部缓冲区仍然可能损坏,尽管可能性不大。你对代码的看法是对的,我从两个不同的来源中提取了代码,希望它现在已经修复。@paxdiablo是的,这就是为什么ctime是不安全的,而ctime_是首选的。谢谢你为我工作的雷米,但你知道这是什么吗:1591408047。这就是我得到的。我知道现在是时间,但你知道我该怎么读吗this@Void:这是UNIX时间,请参见06/06/2020@1:47am UTC。@由时间返回的时间编码无效是由实现定义的,但是大多数实现将返回自POSIX纪元1970年1月1日00:00 UTC以来经过的秒数。如果您将1591408047输入,它将显示2020年6月6日星期六上午1:47:27 GMT函数,如localtime和gmttime,将时间从其本机编码转换为更可读的tm结构。谢谢您为我工作的雷米,但您知道这是什么吗:1591408047。这就是我得到的。我知道现在是时间,但你知道我该怎么读吗this@Void:这是UNIX时间,请参见06/06/2020@1:47am UTC。@由时间返回的时间编码无效是由实现定义的,但是大多数实现将返回自POSIX纪元1970年1月1日00:00 UTC以来经过的秒数。如果在中输入1591408047,它将显示2020年6月6日星期六上午1:47:27 GMT函数,如localtime和gmttime,将时间从其本机编码转换为更可读的tm结构。