首页 > 解决方案 > 如果前导 0 之后的数字是 8 或 9,则 Scanf 不会读取前导 0

问题描述

我有一个非常奇怪的问题,源于我一直在编写的 C++11 程序的错误。

请参阅以下代码:

long long a[1000];
int main(int argc, char * argv[]) {
    
    for(long long i = 0; i < 300; ++i) {
        scanf("%lli", &a[i]);
        std::cout << a[i] << std::endl;
    }
    
    return 0;
}

尝试输入等,我们得到了1预期2的输出等1\n2\n这也适用于我们从哪里获得的输入,001我们从哪里获得。1\n00044\n

但是,当前导零后面的数字是 8 或 9 时,scanf()首先读取前导零,然后读取后面的数字。

例如:

输入:0009,输出:000\n9\n

输入:08,输出0\n8\n

输入:00914,输出00\n914\n

我已经做了一些测试,对于这些情况,似乎scanf()首先读取前导零,其余数字留在缓冲区中,这些数字在循环的第二次运行时被拾取。

有人可以暗示发生了什么吗?

我正在使用 XCode 11.3.7 并使用 Clang C++11 进行编译。(我没有弄乱项目设置)

先感谢您!!!

标签: c++c++11scanfstdin

解决方案


使用%lld而不是%lli.

%i不起作用的原因是因为0解释为八进制数的前缀,而数字89八进制中不存在:

d 匹配可选带符号的十进制整数;下一个指针必须是指向 int 的指针。

i 匹配一个可选的有符号整数;下一个指针必须是指向 int 的指针。如果整数以 0x 或 0X 开头,则以 16 为基数读取,如果以 0 开头,则以 8 为基数读取,否则以 10 为基数读取。仅使用与基础相对应的字符。

对于其他数字,您也会得到错误的答案,例如010八进制将被解析为 8。

或者,甚至更好:使用 C++ 而不是 C。

std::cin >> a[i];

推荐阅读