1

Question: Why is my for loop not iterating for the third time?

What I noticed: In the for loop statement below, removing the if-else statement allowed me to print i from 0-2 and the "1" three times.

for (size_t i {0}; i < user_input.length(); ++i) {
        
        cout << i << endl;
        cout << user_input.length() << endl;
        
        string the_spaces;
        string the_line;

        for (size_t b {i}; b < (user_input.length() - 1); ++b) {
            the_spaces += " ";
        }

        for (size_t k {0}, y {i+1}; k < y; ++k) {
            the_line += user_input[k];
        }
        
        if (i >= 1) {
            cout << "Bob";
            for (size_t z {i - 1}; z >= 0; --z) {
                the_line += user_input[z];
            }
        }
        else {
            cout << "Beb" << endl;
        }
        
        cout << "1" << endl;
            
    } 

Output:

0                   // i
3                   // the user_input.length
Beb                 // output from if-else
1                   // 1 printed at the end of the for loop expression
1                   // i (2nd iteration)
3                   // the user input.length 

the code ends here... Neither printing Beb or Bob, as well as, the "1" from cout << "1" << endl; on the 2nd & 3rd iteration.

Benz
  • 13
  • 3
  • 2
    `for (size_t z {i - 1}; z >= 0; --z)` is infinite loop. – Jarod42 Dec 14 '21 at 11:29
  • 4
    This should be the perfect time to learn how to *debug* your programs. For example, with a *debugger* you can step through the code statement by statement while monitoring variables and their values. – Some programmer dude Dec 14 '21 at 11:30
  • 2
    Shouldn't even need a debugger - just turn on (all) compiler warnings: any sane one will warn you that `z >= 0` is always true. – Adrian Mole Dec 14 '21 at 11:31

3 Answers3

3

z >= 0 is always true since z is an unsigned type.

Your program therefore loops. Although there are other solutions, using a long long rather than a std::size_t as the loop index is probably the simplest.


b < (user_input.length() - 1) is also problematic if user_input is empty. Use

b + 1 < user_input.length()

instead.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Allow me to add one suggestion: ``std::ptrdiff_t`` would also be appropriate for ``z``. (The standard states: "std::ptrdiff_t is used for pointer arithmetic and array indexing, if negative values are possible." This perfectly matches this use case). – Christian Halaszovich Dec 14 '21 at 11:39
  • @ChristianHalaszovich: Yes, that's not a bad one. Why not submit an answer? Stack Overflow works best when there are a selection to choose from. I think though I'd prefer something based around `std::make_signed`. Personally I use `-->` (slide operator) when counting backwards with an unsigned type, thereby not messing about with the type at all, but it's fallen out of fashion. – Bathsheba Dec 14 '21 at 11:40
1

In the for loop:

for (size_t z {i - 1}; z >= 0; --z) {
    the_line += user_input[z];
}

because size_t will never be negative, so z >= 0 will always true. So this is an infinite loop.

You can typecast it:

for (long long z {static_cast<long long>(i - 1)}; z >= 0; --z) {
    the_line += user_input[z];
}

or if you don't want t typecast it, you can use this rather odd way:

for (size_t z{i}; z-- > 0; )
    the_line += user_input[z];
}
  • 1
    Thanks for fixing. The "rather odd way" is how I'd do it, although I like to write `z --> 0` as I feel it better expresses the idiom. – Bathsheba Dec 14 '21 at 11:48
  • @Bathsheba I'll use my rather odd way as well. It's interesting that you call it the slide operator while I call it the [downto](https://stackoverflow.com/questions/1642028/what-is-the-operator-in-c-c#comment119493280_1642035) operator. Maybe it differs between C++ standards – justANewb stands with Ukraine Dec 14 '21 at 11:52
  • Folk listening in would be horrified at our thinking the C++ standard cares to mention it. It's not really an operator at all of course. I started using it in my C days at university. – Bathsheba Dec 14 '21 at 12:01
  • @Bathsheba That looks a bit weird. Most sane coding conventions/design rules prescribe that postfix operators should appear directly after the variable, and that there should be spaces between the comparison operator and its operands. "It looks funny" is not a good reason to break well-established conventions. – Alderath Dec 14 '21 at 12:04
  • @Alderath: Yes it does look weird on first inspection. But then bearing in mind that unsigned subtraction is not closed, `--` is a weird thing to do to an unsigned type. Yes I guess it's down to fashion. – Bathsheba Dec 14 '21 at 12:07
  • https://stackoverflow.com/q/1642028/4117728 – 463035818_is_not_an_ai Dec 14 '21 at 12:16
0

One addition to the answers already given: Another C++ standard conform and highly portable signed type appropriate for z is std::ptrdiff_t. (It is similar to POSIX's ssize_t.)

(Quoting from the standard: "std::ptrdiff_t is used for pointer arithmetic and array indexing, if negative values are possible.")