0

I have programmed a simple ASCII to string converter but I am facing problems in turning it to a binary to string converter.

When I try to input binary values I am getting an error and the vector insertion skips the starting zeros in the input.

This is the code that works with ASCII decimal values:

use std::*;

fn main() {
    println!("AregevDev's binary to string converter!");
    println!("Enter a sequence of binary values:");

    let mut int_seq: Vec<u32> = Vec::new();

    loop {
        let mut it = String::new();
        io::stdin()
            .read_line(&mut it)
            .expect("Failed to read line!");
        let num = match it.trim().parse::<u32>() {
            Ok(num) => num,
            Err(_) => break,
        };

        int_seq.push(num);
    }

    println!("Converted string: {}", binary_to_string(&int_seq));
}

fn binary_to_string(vec: &Vec<u32>) -> String {
    let mut result = String::new();

    for u in vec.iter() {
        let ch = char::from_u32(*u).unwrap();
        result.push(ch);
    }

    return result;
}

Code that does not work:

use std::*;

fn main() {
    println!("AregevDev's binary to string converter!");
    println!("Enter a sequence of binary values:");

    let mut int_seq: Vec<u32> = Vec::new();

    loop {
        let mut it = String::new();
        io::stdin()
            .read_line(&mut it)
            .expect("Failed to read line!");
        let num = match it.trim().parse::<u32>() {
            Ok(num) => num,
            Err(_) => break,
        };

        int_seq.push(num);
    }

    println!("Vec: {:?}", int_seq);
    println!("Converted string: {:?}", binary_to_string(&int_seq));
}

fn binary_to_string(vec: &Vec<u32>) -> String {
    let mut result = String::new();

    for u in vec.iter() {
        let ch = char::from_digit(*u, 2).unwrap();
        result.push(ch);
    }

    return result;
}

Error:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', libcore/option.rs:345:21
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::print
             at libstd/sys_common/backtrace.rs:71
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:227
   4: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:511
   5: std::panicking::continue_panic_fmt
             at libstd/panicking.rs:426
   6: rust_begin_unwind
             at libstd/panicking.rs:337
   7: core::panicking::panic_fmt
             at libcore/panicking.rs:92
   8: core::panicking::panic
             at libcore/panicking.rs:53
   9: rust_practices::main
  10: std::rt::lang_start::{{closure}}
  11: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:310
  12: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  13: std::rt::lang_start_internal
             at libstd/panicking.rs:289
             at libstd/panic.rs:392
             at libstd/rt.rs:58
  14: main
  15: __libc_start_main
  16: _start
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
AregevDev
  • 29
  • 1
  • 7
  • 2
    It is probably there. You just can't see it, because the NUL character is invisible. – starblue Aug 14 '18 at 08:03
  • ... and it confuses most applications written in C (I tried copy-and-paste into `hd`). :-) – starblue Aug 14 '18 at 08:06
  • 1
    It's not a good idea when your code to demonstrate a problem depends on manual input. – starblue Aug 14 '18 at 08:18
  • 2
    [Why is it discouraged to accept a reference to a String (&String), Vec (&Vec) or Box (&Box) as a function argument?](https://stackoverflow.com/q/40006219/155423) – Shepmaster Aug 14 '18 at 13:06

1 Answers1

4

The characters corresponding to zeros are there, but you can't see them:

fn main() {
    let mut s = String::new();
    s.push(char::from(0));
    s.push('a');
    s.push('b');
    println!("Hello, {}!", s);
    println!("{:?}", s);
    for c in s.chars() {
        println!("{}", c as u32);
    }
}

I can't show you the output, because the NUL character confuses the Stack Overflow editor as well. :-)

starblue
  • 55,348
  • 14
  • 97
  • 151
  • You can build the string like this `let s: String = vec![char::from(0), 'a', 'b'].into_iter().collect();` instead of pushing `char`s by hand. – Boiethios Aug 14 '18 at 08:17
  • 5
    You could print in debug mode, though `'\u{0}'` might not be an obvious sight. – ljedrz Aug 14 '18 at 08:17
  • 2
    @ljedrz I wanted to use display mode to demonstrate the invisibility, but using both display and debug mode is nice. – starblue Aug 14 '18 at 08:23
  • @Boiethios Here pushing them one-by-one is better, because it is closer to OP's code. – starblue Aug 14 '18 at 08:38