如何将含控制字符的字符串转换为指定格式的表示?
问题描述
需要将字符串转换为如下格式的表示形式:
- 输入
"Text\n\0"→ 输出"Text" 0x0A 0x00 - 输入
"Test1\t\x7FTest2"→ 输出"Test1" 0x09 0x7F "Test2"
规则:连续的可打印普通字符用双引号包裹,特殊控制字符(如换行、制表符、DEL等)转换为0xXX的十六进制格式,各部分用空格分隔。
现有代码问题分析
你当前的代码存在几个关键问题:
- 每个字符都单独添加双引号,导致普通字符被拆分成单个带引号的片段(比如
T变成"T"),无法将连续普通字符作为整体包裹 - 仅处理了
\t和\x7F两种特殊字符,未覆盖\n、\0等其他需要转换的控制字符 - 拼接逻辑错误,最终输出格式完全不符合预期
解决方案思路
核心采用分组处理逻辑:
- 维护一个缓冲区,收集连续的普通可打印字符
- 遇到特殊控制字符时,先将缓冲区内容(若有)用引号包裹加入结果,再将特殊字符转为
0xXX格式加入结果,最后清空缓冲区 - 遍历结束后,若缓冲区还有剩余普通字符,也要加入结果
这里定义的"特殊控制字符"为:ASCII码在0-31(不含空格0x20)和127(DEL)范围内的字符,其余视为普通可打印字符。
Rust 实现代码
fn format_string(s: &str) -> String { let mut result = Vec::new(); let mut current_normal = String::new(); for c in s.chars() { let code = c as u32; // 判断是否为需要转十六进制的控制字符 if (code <= 0x1F && code != 0x20) || code == 0x7F { // 先处理缓冲区中积累的普通字符 if !current_normal.is_empty() { result.push(format!("\"{}\"", current_normal)); current_normal.clear(); } // 将控制字符转为0xXX格式 result.push(format!("0x{:02X}", code)); } else { // 普通字符加入缓冲区 current_normal.push(c); } } // 处理遍历结束后剩余的普通字符 if !current_normal.is_empty() { result.push(format!("\"{}\"", current_normal)); } // 用空格连接所有片段 result.join(" ") } fn main() { // 测试案例1 let test1 = "Text\n\0"; let output1 = format_string(test1); println!("{}", output1); assert_eq!(output1, "\"Text\" 0x0A 0x00"); // 测试案例2 let test2 = "Test1\t\x7FTest2"; let output2 = format_string(test2); println!("{}", output2); assert_eq!(output2, "\"Test1\" 0x09 0x7F \"Test2\""); }
代码说明
format_string函数负责核心转换逻辑,接收输入字符串并返回格式化结果- 通过字符的ASCII码判断类型,确保所有目标控制字符都被正确转换
- 缓冲区机制保证连续普通字符被作为整体包裹,符合输出格式要求
- 最终通过
join(" ")完成所有片段的拼接,生成符合要求的字符串
内容的提问来源于stack exchange,提问作者i_am_learning
相关产品推荐
相关产品推荐

