我正在尝试将 ASCII 字节向量转换为 Rust 字符串。我找到了
std::str::from_utf8()
函数,它应该能够处理所有 ASCII 字符串。由于某种原因,它无法读取版权符号,如以下代码示例所示:
let buf = vec![0xA9, 0x41, 0x52, 0x54]; //©ART
println!(
"{}",
match std::str::from_utf8(&buf) {
Ok(x) => x,
Err(x) => {
println!("ERROR: {}", x);
"failed"
}
}
);
// > ERROR: invalid utf-8 sequence of 1 bytes from index 0
根据 https://www.ascii-code.com/CP1252/169
0xA9
是有效的 ASCII 字符,并且根据 https://www.compart.com/en/unicode/U+00A9 也是一个有效的 UTF-8 字符。
我也尝试过
String::from_utf8_lossy()
,但这给了我�ART
作为结果,这不是字符串应该是的。
我在这里遗漏了一些东西还是这是 Rust 处理 ASCII 方式的一个错误?
0xA9
不是 ASCII; ASCII 只是 7 位编码,该值设置了第 8 位。
它可以解释为扩展 ASCII,这意味着它需要预先了解字符集才能将其解释为“©”。您可以在链接中看到它在 Windows-1252 字符集中是“©”,但 另一个链接 显示
0xA9
在代码页 437 字符集中是“⌐”。还有很多其他的字符集。
由于
0xA9
不是 ASCII,因此它不是 UTF8 - 至少不是它本身。第 8 位集表示它是多字节序列的一部分,更重要的是 0xA9
的位表示以 10xxxxxx
开头,这意味着它是多字节序列的 middle(请参阅 wikipedia 上的 UTF8) )。因此任何遇到这种情况的 UTF8 解码器(没有前面的多字节起始字符)都会拒绝它。
如果您想使用扩展的 ASCII 字符集并将其解码为 Rust 字符串,则需要以不同的方式进行解码。像 encoding-rs 这样的板条箱可能可以做到这一点。