gpt4 book ai didi

使用 _stscanf_s C 库函数转换成功,但实际上失败

转载 作者:行者123 更新时间:2023-11-30 16:59:16 27 4
gpt4 key购买 nike

这个问题有一个内置的答案,但无论如何我想分享这个小小的 war 故事,希望它能对其他人有所帮助......

给定输入“20160708”,您看到以下 C 语句有什么问题吗?这些代码摘自一些检查软件更新是否可用的代码...

struct tm ParseTime;
memset(&ParseTime, 0, sizeof(ParseTime));

// Extract date information
int ScanResult = _stscanf_s(UTCDate, _T("%4i%2i%2i"),
&ParseTime.tm_year, &ParseTime.tm_mon, &ParseTime.tm_mday);

if (ScanResult != 3)
DEBUG_MESSAGE(MB_OK | MB_ICONERROR, _T("Debug: Unexpected Error"),
_T("ConvertUTCDateTime - could not scan UTCDate = '%s', ScanResult = %d"),
UTCDate, ScanResult);

一开始我们也没有。并且上述代码已经多次通过系统测试。

但在 7 月 8 日,它在后面的断言语句中引发了异常,但没有发出 DEBUG_MESSAGE。

调试显示,尽管 ScanResult 加载了预期值 3,这意味着 3 个字段已成功转换,但 ParseTime.tm_mday 字段实际上加载了 0,这是一个无效的月份数字!

但是“i”格式说明符表示“整数”,对吧?那么问题出在哪里呢?

最佳答案

我们想到要查找它......

来自 C 库文档 ( https://msdn.microsoft.com/en-us/library/6ttkkkhh.aspx )

i - An integer.

Hexadecimal if the input string begins with "0x" or "0X",
octal if the string begins with "0", otherwise decimal.

好的,“一个整数”。没关系,对吧?

但是...

阅读整个描述...八进制?!?我们这里是 1970 年代的复古!

没错,“0”字符既会导致转换为八进制,又会继续转换为零。然后转换在无效(八进制)“8”或“9”字符处停止,这意味着上述代码仅在该月的第 8 号和第 9 号或第 8 号或第 9 个月以最坏的方式失败!

具有“%2i”格式规范的 scanf 是否应该认为“08”或“09”的转换成功是有争议的,但事实上它确实如此 - 无论如何使用当前的 Microsoft CRT 库。

解决方法当然是使用“%4u%2u%2u”作为格式说明符,它显式选择十进制转换。

故事的寓意...始终读到段落末尾。

要么在本月 8 日或 9 日,要么在 8 月或 9 月发布新软件。 :-)

关于使用 _stscanf_s C 库函数转换成功,但实际上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38284081/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com