0

I am trying to covert a string to an ascii code in rust to turn the string into BrainFuck code:

(The varable "input" is the string "hello" and this snippet starts at line 12)

for x in input.chars(){
    ascii = x as u8;
    println!("{}", ascii);
    if ascii > 86 {
      target = ascii - 86;
      output = output.clone() + "+[--------->++++++<]>";
      for x in 0..target{
        output = output + "+";
      output = output + ".>";
      }
    
    }else if ascii <= 86 {
      println!("{}", ascii);
      target = ascii - 86;
      output = output.clone() + "+[--------->++++++<]>";
      for x in 0..target{
        output = output + "-";
      output = output + ".>"
      }
    }
  }
  println!("{}", output)

However, the program fails with an 'attempt to subtract with overflow' at 25:16. This was unusual so I printed out all of the ascii values and got:

104
101
108
108
111
10
10

I am not sure why the two extra 10's are there, but they seem to be causing this subtract overflow. Why are these 10's being put into the ascii varable? Could it be that I am technically converting a string to base 10 and rust puts them there by default?

kometen
  • 6,536
  • 6
  • 41
  • 51
Cody
  • 3
  • 2
  • 1
    You have two branches, one for `ascii > 86` and one for `ascii <= 86`, but you have exactly the same code for either branch, including `target = ascii - 86`, which is certain to fail in the latter branch. – Sven Marnach Mar 13 '23 at 12:29
  • Copypasta strikes again! Good catch @SvenMarnach – Kevin Anderson Mar 13 '23 at 12:30
  • There are more problems with the code, e.g. `x as u8` will overflow if the input contains any Unicode codepoints ≥ 256. – Sven Marnach Mar 13 '23 at 12:31
  • The second `if` in the `else` branch is also unnecessary, and for iteratively building a string I recommend `output.push_str(...)` or `write!(&mut output, ...)`. – Sven Marnach Mar 13 '23 at 12:33
  • 5
    The 10s are newline characters. – Sven Marnach Mar 13 '23 at 12:34
  • Could you try `input.trim().chars()` instead of `input.chars()` I think like sven, is probably a newline char – Zeppi Mar 13 '23 at 12:44
  • Where does `input` come from? If you read it with `io::stdin().read_line(&mut input)`, then this is a duplicate of https://stackoverflow.com/q/27773313/5397009 – Jmb Mar 13 '23 at 13:18
  • @SvenMarnach, target = ascii - 86 is purposfully the same for both. (2nd comment), It is converting to to ascii which does not go over 255. – Cody Mar 13 '23 at 13:30
  • @Cody ASCII codes are always in the range 0–127. My point is that you can't subtract 86 from an unsigned number that is less than 86. It will overflow. Moreover, having an `if` with both branches doing exactly the same seems redundant. – Sven Marnach Mar 13 '23 at 13:38
  • @Cody if ascii is less than 86, you want target = 86 - ascii instead. – Daniel Cristofani Mar 14 '23 at 01:08
  • The 10s are linefeeds but they aren't the main problem; anything below 86, such as an 'H' or a space or a '!', would give target a negative value. – Daniel Cristofani Mar 14 '23 at 01:24
  • Linefeeds are important to be able to generate, anyway. I'd see it as a warning sign that the code you generate for them is like +[--------->++++++<]> ----------------------------------------------------------------------------.> rather than maybe ++++++++++.[-] or something. – Daniel Cristofani Mar 14 '23 at 01:38

0 Answers0