【问题标题】:Printing integers as a set of 4 bytes arranged in little endian?将整数打印为一组以小端排列的 4 个字节?
【发布时间】:2013-07-28 21:16:23
【问题描述】:

我有一个由 256 个无符号整数组成的数组,称为频率 [256](每个 ascii 值一个整数)。我的目标是通读输入,并且对于每个字符,我都会增加数组中与其对应的整数(例如,字符“A”将导致频率 [65] 整数增加一)并且当输入结束时我必须在little endian form 中将每个整数输出为 4 个字符。

到目前为止,我已经创建了一个循环,该循环遍历输入并增加数组中每个相应的整数。但是我对如何以小端形式输出每个整数感到非常困惑。我知道每个整数的四个字节中的每个字节都应该作为一个字符输出(例如,小端序中的无符号整数 1 是“00000001 00000000 00000000 00000000”,我希望将其输出为对应于那些的 4 个 ascii 字符字节)。

但是我如何在我的代码中获得无符号整数的二进制表示,我将如何将它切碎并重新排列?

感谢您的帮助。

【问题讨论】:

    标签: c++ character-encoding endianness


    【解决方案1】:

    为了硬件可移植性,请使用以下解决方案:

    int freqs[256];
    for (int i = 0; i < 256; ++i)
        printf("%02x %02x %02x %02x\n", (freqs[i] >> 0 ) & 0xFF
                                      , (freqs[i] >> 8 ) & 0xFF
                                      , (freqs[i] >> 16) & 0xFF
                                      , (freqs[i] >> 24) & 0xFF);
    

    【讨论】:

    • 我不知道硬件是什么,该程序旨在在所有计算机上运行相同。感谢您的回复,我想知道您是否可以再解释一下您的第二个代码块。另外我用的是c++而不是c,有没有办法用cout完成同样的任务?
    • 第二个代码使用按位运算从每个值中提取单个字节,以小端顺序(最低有效字节到最高有效字节)。这是 C++ 中的打印行:cout &lt;&lt; setfill('0') &lt;&lt; setw(2) &lt;&lt; hex &lt;&lt; ((freqs[i]&gt;&gt;0) &amp; 0xFF) &lt;&lt; ((freqs[i]&gt;&gt;8) &amp; 0xFF) &lt;&lt; ((freqs[i]&gt;&gt;16) &amp; 0xFF) &lt;&lt; ((freqs[i]&gt;&gt;24) &amp; 0xFF)
    • 用 0xFF 'and' 字节的目的是什么?这是否确保它只输出 8 位,因为 cout-ing freqs[i]>>n 仍然会输出完整的 32 位 int 对吗?
    • 我在 for 循环中实现了您的代码,它似乎正在打印整数(我假设它正在打印 8 位二进制到十进制的整数转换)。如果我想让它打印出那个字符版本,应该在每个 ((freqs[i]>>n) & 0xFF) 块前面加上一个简单的 (char) 吗?
    • @Antonio 答案不是完全可移植的:它假定为 8 位 charsizeof(int) == 4。但它肯定比大多数提议的解决方案要好。它甚至可以在具有奇怪字节顺序的系统上工作,既不是大端也不是小端。
    【解决方案2】:

    你可以使用memcpy复制一块内存。

    char tab[4] ; 
    memcpy(tab, frequencies+i, sizeof(int));
    

    现在,tab[0]、tab[1] 等将成为您的角色。

    【讨论】:

    • 嗯,这是一个非常有趣的想法!感谢您的输入!我可以为频率数组中的所有无符号整数使用一个制表符声明,还是每次都需要声明一个新制表符? (基本上 memcpy 会正确覆盖选项卡吗?)此外,memcpy 如何处理复制大于其目标的内容?
    • @user0123 - 如果硬件是大端,则此解决方案将不起作用。
    • 啊,那不好。我的程序必须在两个系统上运行相同。
    • 问题中没有关于 big-endian 的内容 :) 没错,它是唯一的 little-endian 解决方案。很高兴我能以任何形式提供帮助。
    【解决方案3】:

    从大端到小端交换的程序:Little Endian - Big Endian Problem

    要了解您的系统是小端还是大端:https://stackoverflow.com/a/1024954/2436175

    将您的字符/整数转换为一组可打印位:https://stackoverflow.com/a/7349767/2436175

    【讨论】:

      【解决方案4】:

      这里的“小端”不是很清楚。 整数本身没有字节顺序;字节序只会出现 当你把它们切成小块时,它们就起作用了。那么哪个 对您而言,较小的部分是指:字节或字符。如果是字符, 只需以正常方式转换,并反转生成的 细绳。如果字节(或任何其他较小的部分),每个人 字节可以表示为int的函数:i &amp; 0xFF 计算低位字节,(i &gt;&gt; 8) &amp; 0xFF 下一个 最低,以此类推。 (如果字节不是 8 位,则更改 对应的移位值和掩码。)

      关于您的第二段: int 不一定对应一个字符,不管 的编码。例如,对于您显示的四个字节,无 其中的一个对应于任何通常的字符 编码。

      关于最后一段:获取二进制文件 无符号整数的表示,使用相同的算法 您将用于任何表示:

      std::string
      asText( unsigned int value, int base, int minDigits = 1 )
      {
          static std::string digits( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
          assert( base >= 2 && base <= digits.size() );
          std::string results;
          while ( value != 0 || minDigits > 0 ) {
              results += digits[ value % base ];
              value /= base;
              -- minDigits;
          }
          //  results is now little endian.  For the normal big-endian
          std::reverse( results.begin(), results.end() );
          return results;
      }
      

      以等于 2 的基数调用,这将为您提供二进制文件 表示。

      【讨论】:

        猜你喜欢
        • 2011-01-03
        • 1970-01-01
        • 2012-06-17
        • 1970-01-01
        • 2014-10-27
        • 2015-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多