如何将i32转换为表示ASCII字符的字符串

时间:2016-03-06 22:19:57

标签: rust ascii

我本周末在Rust重新做一个项目,我需要将i32转换为ASCII字符,并将其作为字符代码。到目前为止,我所有的都是一个可怕的match,我隐藏在文件的末尾。很遗憾,std::ascii不支持此转换。目前我只是在寻找一种不那么荒谬/更像Rust(?)的方式来做这件事。

fn to_ascii(i: &i32) -> String {
    let a = match *i {
        0 => "NUL",
        1 => "SOH",
        2 => "STX",
        // ...
        125 => "}",
        126 => "~",
        127 => "DEL",
        _ => "",
    }
    a
}

5 个答案:

答案 0 :(得分:9)

首先,您无需返回String&'static str就足够了。其次,您可以简单地设置一个&'static str s数组,其中包含您喜欢的所有代码表示,并使用.get(_)来获取相关的字符串切片,只要所有的char代码都是连续的(它们应该是如果我有我的ASCII权利)。即使它们不是,你总是可以把空字符串放在空白处。

代码应如下所示:

const CHARS: [&'static str; 128] = ["NUL", "SOH", "STX", .., "DEL"];

fn get_char_code(c: i32) -> &'static str {
    CHARS.get(c as usize).unwrap_or("")
}

答案 1 :(得分:4)

对于它的价值,我不介意match版本。唯一的调整是你不需要临时变量。我们建议您关注llogiq's answer并返回&'static str,如果需要,您的来电者可以转换为String

fn get_char_code(i: &i32) -> &'static str {
    match *i {
        0 => "NUL",
        1 => "SOH",
        2 => "STX",
        // ...
        125 => "}",
        126 => "~",
        127 => "DEL",
        _ => "",
    }
}

此外,我高度建议不要在此代码中使用“ASCII”一词。大多数程序员将“ASCII字符”关联为单个u8数据,这些数据映射到特定字符,标点符号或控制代码。

答案 2 :(得分:2)

您可以使用format!宏将char转换为String

fn to_ascii(i: &i32) -> String {
    match *i {
        x@0...127 => format!("{:?}", x as u8 as char),
        _ => "".into(),
    }
}

fn main() {
    for x in 0x09..0x12 {
        print!("{} ", to_ascii(&x));
    }
    println!("");
    //'\t' '\n' '\u{b}' '\u{c}' '\r' '\u{e}' '\u{f}' '\u{10}' '\u{11}' 

    for x in 0x30..0x40 {
        print!("{} ", to_ascii(&x));
    }
    println!("");
    //'0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ':' ';' '<' '=' '>' '?' 
}

这会返回'\u{0}'而不是"NUL",即转义码而不是缩写。如果你不喜欢它的外观,你可以使用一个巨大的匹配或字符串数​​组。

实际上,您只需要重新定义33个控制代码字符。对于其他可打印字符,您仍然可以使用format!

fn to_ascii(i: &i32) -> String {
    match *i {
        x@0...32 => ["NUL", "SOH", "STX", ..., "SPC"][x as usize].into(),
        x@33...126 => format!("{}", x as u8 as char),
        127 => "DEL".into(),
        _ => "".into(),
    }
}

对于更像Rust的方式,您可以使用Cow之类的智能指针作为返回类型:

use std::borrow::Cow;

fn to_ascii(i: &i32) -> Cow<'static, str> {
    match *i {
        x@0...32 => ["NUL", "SOH", "STX", ..., "SPC"][x as usize].into(),
        x@32...126 => format!("{}", x as u8 as char).into(),
        127 => "DEL".into(),
        _ => "".into(),
    }
}

详细了解Cow使用情况here

答案 3 :(得分:0)

您可以按如下所述进行投射:

println!("{}", 'A' as i8); // prints 65
println!("{}", 65 as char); // prints 'A'

答案 4 :(得分:0)

您可以将i32from_u32结合使用,而不是u32

use std::char::from_u32;

fn main() -> Result<(), u32> {
   let n = 0x21;
   let c = from_u32(n).ok_or(n)?;
   println!("{}", c);
   Ok(())
}