expected {&unknown}, found String - rust

I can't compare guess with word and it throws me an expected {&unknown}, found String. error
fn main() {
let mut guess = String::new();
let word: String = String::from("Hello, world");
for x in 1..10 {
io::stdin()
.read_line(&mut guess)
.except("failed to read line");
println!("{}", guess.eq(word)); //error is in this line
}
println!("Game is over");
}

You must borrow word when you are comparing to it. So write guess.eq(&word). But this is equivalent to guess == word, so I would recommend this instead.
Also when you are reading line the endline character '\n' will also be added to guess, so you should probably use guess.trim() before compering to discard leading and trailing whitespaces.

Related

Identical strings don't seem to be treated as identical for the if statement [duplicate]

I'm trying to get user input and check if the user put in "y" or "n". Surprisingly, in the below code, neither the if nor the if else case executes! Apparently, correct_name is neither "y" nor "n". How can that be? Am I doing my string conversion wrong or something?
use std::io;
fn main() {
let mut correct_name = String::new();
io::stdin().read_line(&mut correct_name).expect("Failed to read line");
if correct_name == "y" {
println!("matched y!");
} else if correct_name == "n" {
println!("matched n!");
}
}
read_line includes the terminating newline in the returned string.
To remove it, use trim_end or even better, just trim:
use std::io;
fn main() {
let mut correct_name = String::new();
io::stdin()
.read_line(&mut correct_name)
.expect("Failed to read line");
let correct_name = correct_name.trim();
if correct_name == "y" {
println!("matched y!");
} else if correct_name == "n" {
println!("matched n!");
}
}
This last case handles lots of types of whitespace:
Returns a string slice with leading and trailing whitespace removed.
‘Whitespace’ is defined according to the terms of the Unicode Derived Core Property White_Space.
Windows / Linux / macOS shouldn't matter.
You could also use the trimmed result's length to truncate the original String, but in this case you should only use trim_end!
let trimmed_len = correct_name.trim_end().len();
correct_name.truncate(trimmed_len);
read_line includes the terminating newline in the returned string. Add .trim_right_matches("\r\n") to your definition of correct_name to remove the terminating newline.
You can use the chomp-nl crate which provides a chomp function which returns a string slice without the newline characters.
There is also a trait ChompInPlace if you prefer to do this in-place.
Disclaimer: I am the author of this library.

How do I take a string, convert it to an array, and then call specific characters from that array to create a new string?

Now that I'm typing it, this seems like a very convoluted process that could definitely be solved easier. Ignoring that for the moment, I'm trying to take a string (from user input), separate the characters into an array, then call individual characters to make a new string. The issue I'm running into is that the "join" function doesn't like working with the "Vec" function (not sure if function is the right term, sorry). Here is my code so far:
use std::io;
fn main() {
println!("Enter P1:");
let mut mono = String::new();
io::stdin()
.read_line(&mut mono)
.expect("Failed to read line");
let mono: Vec<char> = mono.chars().collect();
let x = [mono[0],mono[1]].join("");
println!("Square 1: {x}");
}
I'm very new to Rust, so any suggestions are extremely helpful. Thank you!
You could always just slice the original string str[a..b].to_string().
If you need to work with char arrays, there's String::from_iter and collecting into a String. Example:
fn main() {
let string = "My String".to_string();
let substr1 = string[0..3].to_string();
let substr2 = string[3..].to_string();
println!("substr1 = {}", substr1);
println!("substr2 = {}", substr2);
let chars: Vec<_> = string.chars().collect();
let collected_substr1: String = chars.iter().take(2).collect();
let collected_substr2: String = chars.iter().skip(3).collect();
println!("collected_substr1 = {}", collected_substr1);
println!("collected_substr2 = {}", collected_substr2);
let from_iter_substr1 = String::from_iter([chars[0], chars[1]].iter());
let from_iter_substr2 = String::from_iter(chars.iter().skip(3));
println!("from_iter_substr1 = {}", from_iter_substr1);
println!("from_iter_substr2 = {}", from_iter_substr2);
}
Vec is a type, FYI.
join only works on string slices (&str), not chars. Assuming you are just trying to join two characters without a separator, you can do
let x: String = mono.chars().take(2).collect();
If the goal is only to extract a substring from the input it can be done much simpler
use std::io;
fn main() {
println!("Enter P1:");
let mut mono = String::new();
io::stdin()
.read_line(&mut mono)
.expect("Failed to read line");
let x = &mono[..2].to_string(); // get rhe slice you need and create a new string from it
println!("Square 1: {x}");
}
Edit
As pointed out in comments, note that in a real life use case you should check the length of your string before slicing in it with arbitrary indexes... this example could easily crash at runtime.

Using string inputs and if statements together in rust [duplicate]

