【问题标题】:How do I print a vector of u8 as a string?如何将 u8 的向量打印为字符串?
【发布时间】:2015-03-23 07:40:15
【问题描述】:

这是我的代码:

let mut altbuf: Vec<u8> = Vec::new();

// Stuff here...

match stream.read_byte() {
    Ok(d) => altbuf.push(d),
    Err(e) => { println!("Error: {}", e); doneflag = true; }
}

for x in altbuf.iter() {
    println!("{}", x);
}

代码打印了正确的 u8 字节,但我一生都无法弄清楚如何将纯 u8 字节的向量转换为字符串?关于堆栈溢出的类似问题的唯一其他答案假设您正在使用 &[u8] 类型的向量。

【问题讨论】:

  • 欢迎来到 Stack Overflow!本着提出好问题的精神,您可能需要稍微改写您的问题。你的标题听起来就像你只想print the vector of bytes,这很容易。您的身体看起来像是您想将字节序列视为 UTF-8 字符串,但您没有提及字节的编码方式。您可能还想包含一些有关您正在尝试做的事情的细节;也许像read_to_string 这样的解决方案可以解决你真正的问题。

标签: rust


【解决方案1】:

如果您查看String documentation,您可以使用一些方法。有String::from_utf8 接受Vec&lt;u8&gt;,还有String::from_utf8_lossy 接受&amp;[u8]

请注意,Vec&lt;T&gt; 或多或少是 [T] 周围拥有的、可调整大小的包装器。也就是说,如果你有一个Vec&lt;u8&gt;,你可以把它变成一个&amp;[u8],最容易通过重新借用它(&amp;*some_vec)。您还可以直接在 Vec&lt;T&gt; 上调用在 &amp;[T] 上定义的任何方法(通常,这适用于实现 Deref 特征的事物)。

【讨论】:

  • 嗨,DK,您能否将我链接到澄清再借的资源?为了进一步扩展,当我尝试做 println!("{}", &*altbuf);我得到“特征 core::fmt::String 没有为类型 [u8] 实现”。
  • @AAnderson:你可能想要println!("{:?}", &amp;*altbuf){} 使用 String 格式化程序,用于面向用户的显示,而 {:?} 仅用于任何类型的内部表示。不是所有的都有一个String格式化器,但几乎所有的都有一个Show格式化器(这是{:?}使用的)。为了澄清重新借用:它基本上只是在一个事物上调用 Deref::deref 并保留它返回的引用(通常,deref 调用的结果会自动取消引用;额外的 &amp; 可以防止这种情况发生)。我不知道任何地方有任何更明确的解释。
【解决方案2】:

如果您的altbufu8 的向量,如图所示,这应该可以:

println!("{:?}", altbuf);

这是我拥有的一段经过编辑的代码,它做类似的事情:

let rebuilt: Vec<u8>;

unsafe {
    ret = proc_pidpath(pid, buffer_ptr, buffer_size);
    rebuilt = Vec::from_raw_parts(buffer_ptr as *mut u8, ret as usize, buffer_size as usize);
};

println!("Returned a {} byte string", ret);
println!("{:?}", rebuilt);

这会从由通过 FFI 调用的 C 函数填充的缓冲区重建 u8 值的向量,因此字节可以是任何内容,可能不是有效的 UTF-8。

当我运行它时,输出是:

返回一个 49 字节的字符串

[47, 85, 115, 101, 114, 115, 47, 97, 110, 100, 114, 101, 119, 47, 46, 114, 98, 101, 110, 118, 47, 118, 101, 114, 115, 105, 111, 110, 115, 47, 49, 46, 57, 46, 51, 45, 112, 51, 57, 50, 47、98、105、110、47、114、117、98、121]

您可以在{} 中使用different format strings 格式化打印的数字(十六进制、八进制等)。

您可以使用String::from_utf8(rebuilt) 从中获取String - 这可能会返回错误。

match String::from_utf8(rebuilt) {
    Ok(path) => Ok(path),
    Err(e) => Err(format!("Invalid UTF-8 sequence: {}", e)),
}

【讨论】:

  • Using a byte literal 可能是比使用 FFI 和 unsafe 更清晰的示例。您能否举一个将整个切片打印为十六进制数字的示例?我don't believe that works,但很高兴被证明是错误的。
  • 我认为这就够了,打印不同的格式可以作为读者的练习。
【解决方案3】:

要将字节打印为 UTF-8 字符串,请在字节可能格式不正确时使用 std::str::from_utf8。当字节总是有效的 UTF-8 时,使用不安全的std::str::from_utf8_unchecked

println!("{}", std::str::from_utf8(&altbuf).unwrap());

【讨论】:

    【解决方案4】:

    使用std::io中的write方法:

    use std::{io, io::Write};
    
    fn main() -> io::Result<()> {
       io::stdout().write(b"March\n")?;
       Ok(())
    }
    

    它打印出u8 的一部分,也称为字节串。

    io::stdout

    【讨论】:

      猜你喜欢
      • 2013-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      • 2023-02-05
      • 1970-01-01
      • 2014-02-09
      • 1970-01-01
      相关资源
      最近更新 更多