MinGW-w64 上 cin 和 scanf() 的问题

Problems of cin and scanf() on MinGW-w64

我的 MinGW-w64 版本是:x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z

我的系统版本是:Windows10 2004

当我尝试使用MinGW-w64的g++编译运行这个源文件时,我运行陷入了困境。 此文件的名称是“temp.cpp”

#include <iostream>
using namespace std;
int main()
{
    char player1[8] = {0}, player2[8] = {0};
    cin >> player1 >> player2;
    cout << player1 << ' ' << player2;
    return 0;
}

我通过输入这行代码在 PowerShell 中构建并 运行 这个文件。

g++ -g .\temp.cpp -o .\temp.exe; .\temp.exe

然后我输入了输入。

Rock Scissors

在我按下回车键之后。我明白了。

 Scissors

第一个字没有打印出来。

然后我用VS Code调试源文件。我输入后发现,player1[0]中的数据并没有被'R'替换。相反,它仍然是 0.

然后我把整个mingw64文件夹复制到另一台电脑上再试,同样的事情又发生了。

然后我用 scanf() 替换了 cin。

#include <iostream>
using namespace std;
int main()
{
    char player1[8] = {0}, player2[8] = {0};
    scanf("%s %s", player1, player2);
    printf("%s %s", player1, player2);
    return 0;
}

同样的事情又发生了。

然后我下载旧版本的MinGW-w64:x86_64-5.4.0-release-posix-seh-rt_v5-rev0.7z

使用老版本,现在可以正常打印了。

为什么?

哦...您的数组 one-character 对于 Scissors 来说太短了。 nul-terminating 字符需要 9 个字符 8 + 1。所以在你的堆栈上发生的是你有 Player1 后跟 Player2 (但是由于堆栈向下增长,Player1Player2) 之上的内存中,例如

    |        Player2                |        Player1                |
    +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
    | S | c | i | s | s | o | r | s | [=10=]| o | c | k | [=10=]|   |   |   |
    +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

因此,当您输入 "Scissors" 并为 end-of-string 写入 nul-terminating 字符时,您会用 [=21= 覆盖 Player1 的第一个字符] 导致它看起来像 empty-string.

经验教训 -- 不要吝啬缓冲区大小!(或者更好,使用 std::string

声明:

char player1[32] = {0}, player2[32] = {0};

#include <string>
...
std::string player1 {}, player2 {};

然后重试。