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

Sam*_*mpa 6 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

...但事实证明,这个最里面的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() {
  |                       ^^^^^
Run Code Online (Sandbox Code Playgroud)

A.B*_*.B. 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

关键点:file.lines()是一个产生的迭代器io::Result.在filter_map,我们将转换io::ResultOption和过滤任何出现的None.然后我们只留下简单的线条(即字符串).