gpt4 book ai didi

rust - 迭代同一文件的行后,迭代文件的字节为空

转载 作者:行者123 更新时间:2023-11-29 08:07:13 30 4
gpt4 key购买 nike

我正在创建类似于 wc 命令的东西。计算行数似乎工作正常,但计算字节数总是返回 0。计算单词数也不起作用;输出似乎“挂起”,就像在等待什么。

我意识到它的制作方式(读取文件 3 次以上)并不是执行此操作的最佳方式,但我只想要一个有效且简单的示例

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

fn main() {
let arg = &std::env::args()
.nth(1)
.expect("No file operand found")
.to_owned();
let file = File::open(arg).expect("Unable to open file for reading");

let lines = count_lines(&file);
print!("{} ", lines);
let bytes = count_bytes(&file);
println!("{}", bytes);
let words = count_words(&file);
print!("{} ", words);
}

fn count_lines(file: &File) -> u32 {
let mut count: u32 = 0;
BufReader::new(file).lines().for_each(|f| {
if f.is_ok() {
count += 1;
}
});

count
}

fn count_bytes(file: &File) -> u32 {
let mut count: usize = 0;
BufReader::new(file).bytes().for_each(|f| {
if f.is_ok() {
count += 1;
}
});

count as u32
}

fn count_words(file: &File) -> u32 {
let mut count: u32 = 0;

let mut buf: Vec<u8> = Vec::new();
let mut reader = BufReader::new(file);
while let Ok(_) = reader.read_until(b' ', &mut buf) {
count += 1;
}

count
}

最佳答案

你的问题是你打开文件一次,读取完整的文件,然后假设它会被神奇地重置。

一个 File 有一个位置“指针”来知道接下来要读取哪个字节。读取一个字节后,该位置将递增 1,因此下一个读取调用将读取下一个字节而不是同一个字节。

您可以使用 File::seek 更改此位置在调用 count_linescount_bytescount_words 之间。

use std::io::{Seek, SeekFrom};

fn main() {
let arg = &std::env::args()
.nth(1)
.expect("No file operand found")
.to_owned();
let mut file = File::open(arg).expect("Unable to open file for reading");

let lines = count_lines(&file);
print!("{} ", lines);

file.seek(SeekFrom::Start(0)).expect("Seek failed");
let bytes = count_bytes(&file);
println!("{}", bytes);

file.seek(SeekFrom::Start(0)).expect("Seek failed");
let words = count_words(&file);
print!("{} ", words);
}

为了进一步解决您的代码,它被认为不是很“使用rust ”。使用 Iterator::count 可以简化您的手动计数.

fn count_lines(file: &File) -> u32 {
BufReader::new(file).lines().count() as u32
}

fn count_bytes(file: &File) -> u32 {
BufReader::new(file).bytes().count() as u32
}

count_words 函数“挂起”的原因是您忽略了读取的字节数。当 read_until 到达 EOF(文件末尾)时,它将返回 0 作为数量。你必须引入一个中断条件,例如

fn count_words(file: &File) -> u32 {
let mut count: u32 = 0;

let mut buf: Vec<u8> = Vec::new();
let mut reader = BufReader::new(file);
while let Ok(amount) = reader.read_until(b' ', &mut buf) {
if amount == 0 {
break
}
count += 1;
}

count
}

请注意,这个实现并不是真正正确的,因为 "hello "(最后两个空格)会给你 2 而不是 1 ,但这取决于您来解决。确保 add some tests以确保一切正常。

关于rust - 迭代同一文件的行后,迭代文件的字节为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55829045/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com