Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine reading a file line by line and iterating over each character in each line?

Tags:

rust

I started from this code, which just reads every line in a file, and which works well:

use std::io::{BufRead, BufReader};
use std::fs::File;

fn main() {
    let file = File::open("chry.fa").expect("cannot open file");
    let file = BufReader::new(file);
    for line in file.lines() {
        print!("{}", line.unwrap());
    }
}

... but then I tried to also loop over each character in each line, something like this:

use std::io::{BufRead, BufReader};
use std::fs::File;

fn main() {
    let file = File::open("chry.fa").expect("cannot open file");
    let file = BufReader::new(file);
    for line in file.lines() {
        for c in line.chars() {
            print!("{}", c.unwrap());
        }
    }
}

... but it turns out that this innermost for loop is not correct. I get the following error message:

error[E0599]: no method named `chars` found for type `std::result::Result<std::string::String, std::io::Error>` in the current scope
 --> src/main.rs:8:23
  |
8 |         for c in line.chars() {
  |                       ^^^^^
like image 882
Samuel Lampa Avatar asked Aug 06 '14 18:08

Samuel Lampa


1 Answers

You need to handle the potential error that could arise from each IO operation, represented by an io::Result which can contain either the requested data or an error. There are different ways to handle errors.

One way is to just ignore them and read whatever data we can get.

The code shows how this can be done:

use std::io::{BufRead, BufReader};
use std::fs::File;

fn main() {
    let file = File::open("chry.fa").expect("cannot open file");
    let file = BufReader::new(file);
    for line in file.lines().filter_map(|result| result.ok()) {
        for c in line.chars() {
            print!("{}", c);
        }
    }
}

The key points: file.lines() is an iterator that yields io::Result. In the filter_map, we convert the io::Result into an Option and filter any occurrences of None. We're then left with just plain lines (i.e. strings).

like image 50
A.B. Avatar answered Sep 29 '22 12:09

A.B.