Reputation: 1551
use std::env;
use std::process;
fn main(){
let mut repository_urls: Vec<String> = env::args().collect();
if repository_urls.len() == 1 {
eprintln!("You have to enter at least one repository url!");
process::exit(1);
} else {
for i in 0 .. repository_urls.len() - 1 {
if repository_urls[i + 1] == "--advanced" && repository_urls.len() >= i + 5 {
repository_urls.remove(i + 4);
repository_urls.remove(i + 3);
repository_urls.remove(i + 2);
} else {
}
}
//Ends the process normally
process::exit(0);
}
}
If you were to have --advanced 1 2 3
for the arguments for this it would do everything and execute all the logic as intended but when it finishes it ends up crashing with:
thread 'main' panicked at 'index out of bounds: the len is 2 but the index is 2', /rustc/a53f9df32fbb0b5f4382caaad8f1a46f36ea887c/src/libcore/slice/mod.rs:2695:10
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
How would I get my program but exit normally without a crash?
Upvotes: 2
Views: 9408
Reputation: 1329
Above the advice from @lukas-kalbertodt in idiomatic Rust you normally create iterator over existing vector, then using filtering techniques you collect data to the new vector. Please avoid very inefficient removal from vectors.
Upvotes: 0
Reputation: 88886
Your immediate problem is that after you called remove
three times, your loop continues to run. The loop range (0..repository_urls.len() - 1
) is only evaluated at the very beginning of the loop. But now the vector length has changed and accessing the vector via repository_urls[i + 1]
then fails. You can fix this by adding a break
after your remove
s.
For command line argument parsing, it's usually advisable to use a crate. Doing it manually usually leads to spaghetti code and subtle bugs. I can very much recommend structopt
. It's really easy to add it to your application.
Upvotes: 3