在 C++ 中使用 scanf() 和 printf() 的意外输出

Unexpected output using scanf() and printf() in C++

我编写了以下简单的代码片段:

#include<cstdio>
#include<iostream>
using namespace std;

int main()
{
    int w, h;

    scanf("%d %d", &w, &h);

    char shop[h][w];
    for(int i=0; i<h; i++)
        for(int j=0; j<w; j++)
            scanf("%c", &shop[i][j]);
            //cin>>shop[i][j];

    for(int i=0; i<h; i++)
    {
        for(int j=0; j<w; j++)
            printf("%c", shop[i][j]);
            //cout<<shop[i][j];
        printf("\n");
        //cout<<"\n";
    }

    return 0;
}

按如下方式传递输入:

4 3
X1S3
42X4
X1D2

我希望输出是一样的,因为我没有修改代码中的任何内容。但是,当我打印它时,我得到以下输出:

X1S
3
42
X4
X

但是,将 scanf()printf() 替换为 cincout 会正确生成所需的输出。对我可能出错的地方有任何输入吗?

Link 使用 printf() 编码:http://ideone.com/NvHQUl
Link 使用 cout 编码:http://ideone.com/PQWe9R

更新:h表示行数;而 w 表示列数。

这是因为 scanf("%c", ...) 将换行符读取为字符。

因此,如果您的输入提供 LF 换行符,例如,您的二维数组最终包含:

\n  X  1  S
 3 \n  4  2
 X  4 \n  X

当你在循环中打印出来时,你基本上是在打印:

"\nX1S" "\n"  <-- that's the "\n" you explicitly print after each row
"3\n42" "\n"
"X4\nX" "\n"

当然,这就是您看到的输出。

scanf中的%c格式说明符读取并赋值下一个字符包括whitespaces 和换行符。每 scanf specs:

All conversion specifiers other than [, c, and n consume and discard all leading whitespace characters (determined as if by calling isspace) before attempting to parse the input.

因此scanf("%c", &shop[i][j]);会将每行输入末尾的换行符作为常规字符读取,并将其分配给数组中的某个元素,这解释了printf输出。

要跳过白色 space,请改用 scanf(" %c", &shop[i][j]);(请注意 %c 之前的附加 space)。