ynn*_*ynn 0 c++ language-lawyer
当你写int i; cin >> i;输入00325或325,两者的投入表现得像i = 325;.但为什么?我认为如果你输入i的价值设定为更自然,那么下一个产生了,而下一个产生了.我知道可以是八进制数,但我现在输入数字作为十进制数(我不使用操纵器).000325cin >>i;i = 0;cin >> i;i = 325;00325oct
什么书面证据保证了这种行为?我快速浏览了N4140,却找不到任何证据.
注意:我想要的是不知道在输出时保持前面的零的方法,这在使用cout << operator时如何用前导零填充int中讨论?.
一旦有人给我这样的句子,我的问题就会得到解决
preceding zeros are ignored when setting a number-type object as the right operand of <<
在一些可靠的文件中.
警告: 非常无聊的回答
C++ 14 [istream.formatting.arithmetic]3
Run Code Online (Sandbox Code Playgroud)operator>>(int& val);转换发生时好像由以下代码片段执行(使用与前面的代码片段相同的表示法):
Run Code Online (Sandbox Code Playgroud)typedef num_get<charT,istreambuf_iterator<charT,traits> > numget; iostate err = ios_base::goodbit; long lval; use_facet<numget>(loc).get(*this, 0, *this, err, lval); if (lval < numeric_limits<int>::min()) { err |= ios_base::failbit; val = numeric_limits<int>::min(); } else if (numeric_limits<int>::max() < lval) { err |= ios_base::failbit; val = numeric_limits<int>::max(); } else val = static_cast<int>(lval); setstate(err);
这里的咕噜声完成了num_get::get,在[facet.num.get.members]中指定了1:
Run Code Online (Sandbox Code Playgroud)iter_type get(iter_type in, iter_type end, ios_base& str, ios_base::iostate& err, long& val) const;[...] 返回:
do_get(in, end, str, err, val).
do_get然后立即定义([facet.num.get.virtuals]),其中详细说明了整个shebang的确切运作.我不会复制三页的痛苦,而只是重点.
在阶段1中,根据流标志确定"等效的stdio格式说明符",如表85和86所示; std::ios_baseis 的默认值dec | skipws,所以我们将遵循该路径(对应于%d).此外,还为下一阶段确定了一些其他区域设置和特定于标志的字符.
在阶段2中,从流中读取字符并将其累积在缓冲器中; 你问题的关键点在于
如果它没有被丢弃,则进行检查以确定是否
c允许作为阶段1返回的转换说明符的输入字段的下一个字符.如果是,则累积它
因此,决定是继续阅读你的零还是在一个零之后停止取决于%d上述情况; 我们会回到它.
在阶段3中,累积的字符最终转换为a long
通过标题中声明的其中一个函数的规则
<cstdlib>:
- 对于有符号整数值,该函数
strtoll.
说明%d符和strtollC语言都定义了(C++ 14指的是C99); 让我们把它们挖出来.
在C99§7.19.6.212(谈论时fscanf),它被告知
d匹配可选带符号的十进制整数,其格式与strtol函数的主题序列的预期相同,base参数值为10 .
所以这一切归结为strtol/ strtoll,我们可以在C99§7.20.1.4找到.指定跳过最长的空白序列,然后考虑"主题序列":
如果值
base为零,则主题序列的预期形式是如6.4.4.1中所述的整数常量的形式,可选地前面带有加号或减号,但不包括整数后缀.如果值base介于2和36之间(包括),则主题序列的预期形式是字母和数字序列,表示具有指定基数的整数base,可选地前面带有加号或减号,但不包括整数后缀.来自a(或A)到z(或Z)的字母归属于值10到35; 只允许其归属值小于基数的字母和数字.如果值为base16,则字符0x或0X可选地在字母和数字序列之前,如果存在则在符号之后.主题序列被定义为输入字符串的最长初始子序列,从第一个非空白字符开始,即预期形式.如果输入字符串为空或完全由空格组成,或者第一个非空白字符不是符号或允许的字母或数字,则主题序列不包含任何字符.
如果主题序列具有预期形式且值
base为零,则根据6.4.4.1的规则将以第一个数字开头的字符序列解释为整数常量.如果主题序列具有预期形式并且值base在2和36之间,则将其用作转换的基础,将其值归于每个字母,如上所述.如果主题序列以减号开头,则转换产生的值将被否定(在返回类型中).
(ibidem,3-5)
如您所见,对于前导零没有特殊规定; 如果它是一个有效的数字,它将进入主题序列,在同一批次中进行处理.
| 归档时间: |
|
| 查看次数: |
231 次 |
| 最近记录: |