Rust - Matching strings

ghz 8months ago ⋅ 62 views

currently I am trying to learn rust. I wanted to create a very little and simple todo list, but I have some issues with matching the user input to the different options.

I've allready tried different solutions from the Internet, but the program allways ends up in the "no match" branch of my code:

use std::io::{self, stdin};

fn main() {
    
    let mut todo = Vec::new();

    println!("--TODO LIST--");
    println!("");

    println!("1. Show List");
    println!("2. Add to list");
    println!("3. Remove from list");

    let mut input = String::new();
    let mut add = String::new();

    stdin().read_line(&mut input).expect("cannot readline"); 

    let mut i = 0;

    let _= input.trim_end();

    //println!();
    //println!("{}", input);

    match input.as_str() {
        "1" => {
            
            while i <= todo.len() {
                print!("{}. {}", i, todo[i]);
                i += 1;
            }
        },

        "2" => {
            println!("What do you want to add?");
            io::stdin().read_line(&mut add).expect("Invalid answer");
            todo.push( add);

        },
        
        "3" => {
            println!("What do you want to remove (number)");
            io::stdin().read_line(&mut add).expect("Invalid answer");

            let my_int = add.parse::<usize>().unwrap();

            todo.remove(my_int);
        },

        _=> {
            println!("No Match");
            main();

        },
    };

    main();

}

Answers

It seems like you're encountering issues with matching user input to different options in your todo list program. The problem lies in the way you're reading input from the user and comparing it to the menu options. Here's a revised version of your code with some corrections:

use std::io::{self, stdin};

fn main() {
    let mut todo = Vec::new();

    println!("--TODO LIST--");
    println!();
    println!("1. Show List");
    println!("2. Add to list");
    println!("3. Remove from list");
    println!("4. Exit");

    let mut input = String::new();
    let mut add = String::new();

    stdin().read_line(&mut input).expect("cannot readline");

    // Remove trailing newline character
    let input = input.trim();

    match input {
        "1" => {
            for (i, item) in todo.iter().enumerate() {
                println!("{}. {}", i + 1, item);
            }
        }

        "2" => {
            println!("What do you want to add?");
            io::stdin().read_line(&mut add).expect("Invalid answer");
            todo.push(add.trim().to_string());
        }

        "3" => {
            println!("What do you want to remove (number)");
            io::stdin().read_line(&mut add).expect("Invalid answer");
            let my_int = add.trim().parse::<usize>().unwrap();
            if my_int < todo.len() {
                todo.remove(my_int);
            } else {
                println!("Invalid index");
            }
        }

        "4" => {
            println!("Exiting program.");
            return;
        }

        _ => {
            println!("No Match");
            return;
        }
    };

    main();
}

Changes made:

  1. Removed the unnecessary use of trim_end() and stored the trimmed input directly.
  2. Changed the loop for displaying the todo list to use enumerate() to also print the index of each item.
  3. Added a trim to the string before pushing it into the todo list to remove any trailing newline characters.
  4. Added an option to exit the program with input "4".
  5. Removed the recursive call to main() after each input processing, as it's not necessary and can lead to unexpected behavior. Instead, the program returns after processing each input.