ceving
ceving

Reputation: 23764

How to read and unread Unicode characters from stdin in Rust?

In C you use getc and ungetc to read bytes with look ahead for parsers.

What is the idiomatic way to do this in Rust with Unicode characters?

I tried io::stdin().chars() but there seems to be some kind of problem, I do not understand. The Compiler complains to use it.

Upvotes: 0

Views: 1109

Answers (1)

Stargateur
Stargateur

Reputation: 26697

In C, getc() and ungetc() are using a global FILE * named stdin, this allow then to buffering the input. In rust it's similar, stdin.lock() will give you StdinLock that implement Bufread, AFAIK there is no builtin way to do what you want, people will simply use lines(). Also, your requirement is more hard than it's look, you ask for unicode stream, while your C function doesn't care about this.

So here a basic solution:

use std::io;
use std::io::prelude::*;
use std::str;

fn main() {
    let stdin = io::stdin();
    let mut stdin = stdin.lock();

    while let Ok(buffer) = stdin.fill_buf() {
        let (input, to_consume) = match str::from_utf8(buffer) {
            Ok(input) => (input, input.len()),
            Err(e) => {
                let to_consume = e.valid_up_to();
                if to_consume == 0 {
                    break;
                }
                let input = unsafe { str::from_utf8_unchecked(&buffer[..to_consume]) };
                (input, to_consume)
            }
        };

        println!("{}", input);

        // here you could do many thing like .chars()

        stdin.consume(to_consume);
    }
}

Upvotes: 1

Related Questions