Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I read a single line from stdin?

Tags:

rust

I'm asking for the equivalent of fgets() in C.

let line = ...; println!("You entered: {}", line); 

I've read How to read user input in Rust?, but it asks how to read multiple lines; I want only one line.

I also read How do I read a single String from standard input?, but I'm not sure if it behaves like fgets() or sscanf("%s",...).

like image 277
sashoalm Avatar asked May 12 '15 08:05

sashoalm


People also ask

How do you read stdin lines?

The gets() function reads a line from the standard input stream stdin and stores it in buffer. The line consists of all characters up to but not including the first new-line character (\n) or EOF. The gets() function then replaces the new-line character, if read, with a null character (\0) before returning the line.

Which method is read a single line?

The readline() method helps to read just one line at a time, and it returns the first line from the file given. We will make use of readline() to read all the lines from the file given.


2 Answers

In How to read user input in Rust? you can see how to iterate over all lines:

use std::io::{self, BufRead};  fn main() {     let stdin = io::stdin();     for line in stdin.lock().lines() {         println!("{}", line.unwrap());     } } 

You can also manually iterate without a for-loop:

use std::io::{self, BufRead};  fn main() {     let stdin = io::stdin();     let mut iterator = stdin.lock().lines();     let line1 = iterator.next().unwrap().unwrap();     let line2 = iterator.next().unwrap().unwrap(); } 

You cannot write a one-liner to do what you want. But the following reads a single line (and is exactly the same answer as in How do I read a single String from standard input?):

use std::io::{self, BufRead};  fn main() {     let stdin = io::stdin();     let line1 = stdin.lock().lines().next().unwrap().unwrap(); } 

You can also use the text_io crate for super simple input:

#[macro_use] extern crate text_io;  fn main() {     // reads until a \n is encountered     let line: String = read!("{}\n"); } 
like image 116
oli_obk Avatar answered Sep 20 '22 23:09

oli_obk


If you truly want the equivalent to fgets, then @Gerstmann is right, you should use Stdin::read_line. This method accepts a buffer that you have more control of to put the string into:

use std::io::{self, BufRead};  fn main() {     let mut line = String::new();     let stdin = io::stdin();     stdin.lock().read_line(&mut line).unwrap();     println!("{}", line) } 

Unlike C, you can't accidentally overrun the buffer; it will be automatically resized if the input string is too big.

The answer from @oli_obk - ker is the idiomatic solution you will see most of the time. In it, the string is managed for you, and the interface is much cleaner.

like image 42
Shepmaster Avatar answered Sep 18 '22 23:09

Shepmaster