'Print error message with missing parameter

I have following code that works fine if parameter (the file .csv) is present. It must be, in W10 cmd: target\debug\testecsv < file.csv But it I enter: target\debug\testecsv without the required parameter "file.csv" routine prints "begining..." and prompt keeps as "waiting" for the parameter and I must finish with Ctrl + c. If the parameter "< file.csv" is not present, I want to print an error msg and exit the routine. Thanks in advance.

extern crate csv;
use std::io;
use std::process;
use std::error::Error;
use serde::Deserialize;

#[derive(Deserialize)]
struct Registro {
    dia: String,
    kg: f32
}
fn lercsv() -> Result<(), Box<dyn Error>> {
    let mut leitor = csv::Reader::from_reader(io::stdin());
    for l in leitor.deserialize() {
        let registro: Registro = l?;
        println!("dia {} peso foi {} kg", registro.dia, registro.kg);
    }
    Ok(())
}
fn main() {
    println!("begining...");
    if let Err(e) = lercsv() {
        println!("{}", e);
        process::exit(1);
    }
}


Solution 1:[1]

The code you posted simply reads the standard input provided by the shell. Your program is unaware of the fact that the data is read from a file. If you want finer control over error handling, you need to parse the command-line yourself, and explicitly read the file.

extern crate csv;
use std::env;
use std::io;
use std::process;
use std::error::Error;
use std::fs::File;
use serde::Deserialize;

#[derive(Deserialize)]
struct Registro {
    dia: String,
    kg: f32
}

fn lercsv() -> Result<(), Box<dyn Error>> {
    // read 1st argument (after the program name itself)
    let filename = env::args().nth(1).ok_or("Missing parameter")?;
    // open the specified file and obtain a reader
    let reader = File::open(filename)?;
    let mut leitor = csv::Reader::from_reader(reader);
    for l in leitor.deserialize() {
        let registro: Registro = l?;
        println!("dia {} peso foi {} kg", registro.dia, registro.kg);
    }
    Ok(())
}

fn main() {
    println!("begining...");
    if let Err(e) = lercsv() {
        println!("{}", e);
        process::exit(1);
    }
}

Playground link

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SirDarius