十六进制转换在CPP中出现了严重的错误
Hex conversion going terribly wrong in CPP
我正在尝试读取unsigned char数组中的命令行十六进制参数。我的代码:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <memory.h>
#include <cstring>
unsigned char key[16] ={0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
int main(int argc, char** argv){
char hex_pref[]="0x";
for (int i = 0; i < 16; i++){
key[i] = strtol(strcat(hex_pref, argv[i]), NULL, 16);
std::cout << argv[i] << "t";
}
std::cout << std::endl;
for (int i = 0; i < 16; i++)
std::cout << key[i] << "t";
std::cout << std::endl;
return 0;
}
程序的输出是非常不可预测的。每次我改变参数都会得到奇怪的结果。
我像
那样运行它./a.out ab 32 bf 00 0a 2e 4c 3d 25 db 66 22 84 fb 19 72
我试着调试,但没有答案。有什么建议吗?谢谢你。
执行了以下操作,但问题仍然存在,因为我无法验证密钥[I]是什么。
char hex_pref[4];
strcpy(hex_pref, "0x");
for (int i = 0; i < 16; i++){
strcat(hex_pref, argv[i]);
key[i] = strtol(hex_pref, NULL, 16);
//std::cout << argv[i] << "t";
}
std::cout << std::endl;
for (int i = 0; i < 16; i++)
std::cout << std::hex << key[i] << "t";
std::cout << std::endl;
return 0;
又一次失败尝试。现在,正如一位用户所说,即使使用std::hex
, key[i]也会打印垃圾。for (int i = 1; i < 17; i++){
//strcat(hex_pref, argv[i]);
key[i-1] = strtol(argv[i], NULL, 16);
//std::cout << argv[i] << "t";
}
std::cout << std::endl;
for (int i = 0; i < 16; i++)
std::cout << std::hex << key[i] << "t";
std::cout << std::endl;
return 0;
问题一:
argv[0]
不是第一个用户提供的参数。arg[0]
保留给实现使用。通常它是用来执行程序的命令。在这种情况下"./a.out"。"。/。因为strtol
没有被检查有效性,所以不会转换为导致不良行为的整数。
解决方案:从argv[1]
开始,相应增加for循环。
附录:不要忽略strtol
的第二个参数。采摘起来很方便关闭无效输入。用户可能会输入"fubar",而你会错过它。
问题2:
部分被Robin Johnson的回答覆盖。hex_pref
不够长,不能容纳"0x"和输入user参数。幸运的是,这不是必须的。strtol
的第三个参数指定输入是十六进制。
解决方案:删除strcat
和hex_pref
。
问题3:
您正在输出无符号字符。这些将被<<
解释为输入的任何数字的ASCII值。这将给你讨厌的垃圾字符输出,哔哔声和其他任何恰好由这个数字表示的东西,不是漂亮的,干净的十六进制值。
解决方案:打印时将unsigned int key
或将key[i]
转换为unsigned int
。
Semi-problem 4:
你没有输出十六进制的结果。
解决方案:使用std::hex
strcat()试图将结果放入未准备的hex_pref,因为它的大小为"2"。这是行不通的。
http://www.cplusplus.com/reference/cstring/strcat/保持你原来的方法。以下代码是"正确的"。并产生良好的输出(见下面的代码)。
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <memory.h>
#include <cstring>
unsigned char key[16] = { 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
int main(int argc, char** argv)
{
char hex_pref[] = "0x";
for (int i = 1; i < 17 && i < argc; ++i)
{
std::cout << argv[i] << "t";
if ( strlen(argv[i]) < 3)
{
char result[5];
result[0]= 0;
strcat(result, hex_pref);
strcat(result, argv[i]);
key[i-1] = char(strtol(result, NULL, 16));
}
}
std::cout << std::endl;
for (int i = 0; i < 16; ++i)
{
std::cout << int(key[i]) << "t";
}
std::cout << std::endl;
return 0;
}
输出是:
C:UsersrjohnsonDesktopWorkspacesTestHexDebug>testhex ab 32 bf 00 0a 2e 4c 3d 25 db 66 22 84 fb 19 72
ab 32 bf 00 0a 2e 4c 3d 25 db 66 22 84 fb 19 72
171 50 191 0 10 46 76 61 37 219 102 34 132 251 25 114
使用流和字符串的另一种方法是"真正的"方法。这里没有足够的空间提供完整的解释,但是有很多教程和成熟的例子。
string result;
result += "0x";
result += argv[i];
key[i]= strtol(result.c_str(), NULL, 16);
您的代码的可能版本如下:无论如何,我会考虑一个更好的设计。我很确定下面的代码也可能出现很多问题。
unsigned long long key[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
int main(int argc, char** argv) {
for (int i = 1; i < argc; i++) {
sscanf(argv[i], "%x", &(key[i]));
std::cout << argv[i] << "t";
}
std::cout << std::endl << std::endl;
for (int i = 0; i < argc; i++)
std::cout << key[i] << "t";
std::cout << std::endl;
getchar();
return 0;
}
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- C++使用params创建线程函数会导致转换错误
- 在混合代码库中将C转换为C++时出现许多包含错误
- 为什么g++在未执行的代码处标记强制转换错误
- 错误:从"int"到枚举c++的转换无效
- 错误 C2679:二进制"<<":未找到采用类型 'std::string_view' 的右侧操作数的运算符(或者没有可接受的转换)
- 从标准::未来<void>到非标量标准::未来<bool>引发的错误转换
- 使用宏的错误转换
- 在 opencv 中使用 Color_YUV2BGR 从 YUV 到 BGR 的错误转换
- 无法通过此操作,因为类型的错误转换
- PyQt5:使用自定义信号时 int 对象的错误转换
- 从长途错误转换
- C 错误:转换为非量表类型
- C 错误:转换为执行字符集
- 使用SOCI从PostgreSQL数据库获取数据时发生错误转换
- 分段错误C++转换问题
- 在ARM上的Qt中从双精度到QString的错误转换
- C++浮点转换为Python浮点错误转换
- 错误:转换为非标量类型