How to convert a vector of strings into numbers

#1

I am trying to create a reverse polish notation calculator. I am able to fill up a vector of strings but am unsure how to proceed.

For example: if I input 1 2 3 - - how do I fill a seperate Vec:i32 with 1 2 3?

use std::io::{stdin,stdout,Write};

fn main() {
    println!("Please enter your RPN to be calculated");

    let mut Rpn_string: Vec<String> = Vec::new();

    let mut buffer = String::new();

    stdin().read_line(&mut buffer).expect("Failed to read");

    for _ in 0..2{
    	let yo: String = buffer.parse().expect("Invalid string");
    	Rpn_string.push(yo);
    	buffer.clear();
    }
}
0 Likes

#2

Why fill a separate one? You can change the existing Rpn_string into an Rpn_numbers, and declare it as a vector of 32-bit integers (or whatever kind of number you want).

fn main() {
    println!("Please enter your RPN to be calculated");

    let mut Rpn_numbers: Vec<i32> = Vec::new();

    let mut buffer = String::new();

    stdin().read_line(&mut buffer).expect("Failed to read");

    for _ in 0..2{
    	let yo = buffer.parse().expect("failed to convert the string into a number");
    	Rpn_numbers.push(yo);
    	buffer.clear();
    }
}

The parse() function is a generic function that converts a string into another data type; in this case, it converts the string into a number (while in your initial example, it converts the string into another string, essentially doing nothing).

0 Likes

#3

Well the buffer string is also going to hold the operations. Will parse know just to grab the numbers and leave the operators alone? And if it does, how will I go about grabbing the required operators from the string.

To clarify my example, I am going to input something like “3 5 * 2 +” and I need to grab all the individuals pieces of that string.

0 Likes

#4

Once you read the input into a String, split it on whitespace and then parse the individual tokens.

parse takes some type T that implements FromStr. You can use that to parse the integers. For operators, you can either assume that if an int parse fails it must be a token (naive but simple approach) or keep track of parse state as you go along and expect certain types based on the state.

0 Likes

#5

Or assume that if it’s not a known operator it must be a number.

0 Likes

#6

I am still having difficulty

use std::io::stdin;

fn main() {
    println!("Please enter your RPN to be calculated");

    let mut Rpn_string: Vec<&str> = Vec::new();

    let mut main_stack: Vec<i32> = Vec::new();

    let mut buffer = String::new();

    let split = buffer.split_whitespace();


    stdin().read_line(&mut buffer).expect("Failed to read");

Rpn_string = split.collect();

    for i in &Rpn_string{

    	let my_string = Rpn_string.pop();

    	if my_string == Some("+"){
    		println!("Found an operator");
    	}
    	else if my_string == Some("save"){
    		println!("Found a save");
    	} 
    	else if my_string == Some("restore"){
    		println!("Found a restore");
    	}
    	else {
    		let my_int: i32 = Rpn_string.pop().unwrap();
    		main_stack.push(my_int);
    	}
    }

So I get an error in my else, when I try to pop my vector it expects a type i32 but the vector is filled with strings. If i change the vector to be a vector of ints I am not sure how I can handle cases of the operators, as they are not ints and throw an error.

0 Likes

#7

You need to call parse() to convert the string into an i32. Like let my_int: i32 = Rpn_string.pop().unwrap().parse().unwrap()

0 Likes

#8

It seems you pop numbers twice? Or even three times? First you iterate over the elements of Rpn_string, so i will get each value. The you pop() a value into my_string(). Don’t this give a compilation error that you try to modify Rpn_string while it is borrowed? Then if the value is not an operator, you pop() again to get an integer. You should probably use my_string there?

Suggestion: Change the loop from for i in &Rpn_string() to while !Rpn_string.is_empty or use i instead of popping to my_string.

Addendum: You split the input string into words before you read it, you need to read first and then split.

0 Likes