I'm trying to get user input and check if the user put in "y" or "n". Surprisingly, in the below code, neither the if nor the if else case executes! Apparently, correct_name is neither "y" nor "n". How can that be? Am I doing my string conversion wrong or something?
use std::io;
fn main() {
let mut correct_name = String::new();
io::stdin().read_line(&mut correct_name).expect("Failed to read line");
if correct_name == "y" {
println!("matched y!");
} else if correct_name == "n" {
println!("matched n!");
}
}
read_line includes the terminating newline in the returned string.
To remove it, use trim_end or even better, just trim:
use std::io;
fn main() {
let mut correct_name = String::new();
io::stdin()
.read_line(&mut correct_name)
.expect("Failed to read line");
let correct_name = correct_name.trim();
if correct_name == "y" {
println!("matched y!");
} else if correct_name == "n" {
println!("matched n!");
}
}
This last case handles lots of types of whitespace:
Returns a string slice with leading and trailing whitespace removed.
‘Whitespace’ is defined according to the terms of the Unicode Derived Core Property White_Space.
Windows / Linux / macOS shouldn't matter.
You could also use the trimmed result's length to truncate the original String, but in this case you should only use trim_end!
let trimmed_len = correct_name.trim_end().len();
correct_name.truncate(trimmed_len);
read_line includes the terminating newline in the returned string. Add .trim_right_matches("\r\n") to your definition of correct_name to remove the terminating newline.
You can use the chomp-nl crate which provides a chomp function which returns a string slice without the newline characters.
There is also a trait ChompInPlace if you prefer to do this in-place.
Disclaimer: I am the author of this library.

Search for a Path containing a String [duplicate]

I'm trying to get user input and check if the user put in "y" or "n". Surprisingly, in the below code, neither the if nor the if else case executes! Apparently, correct_name is neither "y" nor "n". How can that be? Am I doing my string conversion wrong or something?
use std::io;
fn main() {
let mut correct_name = String::new();
io::stdin().read_line(&mut correct_name).expect("Failed to read line");
if correct_name == "y" {
println!("matched y!");
} else if correct_name == "n" {
println!("matched n!");
}
}
read_line includes the terminating newline in the returned string.
To remove it, use trim_end or even better, just trim:
use std::io;
fn main() {
let mut correct_name = String::new();
io::stdin()
.read_line(&mut correct_name)
.expect("Failed to read line");
let correct_name = correct_name.trim();
if correct_name == "y" {
println!("matched y!");
} else if correct_name == "n" {
println!("matched n!");
}
}
This last case handles lots of types of whitespace:
Returns a string slice with leading and trailing whitespace removed.
‘Whitespace’ is defined according to the terms of the Unicode Derived Core Property White_Space.
Windows / Linux / macOS shouldn't matter.
You could also use the trimmed result's length to truncate the original String, but in this case you should only use trim_end!
let trimmed_len = correct_name.trim_end().len();
correct_name.truncate(trimmed_len);
read_line includes the terminating newline in the returned string. Add .trim_right_matches("\r\n") to your definition of correct_name to remove the terminating newline.
You can use the chomp-nl crate which provides a chomp function which returns a string slice without the newline characters.
There is also a trait ChompInPlace if you prefer to do this in-place.
Disclaimer: I am the author of this library.

A string read from standard input has extra whitespace when printed [duplicate]

I'm trying to get user input and check if the user put in "y" or "n". Surprisingly, in the below code, neither the if nor the if else case executes! Apparently, correct_name is neither "y" nor "n". How can that be? Am I doing my string conversion wrong or something?
use std::io;
fn main() {
let mut correct_name = String::new();
io::stdin().read_line(&mut correct_name).expect("Failed to read line");
if correct_name == "y" {
println!("matched y!");
} else if correct_name == "n" {
println!("matched n!");
}
}
read_line includes the terminating newline in the returned string.
To remove it, use trim_end or even better, just trim:
use std::io;
fn main() {
let mut correct_name = String::new();
io::stdin()
.read_line(&mut correct_name)
.expect("Failed to read line");
let correct_name = correct_name.trim();
if correct_name == "y" {
println!("matched y!");
} else if correct_name == "n" {
println!("matched n!");
}
}
This last case handles lots of types of whitespace:
Returns a string slice with leading and trailing whitespace removed.
‘Whitespace’ is defined according to the terms of the Unicode Derived Core Property White_Space.
Windows / Linux / macOS shouldn't matter.
You could also use the trimmed result's length to truncate the original String, but in this case you should only use trim_end!
let trimmed_len = correct_name.trim_end().len();
correct_name.truncate(trimmed_len);
read_line includes the terminating newline in the returned string. Add .trim_right_matches("\r\n") to your definition of correct_name to remove the terminating newline.
You can use the chomp-nl crate which provides a chomp function which returns a string slice without the newline characters.
There is also a trait ChompInPlace if you prefer to do this in-place.
Disclaimer: I am the author of this library.

Resources