如何逐行读取文件并迭代每行中的每个字符?

时间:2014-08-06 18:32:35

标签: rust

我从这段代码开始,它只读取文件中的每一行,并且效果很好:

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());
    }
}

...但后来我试图在每一行中循环每个字符,如下所示:

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());
        }
    }
}

...但事实证明,这个最里面的for循环是不正确的。我收到以下错误消息:

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() {
  |                       ^^^^^

1 个答案:

答案 0 :(得分:13)

您需要处理每个IO操作可能产生的潜在错误,由io::Result表示,其中包含请求的数据或错误。有不同的方法来处理错误。

一种方法是忽略它们并读取我们可以得到的任何数据。

代码显示了如何做到这一点:

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);
        }
    }
}

关键点:file.lines()是一个产生io::Result的迭代器。在filter_map中,我们将io::Result转换为Option并过滤None的所有匹配项。然后我们只留下简单的线条(即字符串)。