Hard coding strings as parameters works, reading them from the terminal doesn't

Hello everyone,

I'm trying to build a simple FTP client and I'm racking my brains currently as why this happens.
It seems that when I read input from console, File::create returns the following error:

thread 'main' panicked at 'Error encountered while creating file!: Os { code: 123, kind: InvalidFilename, message: "The filename, directory name, or volume label syntax is incorrect." }', src\main.rs:30:56

I also tried with fs::rename and had the same issue.
It seems that when I hardcode "test.txt" it works, but if I use the value from standard input, it bugs out. Also, hardcoding the string works too (String::from()), only if I read it from keyboard it has issues.

I've been stuck on this for a long while and since I'm a newb in Rust, it still feels alien to debug, especially coming from C.

Here's the full code:

fn main() {

let mut ftp_stream = FtpStream::connect("192.168.1.2:21").unwrap_or_else(|err|

    panic!("{}", err)

);

let _ = ftp_stream.login("alfonzo", "baumgartner").unwrap();



println!("Current directory: {}", ftp_stream.pwd().unwrap());



ftp_stream.cwd("/files").unwrap();

println!("{:?}", ftp_stream.list(None));

let mut filename = String::new();

println!("Enter the file you'd wish to download: ");

let _b1 = std::io::stdin().read_line(&mut filename).unwrap();

let remote_file = ftp_stream.simple_retr(&filename).unwrap();

println!("Read file with contents\n{}\n", str::from_utf8(&remote_file.into_inner()).unwrap());

assert!(ftp_stream.retr(&filename, |stream| {

    let mut buf = Vec::new();

    stream.read_to_end(&mut buf).map(|_|

        {

            let mut file = File::create(&filename).expect("Error encountered while creating file!");

            file.write_all(&buf).expect("something");

        }

    ).map_err(|e| FtpError::ConnectionError(e))

}).is_ok());

let _ = ftp_stream.quit();

}

read_line leaves the "\r\n" (or just "\n") in filename. If you don't care about supporting any leading or trailing whitespace, you could

let _b1 = std::io::stdin().read_line(&mut filename).unwrap();
let trimmed_filename = filename.trim();
let remove_file = ftp_stream.simple_retr(trimmed_filename).unwrap();

Etc.

More generally, you could make some utility function to read the line, check for a trailing "\r\n" or "\n", and remove them.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.