如何在 Rust 中写入达到缓冲区大小的格式化字符串?

ikh*_*ikh 3 rust

当缓冲区大小不足时,似乎write!不要写参数。

use std::fmt::Write;
use arrayvec::ArrayString; // 'arrayvec' crate

fn main() {
    const SIZE: usize = 16;
    let mut s = ArrayString::<SIZE>::new();
    match write!(s, "{}{}", "0123456789", "0123456789") {
        Ok(_) => println!("success!"),
        Err(err) => println!("{}", err),
    }
    println!("{}", s);
}
Run Code Online (Sandbox Code Playgroud)

输出:

an error occurred when formatting an argument
0123456789
Run Code Online (Sandbox Code Playgroud)

但是,我想编写尽可能长的格式化字符串,直到缓冲区大小为止。在上面的例子中,我想要的输出是0123456789012345.

在C中,我们可以使用snprintf来完成这个任务。

an error occurred when formatting an argument
0123456789
Run Code Online (Sandbox Code Playgroud)

我怎样才能在 Rust 中做到这一点?

rod*_*igo 5

您可以为该特征编写自己的适配器。像这样的东西:

struct FixedWriter<'a, W>(&'a mut W);

impl<'a, W: Write> Write for FixedWriter<'a, W> {
    fn write_str(&mut self, s: &str) -> Result<(), std::fmt::Error> {
        for c in s.chars() {
            self.0.write_char(c)?;
        }
        Ok(())
    } 
}
Run Code Online (Sandbox Code Playgroud)

要使用它,只需包装原始作者的可变引用:

write!(FixedWriter(&mut s), "{}{}", "0123456789", "0123456789");
Run Code Online (Sandbox Code Playgroud)

你可以检查一下这个游乐场,打印出来的0123456789012345

您还可以通过将运算符替换为以下内容来消除错误以模拟成功?

if self.0.write_char(c).is_err() {
    break;
}
Run Code Online (Sandbox Code Playgroud)

,但从问题中尚不清楚您是否需要这个。