1

What I want to do is very very simple. Read through a string character by character and write the numbers to a separate string while including a space in between.

Ex. original string: "45+67-32" becomes "45 67 32"

Here's my logic:

while (i < line.length())
{
    char c = line.at(i);

    if (isdigit(c))
    {
        c = line.at(i);
        while (isdigit(c) || c == '.' && i < line.size())
        {
            expression = expression + line.at(i);
            i++;
        }
        expression = expression + ' ';
    }
    i++;
}
cigien
  • 57,834
  • 11
  • 73
  • 112
sonofzen1
  • 11
  • 2
  • 1
    What's the problem with the logic you've shown? Please describe the actual output clearly, and also try to make a [mre] – cigien May 02 '21 at 22:40
  • We dont know if your using char or int or string or etc to fix it even we cant know if the problem with declaring vars you need to provide the full function code. – coderx64 May 02 '21 at 22:44
  • 1
    On a side note, using `string::at()` is overkill when you are doing your own bounds checking, you can use `string::operator[]` instead – Remy Lebeau May 02 '21 at 22:47
  • Your description says `"45+67-32" becomes "45 67 32"`. The code as shown does not handle `'+'` or `'-'` characters in the input, so would NEVER produce that. Also bear in mind that `&&` is higher precedence than `||` so, if there are digits at the end of the string, the inner loop will happily attempt to access past the end of `line`. – Peter May 02 '21 at 22:53
  • I would suggest rewriting this code to use a single loop that uses `string::find_first(_not)_of()` and `string::substr()`, instead of iterating character-by-character. – Remy Lebeau May 02 '21 at 22:55
  • Why are you testing `c` in your inner `while` loop's condition when you don't modify it inside the loop body (or in the test condition itself)? – Dmitri May 02 '21 at 22:56

1 Answers1

1

C++ standard mandates a feature called short-circuiting. If a result of logical operation can be determined without evaluating all of the operands, it should be done so. There are two cases when this happens:

  1. In expression a || b (a or b), if a is true then expression must also be true and b is irrelevant,
  2. In expression a && b (a and b), if a is false then expression must also be false and b is irrelevant.

Because of short circuits, c == '.' && i < line.size() is not evaluated as long as isdigit(c) is true. Therefore you never know if you are already outside of the string or not.

You can fix your loop by using short circuits to your advantege:

while (i < line.size() && (isdigit(c) || c == '.'))
Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • That is totally unrelated to short circuiting. Even if the full expression was evaluated, it would break in the exact same way. Op's problem is just that `&&` has precedence over `||`. – spectras May 02 '21 at 23:00
  • Oh short circuiting! I completely forgot about that, makes sense. Well i implimented your changes but now everything is written to the new expression, not exclusively the numbers like I wanted. Why is that? It's seems like it's not evealuating the other two conditions anymore. – sonofzen1 May 02 '21 at 23:01
  • Never mind I got it working. It seems @spectras was right, precedence was the issue. Plus the character variable c I using was never updated, so the while loop was always checking how the conditions applied to the first character and nothing after. – sonofzen1 May 02 '21 at 23:06