【问题标题】:Initializing an unsigned char array with hex values in C++在 C++ 中使用十六进制值初始化无符号字符数组
【发布时间】:2013-11-25 15:12:54
【问题描述】:

我想用 16 个十六进制值初始化一个无符号字符数组。但是,我似乎不知道如何正确初始化/访问这些值。当我尝试直观地访问它们时,我根本没有得到任何价值。

这是我的输出

The program was run with the following command: 4
Please be a value! -----> p
Here's some plaintext 

当使用下面的代码运行时 -

int main(int argc, char** argv)
{
  int n;
  if (argc > 1) {
    n = std::stof(argv[1]);
  } else {
    std::cerr << "Not enough arguments\n";
    return 1;
  }

  char buff[100];
  sprintf(buff,"The program was run with the following command: %d",n);
  std::cout << buff << std::endl;

unsigned char plaintext[16] = 
   {0x0f, 0xb0, 0xc0, 0x0f,
    0xa0, 0xa0, 0xa0, 0xa0,
    0x00, 0x00, 0xa0, 0xa0,
    0x00, 0x00, 0x00, 0x00};

unsigned char test = plaintext[1]^plaintext[2];

std::cout << "Please be a value! -----> " << test << std::endl;

std::cout << "Here's some plaintext " << plaintext[3] << std::endl;

  return 0;
}

根据上下文,这是学校小组项目的一部分。我们最终试图实现 Serpent 密码,但不断被 unsigned char 数组绊倒。我们的项目规范说我们必须有两个函数来获取 Java 中的字节数组。我假设 C++ 中最近的亲戚是无符号字符 []。否则我会使用矢量。在代码的其他地方,我实现了一个 setKey 函数,它接受一个 unsigned char 数组,将其值打包成 4 个 long long 整数(密钥需要是 256 位),并对这些整数执行各种位移和异或操作以生成加密算法所需的密钥。希望这是我想要做的足够的背景。我猜我只是在这里忽略了一些基本的 C++ 功能。感谢您的所有帮助!

【问题讨论】:

  • 那么问题出在哪里?
  • 使用强制转换将您的 char 输入转换为 usnsigned char..
  • 使用cout 打印unsigned char 默认打印ASCII 字符。如果您只想打印该值,请执行以下操作:std::cout&lt;&lt;std::hex&lt;&lt;static_cast&lt;unsigned int&gt;(test)&lt;&lt;std::endl;
  • std::stof 将字符串转换为浮点值。你的意思是std::stod

标签: c++ arrays hex unsigned-char


【解决方案1】:

char 是一个 8 位值,能够存储 -128 char 是用于指示 ASCII 或 utf 编码值的表示。 “编码”表示字符集中的符号/字母已分配数值。将元素周期表视为元素的编码,因此“H”(氢)编码为 1,锗编码为 32。在 ASCII(和 UTF-8)表中,位置 32 表示我们称为“空格”的字符。

当您在 char 值上使用 operator &lt;&lt; 时,默认行为是假设您正在向它传递字符编码,例如ASCII 字符代码。如果你这样做了

char c = 'z';
char d = 122;
char e = 0x7A;
char f = '\x7a';
std::cout << c << d << e << f << "\n";

所有四个分配都是等价的。 'z' 是 char(122) 的快捷方式/语法糖,0x7A 是 122 的十六进制,而 '\x7a' 是一个转义符,形成值为 0x7a 或 122 的 ascii 字符 - 即 z。

许多新程序员的错误之处在于他们这样做:

char n = 8;
std::cout << n << endl;

这不会打印“8”,它会在 ASCII 表中的第 8 位打印 ASCII 字符。

想一想:

char n = 8;  // stores the value 8
char n = a;  // what does this store?
char n = '8'; // why is this different than the first line?

让我们回顾一下:当你将120存储在一个变量中时,它可以表示ASCII字符'x',但最终存储的只是数值120,简单明了。

特别是:当您将122 传递给最终将使用它从使用Latin1、ISO-8859-1、UTF-8 或类似编码的字符集中查找字体条目的函数时,然后120表示'z'

归根结底,char 只是标准整数值类型之一,它可以存储值-128 &lt;= n &lt;= +127,它可以简单地提升为shortintlonglong long等等等等。

虽然它通常用于表示字符,但它也经常被用来表示“我只存储非常小的值”(例如整数百分比)。

int incoming = 5000;
int outgoing = 4000;
char percent = char(outgoing * 100 / incoming);

如果要打印数值,只需将其提升为不同的值类型即可:

std::cout << (unsigned int)test << "\n";
std::cout << unsigned int(test) << "\n";

或首选的 C++ 方式

std::cout << static_cast<unsigned int>(test) << "\n";

【讨论】:

  • A char 当然可以存储从 0 到 127 的值。其他任何值都是实现定义的。
【解决方案2】:

我认为(不完全清楚你在问什么)答案就这么简单

std::cout << "Please be a value! -----> " << static_cast<unsigned>(test) << std::endl;

如果要输出 char 或 unsigned char 的数值,则必须先将其强制转换为 int 或 unsigned。

不出所料,默认情况下,字符输出为字符而不是整数。

顺便说一句,这个时髦的代码

char buff[100];
sprintf(buff,"The program was run with the following command: %d",n);
std::cout << buff << std::endl;

更简单的写成

std::cout << "The program was run with the following command: " << n << std::endl;

【讨论】:

    【解决方案3】:

    std::coutstd::cin 始终将 char 变量视为 char
    如果你想以 int 形式输入或输出,你必须像下面这样手动操作。

    std::cin >> int_var; c = int_var;
    std::cout << (int)c;
    

    如果使用scanf或printf,则不存在格式参数(“%d”、“%c”、“%s”)告诉如何转换输入缓冲区(整数、字符、字符串)这样的问题。

    【讨论】:

      猜你喜欢
      • 2012-03-03
      • 2016-02-01
      • 1970-01-01
      • 2015-07-23
      • 2015-12-14
      • 2013-04-15
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      相关资源
      最近更新 更多