这个问题附带内置答案,但无论如何,我想分享这个小小的战争故事,看看它有可能帮助别人......
如果输入" 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日,它在后来的assert语句中引发了异常而没有发出DEBUG_MESSAGE。
调试显示,即使ScanResult加载了预期值3,意味着成功转换了3个字段,ParseTime.tm_mday字段实际上加载了0,这是一个无效的月份数字!
但是'我'格式说明符表示"整数",对吗?那么问题是什么?
答案 0 :(得分:0)
我们突然想到了......
来自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.
好的,"一个整数"。没关系,对吗?
<强>可是... 强>
阅读整个说明...... OCTAL?!?我们这里有一个回溯到20世纪70年代!
没错,&#39; 0&#39;字符都导致转换转换为八进制,并继续转换为零。然后转换将停止在无效(对于八进制)&#39; 8&#39;或者&#39; 9&#39;字符,意思是上述代码仅在本月8日和9日或者在第8个月或第9个月以最坏的方式失败!
是否使用&#34;%2i&#34;扫描是否有争议?格式规范应考虑转换&#34; 08&#34;或&#34; 09&#34;那么,实际上它确实是成功的 - 无论如何都是当前的Microsoft CRT库。
当然,修复是使用&#34;%4u%2u%2u&#34;对于格式说明符,它明确选择十进制转换。
故事的道德......始终一直读到段落的末尾。
要么在本月的8日或9日,也要在8月或9月发布新软件。 : - )