为什么这个C++程序的输出在cmd中产生了巨大的混乱
Why does the output of this C++ program produce a giant mess in cmd?
我已经想好了如何使这个程序正确,但我只是想知道为什么这个不正确的程序只会产生一大堆字符和不同的机器信息,以及这样的错误是否会损坏机器:
练习3.10:编写一个读取字符串的程序包括标点符号和书写所读内容,但使用标点符号已删除。
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string s("Some! string!s.");
for (decltype(s.size()) index = 0;
index != s.size(); ++index){
if (!ispunct(s[index])){
cout << s[index];
++index;
}
else {
++index;
}
}
return 0;
}
现在,我知道这是不正确的,并且已经制作了这个版本来正确地输出所需的内容:
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string s("Some! string!s.");
for (decltype(s.size()) index = 0;
index != s.size(); ++index){
if (!ispunct(s[index])){
cout << s[index];
}
}
return 0;
}
为什么第一个产生了那么混乱的代码?此外,当存在if而没有else时,我认为当它达到"空的"或不存在的else时就会停止;为什么在第二个程序中,它成功地移动到下一个字符,并在命中空的else后重新启动循环?
- 你的字符串有15个字符长
- 错误的代码在每次迭代中将字符索引增加2,而不是1
- 只有当索引恰好等于字符串(15)的长度时,才终止循环,而不是测试越界条件
- 当字符索引为14(对应于"
.
"字符)时,索引将增加到16,但字符串的长度为15,因为16 != 15
循环继续,并且读取字符串末尾之后的未定义内存并将其写入输出流
您的字符串有奇数个字符,因为每次迭代都会将index
增加两个,所以index
总是偶数,因此index != s.size()
总是true,并且您访问的索引超出范围,这就是Undefined Behavior。
第一个被破坏,因为您的循环可以简化为:
for (size_t index = 0; index != s.size(); ++index) {
++index;
}
由于s.size()
很奇怪,你在循环中经过size()
,但你的条件没有抓住它……index
从来都不是== 15
,它从14
到16
,一直持续到发生不好的事情。
您可以通过检查index < s.size()
并注意到您只打印每隔一个字符来发现这一点。
在第一个代码中,每次迭代增加索引两次:一次在if或else子句中;在for迭代上一次。
因此,您正在访问字符串之外的值,从而打印内存中的垃圾。
要了解发生了什么,您应该考虑字符串是如何生成的,它们是字符指针,所以当您打印字符串时,您实际上是在遍历字符串并打印每个字符,直到找到\0字符。在第一个例子中,你多次递增索引,所以你不是移动到下一个字符,而是移动到2个字符,所以你"退出"字符串的范围,并以字符的形式读取一些其他内存,或者你甚至可能有一些Segmentation错误,事实上,最好是索引<尺寸条件。
无论如何,在c++中,你可以有一个if而没有else,而不会有任何问题,所以因为你在for循环中,并且不满足退出条件(index==size),所以它会增加索引变量并移动到下一个循环。
如果您想要其他条件,可以使用continue指令。
- 在提升multi_index容器中,是否定义了"default index"?
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- Clang 给了我符号更改的警告,但代码仍然产生正确的输出
- CMD:程序.exe 1< "A:/input.txt"产生无输出
- 我做了自己的std ::矢量,但我正在产生错误
- imshow() 在 C++ 年使用 OpenCV 3.2 产生了奇怪的结果
- 这种方法是否对分支的预测产生了影响
- 我通过编译器C 11收到了UVA在线法官的错误消息.我永远不知道为什么会产生此错误
- C++编译器在安装了Visual Studios和代码块的cmd中不起作用
- 为什么这个C++程序的输出在cmd中产生了巨大的混乱
- C++程序产生了许多错误
- 试图学习威纳皮.制作了第一个程序,必须向我显示一个窗口.CMD显示,但没有窗口
- gluLookAt似乎产生了错误的观点,OpenGL
- zlib compress() 产生了可怕的压缩率
- 为什么我的 cmd 消失了?我使用 cin.ignore(),但它没有效果!C++
- 我的弹射器游戏产生了不正确的距离
- 我的c++程序读取一个矩阵并打印出非零的数字,这产生了一个运行时错误
- Lorenz示例中的odeint和VecCL在不同的设备上产生了不同的结果
- vs2010和vs2005产生的Exe加载了不同的偏移量