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
(但是由于堆栈向下增长,Player1
在 Player2)
之上的内存中,例如
| 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 {};
然后重试。
我的 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
(但是由于堆栈向下增长,Player1
在 Player2)
之上的内存中,例如
| 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 {};
然后重试。