如何将字节格式化为2位十六进制字符串,以Rust为例
通常需要将一个字节打印为两个十六进制数字,例如如何将字节格式化为2位十六进制字符串,以Rust为例,rust,string-formatting,Rust,String Formatting,通常需要将一个字节打印为两个十六进制数字,例如10应给出0x0a。在Rust中,可以使用类似于println!(“{:#02x}”,10),但它给出了0xa 我尝试过的事情列表(使用和的信息和几个StackOverflow问题): println!(“{:#02x}”,10); 普林顿!(“{:#0x}”,10); 普林顿!(“{:#x}”,10); 普林顿!(“{:#x}”,10); 普林顿!(“{:#0x?}”,10); 普林顿!(“{:{02x}”,第10段); 它们都输出0xa,而不是
10
应给出0x0a
。在Rust中,可以使用类似于println!(“{:#02x}”,10)
,但它给出了0xa
我尝试过的事情列表(使用和的信息和几个StackOverflow问题):
println!(“{:#02x}”,10);
普林顿!(“{:#0x}”,10);
普林顿!(“{:#x}”,10);
普林顿!(“{:#x}”,10);
普林顿!(“{:#0x?}”,10);
普林顿!(“{:{02x}”,第10段);
它们都输出0xa
,而不是0x0A
所需的行为
此问题已编辑(删除相关情绪),随后标记为其他问题的副本。但其他答案并没有说明为什么上面的列表不起作用。
#
格式选项会导致意外的输出(0xa
),尤其是02
,令人惊讶的是,它根本没有任何效果!没有其他问题关注这一点,也没有特别关注
如果您使用:
println!("10 is 0x{:02x} in hex", 10); // ==> "0x0a"
而不是:
println!("10 is {:#02x} in hex", 10); // "0xa"
它起作用了
然而,正如评论员指出的,这不是错误,而是对02
的含义的混淆。它不是指最小有效位数,而是指最小字符总数,现在必须包括0x
。因此,这也是可行的:
println!("10 is {:#04x} in hex", 10); // "0x0a"
但这一解决方案和将其作为“正确”解决方案的文化都存在问题
首先请注意,通过#
包含0x
促进了总宽度的概念,而04
现在规定了总宽度。一个人需要在心里减去2才能得到有效数字,这是有效部分。无论如何,{:#04x}
将10000格式化为0x2710
,它占用6个字符,而不是4个字符。所以总宽度的概念失败了,作为一个概念,也许太微不足道了
此外,{:#03x}
、{:#02x}
和{:#01x}
都会产生与`{:#x}相同的行为,并且编译器(1.35)不会标记它们,尽管它们没有意义并且指示错误
其次,#
格式化程序仅对特定的数字表示有用,例如插入0x
,但不插入$
(另一种常见的十六进制表示格式)
第三,至关重要的是,总宽度的概念只有在使用#
格式化程序时才变得明确(然后在普通字节情况下无声地失败)。“代码”>格式化程序意味着Rube可以考虑总宽度,并且当它应用时应该使用它(即在固定宽度布局的上下文中)。p>
其余部分说明了为什么#
是一种特殊情况下的解决方案,以及为什么在一般情况下不建议使用它
应根据上下文选择格式化程序字符串,特别是在所选格式表达意图时,如何考虑在该上下文中显示数字。因此:
关注总宽度,这在执行刚性固定宽度表格布局时非常有用。在这种情况下,{:#04x}
格式化程序显然符合人体工程学<代码>{:#04x}在生成自定义格式字符串(给定固定宽度的上下文)时显然也很有用,例如当输出需要按需从十六进制更改为二进制时(例如,#
到{:#04x}
),尽管很难想象具体的情况{:#04b}
表示有效位数,当主要关注如何在给定有限空间的情况下表示一行上的信息时,这很有用。在这种情况下,常见的编辑是删除0x{02x}
。使用0x
时,只需删除0x{:02x}
,而使用0x
格式化程序时,需要同时删除{:04}
并用
替换04
。在这两种情况下,最终结果是相同的:02
,但{:02x}
需要一个概念转换#
#
格式化程序是否符合人体工程学和表达意图。使用与要实现的目标相匹配的格式。但在一般情况下,最好将#
视为一个相对模糊的特性。它的额外智能性只有在定义明确的情况下才可取
不幸的是,其他答案建议将{:#04x}
作为默认值,“正确”或“防锈剂”。但是,某些功能(#
)可用并不意味着:
-防锈剂,或建议使用它,
-总宽度的基本概念需要表达,或
-总宽度的概念应该推广到所有的Rust格式表达式(这是大多数答案所证明的根本问题)
总之,#
是可用的,但是0x{:02x}
通常更简单、更切中要害并且得到普遍认可。它是并且没有隐藏的缺陷 如模块中所述:
#
-此标志表示应使用“替代”打印形式。其他形式包括:
-在参数前面加一个0x#x
-在参数前面加一个0x#X
0x0a
是4个字符,而不是2个字符
如果请求的宽度小于所需的宽度,则将忽略请求的宽度,而使用最小宽度(此处为3个字符)
快速实验:
印刷品:
0xa
0xa
0xa
0x0a
0x00a
0x000a
一切都很好。只是
println!(“{:#04x}”,10)代码>--您如何知道这是一个长期存在的bug?您在github回购协议中有问题吗?#
标志应该有不同的含义
fn main() {
println!("{:#01x}", 10);
println!("{:#02x}", 10);
println!("{:#03x}", 10);
println!("{:#04x}", 10);
println!("{:#05x}", 10);
println!("{:#06x}", 10);
}