【问题标题】:strftime() fails on Raspberry Pi (Raspbian)strftime() 在 Raspberry Pi (Raspbian) 上失败
【发布时间】:2015-05-05 19:03:37
【问题描述】:

下面的程序不适用于我的 Raspberry Pi。 strftime() 返回 0 并且变量未设置。这个确切的代码在 AS/400 上编译和工作得很好。有趣,但红帽也有问题。我在 400 上得到的输出是

currentTime=1430852224                                
tm=SPP:0000 :1aefQP0ZSPWT  BEAK      093275 :8840:0:13
tm->year=115                                          
tm->mon=4                                             
tm->mday=5                                            
tm->tm_hour=18                                        
tm->tm_min=57                                         
tm->tm_sec=4                                          
i=20, ctimeStr=2015-05-05T18:57:04Z                   
i=13, ctimeStr=2015 18:57:04                          
timeStr=2015 18:57:04                                 

在树莓上:

currentTime=1430852359
tm=0xb6dd9264
tm->year=115
tm->mon=4
tm->mday=5
tm->tm_hour=18
tm->tm_min=59
tm->tm_sec=19
i=0, ctimeStr=
i=0, ctimeStr=
timeStr=

我可能正盯着我的问题,但我没有看到它。

#include <iostream>
#include <string>
#include <string.h>
#include <sstream>
#include <iomanip>
#include <time.h>

using namespace std;

static void GetUTCTimeStr(string& timeStr)
{
    time_t currentTime;
    struct tm *tm;

    currentTime = time(0);
    cout << "currentTime=" << currentTime << endl;

    tm = gmtime(&currentTime);
    cout << "tm=" << tm << endl;
    cout << "tm->year=" << tm->tm_year << endl;
    cout << "tm->mon=" << tm->tm_mon << endl;
    cout << "tm->mday=" << tm->tm_mday << endl;
    cout << "tm->tm_hour=" << tm->tm_hour << endl;
    cout << "tm->tm_min=" << tm->tm_min << endl;
    cout << "tm->tm_sec=" << tm->tm_sec << endl;

    if (tm != 0) {
        char ctimeStr[25];
        size_t i = strftime(ctimeStr, sizeof(timeStr) - 1, "%FT%TZ", tm);
        cout << "i=" << i << ", ctimeStr=" << ctimeStr << endl;
        i = strftime(ctimeStr, sizeof(timeStr) - 1, "%Y %T", tm);
        cout << "i=" << i << ", ctimeStr=" << ctimeStr << endl;
        timeStr = ctimeStr;
    }
    else {
        cout << strerror(errno) << endl;
    }
}


int main(int argc, char* argv[])
{
    string timeStr;
    GetUTCTimeStr(timeStr);
    cout << "timeStr=" << timeStr << endl;
}

我不知道去哪里找,但我应该说 Pi 上的 locale 命令会产生以下结果:

LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8" 
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

在 AS/400 上:

LANG=/QSYS.LIB/EN_US.LOCALE
LC_COLLATE=                
LC_CTYPE=                  
LC_MESSAGES=               
LC_MONETARY=               
LC_NUMERIC=                
LC_TIME=                   
LC_ALL=                    

【问题讨论】:

  • 如果 i = 0 打印 errno。
  • 在 Red Hat 上,“%Y-%m-%dT%H:%M:%SZ”会导致打印“2015-”和一些图形字符。

标签: c++ linux time strftime


【解决方案1】:

缓冲区可能太小了——或者这就是strftime 的想法。你写道:

strftime(ctimeStr, sizeof(timeStr) - 1, "%FT%TZ", tm);

但你需要:

strftime(ctimeStr, sizeof(ctimeStr) - 1, "%FT%TZ", tm);

根据std::string 的大小,它可能似乎在某些平台上工作 - 但只会造成可能的缓冲区溢出。

【讨论】:

  • 是的,考虑到sizeof(std::string) 非常小。
  • @tadman 不一定——小字符串优化实际上会导致一些“更大”的std::string 对象。无论如何,它是老式 API 上的简单拼写错误导致缓冲区溢出问题以及其他任何可能出错的典型案例之一。
  • 我的意思是它是所有意图和目的的随机值,在这种情况下似乎是 4 或 5 个字节。具有极其相似名称的变量是这里问题的一部分。 strftime 的最佳 C++ 替代方案是什么,可以避免使用固定长度的缓冲区?
  • 就像我说的,我可能正盯着它看。谢谢大家的关注。
  • @KellyBeard 在解决问题时,您应该使缓冲区大于 25。当您尝试猜测所需的确切缓冲区大小时,您玩得太靠近边缘了。我见过太多的程序崩溃,因为试图找出类似这样的事情的确切缓冲区大小,只是让缓冲区溢出一个或两个字节。
【解决方案2】:

你有一个错字:

size_t i = strftime(ctimeStr, sizeof(timeStr) - 1, "%FT%TZ", tm);
                                     ^^^^^^

你想要sizeof(ctimeStr)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2015-01-12
    • 1970-01-01
    • 2023-01-18
    相关资源
    最近更新 更多