【问题标题】:asctime - day of month zero or space padded?asctime - 零月份的日期或空格填充?
【发布时间】:2018-12-22 08:28:46
【问题描述】:

我有以下程序演示asctime 的使用。

#include <stdio.h>
#include <time.h>

int main(void) {
    struct tm   broken_down;
    broken_down.tm_year = 2000 - 1900;
    broken_down.tm_mon = 0;
    broken_down.tm_mday = 1;
    broken_down.tm_hour = broken_down.tm_min = broken_down.tm_sec = 0;

    printf("Current date and time: %s", asctime(&broken_down));
}

此程序在ideone.com 上打印Current date and time: Sun Jan 1 00:00:00 2000,即日期字段是用空格填充的。

当我用 MSVC 编译和运行这个程序时,它会在月份中生成带有前导零的日期字符串:Current date and time: Sun Jan 01 00:00:00 2000

造成这种差异的原因是什么?哪种格式正确?

【问题讨论】:

    标签: c visual-c++ language-lawyer msvcrt time.h


    【解决方案1】:

    像往常一样,微软(非)标准 C 库的作者没有考虑过正确实现标准字母。

    即使在原始标准C89/C90 中也会出现以下文字

    说明

    asctime 函数转换结构中的故障时间 timeptr 指向的字符串形式为

    Sun Sep 16 01:03:52 1973\n\0
    

    使用以下算法的等价物。

    char *asctime(const struct tm *timeptr)
    {
        static const char wday_name[7][3] = {
                 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
        };
        static const char mon_name[12][3] = {
                 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
        };
        static char result[26];
    
        sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
                 wday_name[timeptr->tm_wday],
                 mon_name[timeptr->tm_mon],
                 timeptr->tm_mday, timeptr->tm_hour,
                 timeptr->tm_min, timeptr->tm_sec,
                 1900 + timeptr->tm_year);
        return result;
    }
    

    不幸的是,该示例本身使用了一个具有 2 位日期的日期,但代码使用了 %3d,这意味着一个十进制数字 在 3 个字符宽的字段中用空格填充并右对齐。

    给定分解时间的结果是Sun Jan 1 00:00:00 2000,带有空格填充。


    Python 2,在 2.7.15 之前一直公开 C 标准库 asctime 输出原样,减去导致平台相关行为的换行符,现在在 2.7.15 中已修复为使用硬带前导空格的编码格式。 Python 2 文档在其示例中也使用了带有 2 位月份日期的日期,这进一步增加了混乱。

    【讨论】:

    • 不同意“没有考虑太多来正确执行标准的字母。”。 “造成这种差异的原因是什么?” --> 看起来像EEE
    • @chux 好吧...... Hanlon 的剃须刀 - 也许他们已经 30 年没有注意到它了。
    • 我怀疑 source 错误的来源是由于 Hanlon's razor,但差异的持续是故意的 exploit..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2017-10-19
    相关资源
    最近更新 更多