Exit code: 2 in stdin().read_line(&mut buf))?;

Hi, guys.
As I read in the documentation, the arguments of the type:
let mut buf = String::new();
(io::stdin().read_line(&mut buf))?;
Ok(buf)
}
They may have problems:
" Note: Windows Portability Considerations

When operating in a console, the Windows implementation of this stream does not support non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return an error.

In a process with a detached console, such as one using , or in a child process spawned from such a process, the contained handle will be null. In such cases, the standard library’s and will do nothing and silently succeed. All other I/O operations, via the standard library or via raw Windows API calls, will fail.#![windows_subsystem = "windows"] Read Write"

The problem is that ge tried to solve this by putting the environment variable but the code still throws error 2:

use std::io::{self, Write};
use std::fmt::Display;
use std::{env, process};
#![windows_subsystem = "windows"]

To compile:
= note: inner attributes, like #![no_std], annotate the item enclosing them, and are usually found at the beginning of source files
help: to annotate the function, change the attribute from inner to outer style
|
4 - #![windows_subsystem = "windows"]
4 + #[windows_subsystem = "windows"]

I've already implemented that solution and it doesn't work either.

ERROR: No shift provided
error: process didn't exit successfully: target\debug\cesar.exe (exit code: 2)

note: inner attributes, like #![no_std] , annotate the item enclosing them, and are usually found at the beginning of source files

It means that you should place those attributes on the beginning of source files like this:

#![windows_subsystem = "windows"] // before any other code
use std::io;

fn main() -> io::Result<()> {
    let mut buffer = String::new();
    let stdin = io::stdin(); // We get `Stdin` here.
    stdin.read_line(&mut buffer)?;
    Ok(())
}
1 Like

Thank you.
And I've fixed the code and it has no compilation problems except "Process exited with code 2." I thought this might just be a Windows problem, but on Unix the code doesn't work either.

#![windows_subsystem = "windows"]
use std::io::{self, Write};
use std::fmt::Display;
use std::{env, process};

fn main() {
    let shift: u8 = env::args().nth(1)
        .unwrap_or_else(|| exit_err("No shift provided", 2))
        .parse()
        .unwrap_or_else(|e| exit_err(e, 3));

    let plain = get_input()
        .unwrap_or_else(|e| exit_err(&e, e.raw_os_error().unwrap_or(-1)));

    let cipher = plain.chars()
        .map(|c| {
            let case = if c.is_uppercase() {'A'} else {'a'} as u8;
            if c.is_alphabetic() { (((c as u8 - case + shift) % 26) + case) as char } else { c }
        }).collect::<String>();

    println!("Cipher text: {}", cipher.trim());
}


fn get_input() -> io::Result<String> {
    print!("Plain text:  ");

    let mut buf = String::new();
    let stdin = io::stdin(); // We get `Stdin` here.
    stdin.read_line(&mut buf)?;
    Ok(buf)

}

fn exit_err<T: Display>(msg: T, code: i32) -> ! {
    let _ = writeln!(&mut io::stderr(), "ERROR: {}", msg);
    process::exit(code);
}

How are you executing this program? If you run it from GUI, it won't have anything in args[1] by default.