在 C++ 中实现 time_t 的错误代码

Error code with implementation of time_t in C++

time_t rawtime;
struct tm * timeinfo;

time(&rawtime);
timeinfo = localtime(&rawtime);

heure_= timeinfo->tm_hour;
minute_ = timeinfo->tm_min;
seconde_ = timeinfo->tm_sec;
jourMois_ = timeinfo->tm_mday;
jourSemaine_ = timeinfo->tm_wday;
mois_ = timeinfo->tm_mon;
annee_ = timeinfo->tm_year;

这是我对查找时间、日期...等功能的实现。

我不知道为什么,但我收到错误消息:

1>c:\users\sebastien\blabla: warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data

1> DateHeure.cpp

1>c:\users\sebastien\blabla-> error C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

1> c:\program files (x86)\microsoft visual studio

12.0\vc\include\time.inl(112) : see declaration of 'localtime'

我试图将本地时间更改为 localtime_s,但我收到一些关于与“tm”类型参数的兼容性的错误消息。

我也尝试过(包括或赖特)__CRT_SECURE_NO_WARNINGS 但没有成功 -> 我不知道,但只包括这一行似乎很奇怪(在属性>c++>预处理器>未定义的预处理器定义中) 不添加任何其他内容。

承认我对 Visual Studio 不是很熟悉,所以我不确定所有这些属性设置和调整。

但如果有人能帮我解决这个问题,我将不胜感激,我认为这是我唯一的错误,我会在之后进行调试。

请提供一些有关原因的信息...我想了解一下。

C4996 不应该是一个错误,我想你调整了你的编译选项使其成为一个错误。 (或者 project wizard did

无论如何,不​​使用静态本地缓冲区的备用函数更好,而且它们也是可移植的(除了名称之外,在 Win32 上是 localtime_s,在 Linux,宏可以修复),所以没有理由不使用它们。

没有静态本地缓冲区的版本希望您提供一个缓冲区,这很容易:

time_t rawtime;
struct tm timeinfo;  // no longer a pointer

time(&rawtime);

// on platforms with POSIX localtime_r but no localtime_s, add this macro
// #define localtime_s(x, y) localtime_r(y, x)
localtime_s(&timeinfo, &rawtime); // fills in your structure,
                                  // instead of returning a pointer to a static one

heure_= timeinfo.tm_hour;  // no longer using a pointer
minute_ = timeinfo.tm_min;
seconde_ = timeinfo.tm_sec;
jourMois_ = timeinfo.tm_mday;
jourSemaine_ = timeinfo.tm_wday;
mois_ = timeinfo.tm_mon;
annee_ = timeinfo.tm_year;

localtime 函数可能不安全,因为它 returns 指向一个用于自身和其他调用的结构的指针。这意味着如果您调用一个函数来更改该内部结构,则指向它的所有指针都会反映新数据。

如果您知道这一点,并且可以确保数据在您用完之前不会被修改,那么您仍然可以安全地使用它。在这种情况下,您可以这样做:

#define _CRT_SECURE_NO_WARNINGS 1
#include <ctime>
#include <iostream>

int main()
{
    time_t rawtime = time(nullptr);
    tm* timeinfo = localtime(&rawtime);

    std::cout << asctime(timeinfo) << "\n";
    return 0;
}

如果您希望使用更安全的 localtime_s 来填充您传入的不会意外更改的结构,那么您可以像这样使用它:

#include <ctime>
#include <iostream>

int main()
{
    time_t rawtime = time(nullptr);
    tm timeinfo;
    errno_t error = localtime_s(&timeinfo, &rawtime);
    if(error != 0)
    {
        std::cerr << "localtime_s failed.\n";
        return -1;
    }

    std::cout << asctime(&timeinfo) << "\n";
    return 0;
}

请记住,localtime_s 可能并非在所有平台上都可用,因此它的便携性可能较差。