【问题标题】:Converting uint8_t to binary将 uint8_t 转换为二进制
【发布时间】:2020-01-30 09:15:17
【问题描述】:

在课堂上,我们正在学习如何创建 ppm6 文件。 我们有一个uint8_t 的二维数组,该类要求我们使用fwrite() 以某种方式将此二维数组转换为如下所示的一堆二进制字符:

ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿÿ\0ÿ

如何做到这一点?

班上有人说它会自动进行转换,这对我来说根本没有意义。这就是我目前正在返回的内容。 color_array 是一个由uint8_t 组成的二维数组,每个color_array[i] 为三个uint8_ts 提供一个数组。

fwrite(color_array[i], sizeof(uint8_t), 3, output);

我的输出是:

???????????????????

【问题讨论】:

  • 如何读取输出?用哪个程序?查看那里的真实数据的十六进制代码会很有用。
  • 二进制数据的呈现通常取决于生成输出的软件。如果您使用十六进制文件查看器/编辑器,它将显示为十六进制值。如果您使用标准编辑器(想想“Notepad++”),它将以您选择的编码进行解释;只是一些例子:ANSI、UTF-8。如果您使用 shell 或命令解释器,它也将在编码中进行解释。您向我们展示的示例输出来自哪里?
  • 以文本形式查看的二进制数据在大多数情况下看起来都是垃圾。如果您想查看它实际包含的内容,请使用十六进制转储工具。

标签: c binary-data ppm


【解决方案1】:

首先,一些基础知识。

“以二进制形式”写入数据并不意味着什么特别。该程序只是获取它在 RAM 中的任何内容并将其转储到文件中。这意味着这样的事情:

uint8_t x = 10;
fwrite(&x, sizeof(uint8_t), 1, some_file);

会导致10的二进制值直接写入打开的some_file。由于值10 存储在uint_8 中并且sizeof(uint_8) 为1(一个字节),因此该调用最终将只写入一个字节。 10 的二进制表示(作为一个字节)是00001010

如果在编写二进制文件后,您尝试使用文本编辑器打开它,或者您尝试使用cat 之类的方式将其打印到终端,它将被解释为文本基于在文本编辑器或终端中配置的encoding。这很可能会导致随机和奇怪的字母,因为二进制数据并不意味着代表一些文本,而只是一个字节的整数值。这只能由创建文件的人知道。二进制数据本身可以有无限的解释。


话虽如此,你所看到的:

ÿ\0\0ÿ\0\0ÿ\0\0ÿ\0\0ÿ

正是我所描述的。为了能够看到 real 值,您应该将该输出传递给十六进制查看器,例如 hd 命令:

$ hd your_file
00000000  c3 bf 00 00 c3 bf 00 00  c3 bf 00 00 c3 bf 00 00  |................|                                                                        
00000010  c3 bf                                             |..|                                                                                     
00000012         

如果该文本是使用 UTF-8 显示的(很可能),则写入的字节就是上面显示的字节,从十六进制转换为十进制,是:

195 191 0 0 195 191 0 0 195 191 0 0 195 191 0 0 195 191

现在,谈谈您发布的实际代码:

假设您的二维数组是 Nx3,您所做的是正确的。要将二进制数据写入文件,fwrite() 是正确的函数。

所以,这个:

fwrite(color_array[i], sizeof(uint8_t), 3, output);

正在将二维数组的第 i 行(由 3 个uint8_t 值组成)以二进制形式写入文件。

例如,考虑以下问题:

uint8_t color_array[2][3] = {{1, 2, 3}, {10, 11, 12}};

fwrite(color_array[0], sizeof(uint8_t), 3, output);
fwrite(color_array[1], sizeof(uint8_t), 3, output);

这将使您最终得到一个如下所示的文件:

$ hd your_file
00000000  01 02 03 0a 0b 0c                                 |......|                                                                                  
00000006 

【讨论】:

  • 也许你可以补充一下 hd 和 hexdump 是一样的
  • @YesThatIsMyName 好吧,他们不是。 hdhexdump 是不同的程序。如果这就是您的意思,它们都是十六进制查看器。
  • 手册页上写着:HEXDUMP(1) BSD 通用命令手册 HEXDUMP(1) NAME hexdump, hd — ASCII、十进制、十六进制、八进制转储
  • @YesThatIsMyName 这并不意味着什么,它只是两个命令的手册页。他们采取类似的选择,但是是两个不同的程序。举个例子,hd(不带参数)默认显示 one-byte 十六进制值及其 ASCII 表示,而 hexdump 显示 two-byte hex没有 ASCII 表示的值。
  • @YesThatIsMyName 我不这么认为。它确实没有增加解释的价值,只会给没有经验的用户造成混乱。这不是关于十六进制查看器的问题,我使用hd 只是为了说明一些示例。
猜你喜欢
  • 1970-01-01
  • 2019-03-18
  • 2016-10-12
  • 2018-09-03
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 2011-09-04
  • 2014-11-07
相关资源
最近更新 更多