【发布时间】:2016-02-16 02:22:10
【问题描述】:
当我输入 0x123456789 我得到不正确的输出,我不知道为什么。起初我认为这是一个最大可能的 int 值问题,但我将变量更改为 unsigned long 并且问题仍然存在。
#include <iostream>
using namespace std;
long htoi(char s[]);
int main()
{
cout << "Enter Hex \n";
char hexstring[20];
cin >> hexstring;
cout << htoi(hexstring) << "\n";
}
//Converts string to hex
long htoi(char s[])
{
int charsize = 0;
while (s[charsize] != '\0')
{
charsize++;
}
int base = 1;
unsigned long total = 0;
unsigned long multiplier = 1;
for (int i = charsize; i >= 0; i--)
{
if (s[i] == '0' || s[i] == 'x' || s[i] == 'X' || s[i] == '\0')
{
continue;
}
if ( (s[i] >= '0') && (s[i] <= '9') )
{
total = total + ((s[i] - '0') * multiplier);
multiplier = multiplier * 16UL;
continue;
}
if ((s[i] >= 'A') && (s[i] <= 'F'))
{
total = total + ((s[i] - '7') * multiplier); //'7' equals 55 in decimal, while 'A' equals 65
multiplier = multiplier * 16UL;
continue;
}
if ((s[i] >= 'a') && (s[i] <= 'f'))
{
total = total + ((s[i] - 'W') * multiplier); //W equals 87 in decimal, while 'a' equals 97
multiplier = multiplier * 16UL;
continue;
}
}
return total;
}
【问题讨论】:
-
使用调试器或打印语句逐步执行代码。你知道你对每一行的期望。对照实际值检查它。
-
如果我可以提出一个建议,但是,你是在倒退。从 第一个 数字开始,将其与您的结果 (
total) 相结合,然后乘以 16。重复直到没有数字为止。顺便说一句,如果您使用签名号码,您会遇到问题。使用_unsigned_ long long。 -
@Duthomhas 如果向后完成会更容易,因为十六进制是从右到左读取的。如果我从左到右阅读,我需要将我的代码重新编写到乘数以最高幂(由十六进制数字的数量驱动)开始的位置,并在每次读取十六进制字符时除以 16。此外,当用户以以下形式输入十六进制时,乘数会不必要地被除:0xABCDEFG 因为 0 是一个十六进制字符,如果 0x 是按顺序排列的,这会使我的代码复杂化以忽略前两个字符。向后阅读将是编写此代码的最简单和最有效的方法(请参阅 sol)。
-
您不得不问我们如何实现它,但不知何故您知道如何做?这很有趣,因为我可以用三行代码完成。提示:当你在学习的时候,不要假设你比别人更了解事物。顺便说一句,就像 any 数字一样,十六进制是从左到右读取的;最重要到最不重要。
-
@Duthomhas 如果我让您觉得自己名誉扫地,我深表歉意,那不是我的本意。我知道我是一个初学者,所以我不相信我比其他人更了解代码。我认为看到您的示例在三行中将十六进制转换为 int 而不使用 C/C++ 库中预先编写的解析器因此 strtol 函数会很有趣。我总是乐于扩展我的知识。我找不到任何地方严格从左到右读取十六进制,因为我已经看到它是双向的,但我确实喜欢从最重要到最不重要的想法。
标签: c++ string function hex decimal