Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么输入时忽略前导零?_C++_Language Lawyer - Fatal编程技术网

C++ 为什么输入时忽略前导零?

C++ 为什么输入时忽略前导零?,c++,language-lawyer,C++,Language Lawyer,当你写inti;cin>>i和输入00325或325,两个输入的行为类似于i=325。但是为什么呢?我认为如果在您输入00325时将I的值设置为0,并且下一个cin>>I,则更为自然导致i=0和下一个cin>>i导致i=325。我知道00325可以是一个八进制数,但我现在输入一个十进制数(我没有使用oct操纵器) 什么书面证据可以保证这种行为?我快速查看了N4140,但找不到任何证据 注意:我不想知道在输出时如何保持前面的零,这在使用cout时如何用前导零填充int中进行了讨论前导零不会被忽略;

当你写
inti;cin>>i和输入
00325
325
,两个输入的行为类似于
i=325。但是为什么呢?我认为如果在您输入
00325
时将
I
的值设置为
0
,并且下一个
cin>>I,则更为自然导致
i=0
和下一个
cin>>i导致
i=325。我知道
00325
可以是一个八进制数,但我现在输入一个十进制数(我没有使用
oct
操纵器)

什么书面证据可以保证这种行为?我快速查看了N4140,但找不到任何证据


注意:我不想知道在输出时如何保持前面的零,这在使用cout时如何用前导零填充int中进行了讨论前导零不会被忽略;它们在处理时会被考虑,但保存在变量中的结果值与其他一些文本输入的结果值相同

同一个“数学”数字可以有多个文本表示,有时取决于语言环境。对于阿拉伯数字,
0325
等于
+325
,等于
325
。根据选择的区域设置,以下文本可能具有相同的数值:

  • 123456.89
  • 123.456,89
  • 123456.89
  • 123 456,89(请记住半空间符号为千分隔符)
让我们不要忘记其他数字书写系统,如罗马或赫布、中文等

多重数字表示的问题甚至比简单的人类传统还要深刻,发生在编程之外的纯数学中。可以证明,像
12.9(9)
[12.999999…]这样的有理无止境分数在所有方面都等于
13

我认为如果I的值设置为0,则更为自然


这将假定符号“0”在输入解析中的处理方式与[1-9]不同。但是为什么呢?

前导零不会被忽略;它们在处理时会被考虑,但保存在变量中的结果值与其他一些文本输入的结果值相同

同一个“数学”数字可以有多个文本表示,有时取决于语言环境。对于阿拉伯数字,
0325
等于
+325
,等于
325
。根据选择的区域设置,以下文本可能具有相同的数值:

  • 123456.89
  • 123.456,89
  • 123456.89
  • 123 456,89(请记住半空间符号为千分隔符)
让我们不要忘记其他数字书写系统,如罗马或赫布、中文等

多重数字表示的问题甚至比简单的人类传统还要深刻,发生在编程之外的纯数学中。可以证明,像
12.9(9)
[12.999999…]这样的有理无止境分数在所有方面都等于
13

我认为如果I的值设置为0,则更为自然

这将假定符号“0”在输入解析中的处理方式与[1-9]不同。但是为什么呢?

警告:前面的答案非常无聊

C++14[istream.formatting.Algorithm]^3

转换就像由以下代码片段执行一样进行(使用与 前面的代码片段):

[……] 返回:
do_get(in,end,str,err,val)

do_get
随后立即定义([facet.num.get.virtuals]),它以极其详细的方式指定了整个shebang的确切工作方式。我不会复制三页纸的痛苦,只会复制要点

在阶段1中,根据表85和86,根据流标志确定“等效stdio格式说明符”;
std::ios_base
的默认值是
dec | skipws
,因此我们将遵循该路径(对应于
%d
)。此外,还将为下一阶段确定一些其他特定于区域设置和标志的字符

在阶段2中,从流中读取字符并将其累积到缓冲区中;你问题的要点是

如果未放弃,则进行检查以确定是否允许
c
作为阶段1返回的转换说明符输入字段的下一个字符。如果是的话,它是累积的

因此,决定是继续读取零还是在单个零后停止取决于上面的
%d
;我们会回去的

在阶段3中,累积字符最终转换为
long

根据标题
中声明的函数之一的规则:

  • 对于有符号整数值,函数
    strtoll

%d
说明符和
strtoll
都在C标准中定义(C++14指C99);让我们把它们挖出来

在C99§7.19.6.2∗12(当谈论
fscanf
)时,被告知

d
匹配可选带符号的十进制整数,其格式与
strtol
函数的主题序列的预期格式相同,
base
参数的值为10

因此,我们可以在C99§7.20.1.4中找到所有这些都归结为
strtol
/
strtol
。指定跳过最长的空白序列,然后考虑“主题序列”:

如果
base
的值为零,则主题序列的预期形式为6.4.4.1中所述的整数常量,可选择前面加上加号或减号,但不包括整数后缀。如果
base
的值介于2和36之间(包括2和36),则主题序列的预期形式是表示in的字母和数字序列
operator>>(int& val);
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);
iter_type get(iter_type in, iter_type end, ios_base& str,
     ios_base::iostate& err, long& val) const;