简体   繁体   中英

Why does the output of this C++ program produce a giant mess in cmd?

I have since figured out how to make this program correct, but I was just wondering why this incorrect program for the question that follows produces just a whole bunch of characters and different machine information, and if such an error could damage the machine:

Exercise 3.10: Write a program that reads a string of characters including punctuation and writes what was read but with the punctuation removed.

#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;
}

Now, I know it is incorrect, and have since made this version to correctly output what was needed:

#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;
}

Why did the first one produce that mess of code? Also, when there is an if and no else, I thought that when it reaches an "empty" or non-existing else it stops; why, in the second program, does it successfully move on to the next character and restarts the loop after hitting an empty else?

  • Your string is 15 characters long.
  • The incorrect code increments the character index by 2 on each iteration rather than by 1.
  • You're only terminating the loop when the index is exactly equal to the length of the string (15) rather than testing an out-of-bounds condition.
  • When the character index is 14 (corresponding to the ' . ' character) the index is increment to 16, but the length of the string is 15, as 16 != 15 the loop continues and undefined memory past the end of the string is read and is written to the output stream.

你的字符串中有一个奇数个字符,因为你增加index由两个每次迭代, index始终为偶数,因此index != s.size()始终是真实的,你访问了索引范围,这是不确定的行为。

The first one is broken because your loop can simplify to:

for (size_t index = 0; index != s.size(); ++index) {
    ++index;
}

Since s.size() is odd, you're marching past size() in your loop and your condition doesn't catch it... index is never == 15 , it goes from 14 to 16 and keeps going until something bad happens.

You could've caught this with checking index < s.size() and noticing that you're only printing every other character.

On your first code you are increasing index twice per iteration: once inside the if or the else clause; and once on the for iteration.

Because of that, you are accessing values outside the string, thus printing garbage that is in your memory.

To understand what's going on you should consider how strings are made, they are char pointers, so when you print a string you are literally iterating through the string and print every character until you find the \\0 char. In the first example you were incrementing the index multiple times so instead of moving to the next char you were moving to 2 chars so you were "exiting" the range of the string and reading some other memory as char or you could even have some Segmentation faults, in fact it's better to have the index < size condition.

Anyway in c++ you can have an if without an else without any problems, so because you were inside a for loop and the exiting condition (index == size) wasn't met it increments the index variable and move to the next loop.

if you wanted to have an else condition you could use the continue instruction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM