如何在C中手动将十进制值转换为十六进制字符串?
nb 我知道这个问题之前已经在 StackOverflow 上以各种不同的方式和情况被问过,但搜索我寻求的答案并不能完全帮助我的具体情况。因此,虽然这最初看起来像是问题的重复,例如 我怎样才能在C中将整数转换为十六进制字符串?给出的答案是准确的,但对我没有用。
我的问题是如何手动将十进制整数转换为十六进制字符串。我知道 stdlib.h 和 printf 有一些节拍技巧,但这是一项大学任务,我需要手动完成(教授的命令)。但是,我们可以寻求帮助。
使用古老的“除以 16 并将余数转换为十六进制并反转值” 方法来获取十六进制字符串,但我的代码中一定有一个大错误,因为它没有给我返回值,例如“BC”代表十进制值“188”。
假设该算法永远不需要查找大于 256(或 FF)的小数的十六进制值。虽然参数的传递可能不是最佳或理想的,但我们被告知要使用它(尽管我可以修改 getHexValue 函数,因为我自己编写了该函数)。
这就是我到目前为止所拥有的:
/* Function to get the hex character for a decimal (value) between
* 0 and 16. Invalid values are returned as -1.
*/
char getHexValue(int value)
{
if (value < 0) return -1;
if (value > 16) return -1;
if (value <= 9) return (char)value;
value -= 10;
return (char)('A' + value);
}
/* Function asciiToHexadecimal() converts a given character (inputChar) to
* its hexadecimal (base 16) equivalent, stored as a string of
* hexadecimal digits in hexString. This function will be used in menu
* option 1.
*/
void asciiToHexadecimal(char inputChar, char *hexString)
{
int i = 0;
int remainders[2];
int result = (int)inputChar;
while (result) {
remainders[i++] = result % 16;
result /= (int)16;
}
int j = 0;
for (i = 2; i >= 0; --i) {
char c = getHexValue(remainders[i]);
*(hexString + (j++)) = c;
}
}
char *hexString 是指向我需要输出到屏幕(最终)的字符串的指针。我需要转换为十六进制的 char inputChar 参数(这就是为什么我永远不需要转换超过 256 的值)。
如果有更好的方法来做到这一点,仍然使用 void asciiToHexadecimal(char inputChar, char *hexString) 函数,我洗耳恭听,除此之外,我的调试似乎表明这些值是好的,但输出结果类似于 \377
,而不是预期的十六进制字母数字表示形式。
抱歉,如果问题本身(或代码)有任何术语或其他问题,我对 C 的世界仍然很陌生。
更新: 我只是想到,可能与发布我显示值的方式有关,以防其打印,而不是错误的转换。如下:(
char* binaryString = (char*) malloc(8);
char* hexString = (char*) malloc(2);
asciiToBinary(*(asciiString + i), binaryString);
asciiToHexadecimal(*(asciiString + i), hexString);
printf("%6c%13s%9s\n", *(asciiString + i), binaryString, hexString);
除了 hexString
之外,此代码片段中的所有内容都有效)
n.b. I know that this question has been asked on StackOverflow before in a variety of different ways and circumstances, but the search for the answer I seek doesn't quite help my specific case. So while this initially looks like a duplicate of a question such as How can I convert an integer to a hexadecimal string in C? the answers given, are accurate, but not useful to me.
My question is how to convert a decimal integer, into a hexadecimal string, manually. I know there are some beat tricks with stdlib.h and printf, but this is a college task, and I need to do it manually (professor's orders). We are however, permitted to seek help.
Using the good old "divide by 16 and converting the remainder to hex and reverse the values" method of obtaining the hex string, but there must be a big bug in my code as it is not giving me back, for example "BC" for the decimal value "188".
It is assumed that the algorithm will NEVER need to find hex values for decimals larger than 256 (or FF). While the passing of parameters may not be optimal or desirable, it's what we've been told to use (although I am allowed to modify the getHexValue function, since I wrote that one myself).
This is what I have so far:
/* Function to get the hex character for a decimal (value) between
* 0 and 16. Invalid values are returned as -1.
*/
char getHexValue(int value)
{
if (value < 0) return -1;
if (value > 16) return -1;
if (value <= 9) return (char)value;
value -= 10;
return (char)('A' + value);
}
/* Function asciiToHexadecimal() converts a given character (inputChar) to
* its hexadecimal (base 16) equivalent, stored as a string of
* hexadecimal digits in hexString. This function will be used in menu
* option 1.
*/
void asciiToHexadecimal(char inputChar, char *hexString)
{
int i = 0;
int remainders[2];
int result = (int)inputChar;
while (result) {
remainders[i++] = result % 16;
result /= (int)16;
}
int j = 0;
for (i = 2; i >= 0; --i) {
char c = getHexValue(remainders[i]);
*(hexString + (j++)) = c;
}
}
The char *hexString
is the pointer to the string of characters which I need to output to the screen (eventually). The char inputChar
parameter that I need to convert to hex (which is why I never need to convert values over 256).
If there is a better way to do this, which still uses the void asciiToHexadecimal(char inputChar, char *hexString)
function, I am all ears, other than that, my debugging seems to indicate the values are ok, but the output comes out like \377
instead of the expected hexadecimal alphanumeric representation.
Sorry if there are any terminology or other problems with the question itself (or with the code), I am still very new to the world of C.
Update:
It just occurred to me that it might be relevant to post the way I am displaying the value in case its the printing, and not the conversion which is faulty. Here it is:
char* binaryString = (char*) malloc(8);
char* hexString = (char*) malloc(2);
asciiToBinary(*(asciiString + i), binaryString);
asciiToHexadecimal(*(asciiString + i), hexString);
printf("%6c%13s%9s\n", *(asciiString + i), binaryString, hexString);
(Everything in this code snip-pit works except for hexString
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可能希望为您感兴趣的每个值打印出调用此例程所获得的字符。:)(
printf(3)
格式%c
。)如果您使用 0 到 9 之间的数字调用
getHexValue()
,则在 ASCII 控制字符范围。当您使用 10 到 15 之间的数字调用getHexValue()
时,您将返回 65 到 75 之间的 ASCII 字母范围内的数字。讲道?如果您编写以下测试,单元测试可以为您节省几个小时的时间在你编写代码的同时。
有些人喜欢先编写测试。虽然我从来没有长期坚持这种方法的纪律,但知道您必须编写测试将迫使您编写更容易测试的代码。更容易测试的代码是较少耦合(或“更加解耦”) ,这通常会导致更少的错误!
尽早并经常编写测试。 :)
更新:在包含输出代码后,我也必须对此发表评论:)
hexString
分配的一个字节太小,无法成为 C 字符串 - 您忘记为 ASCII NUL'\0'
字符留出空间。如果您通过%c
格式说明符打印hexString
,或者使用memcpy(3)
构建更大的字符串,可能没问题,但您的 printf() 调用将 hexString 视为字符串。一般来说,当你看到一个
调用时,要害怕 - C 习惯用法是
+1
是你向其他人(以及两个月后的你自己)发出的信号,表明你已经为 NUL 留出了空间。如果您在另一个计算中隐藏该+1
,那么您就错过了记住每次阅读代码时都可以捕获这些错误的模式的机会。 (老实说,两天前我就通过这个确切的模式在SO上找到了其中一个。:)You might wish to print out the characters you get from calling this routine for every value you're interested in. :) (
printf(3)
format%c
.)When you call
getHexValue()
with a number between 0 and 9, you return a number between 0 and 9, in the ASCII control-character range. When you callgetHexValue()
with a number between 10 and 15, you return a number between 65 and 75, in the ASCII letter range.The sermon? Unit testing can save you hours of time if you write the tests about the same time you write the code.
Some people love writing the tests first. While I've never had the discipline to stick to this approach for long, knowing that you have to write tests will force you to write code that is easier to test. And code that is easier to test is less coupled (or 'more decoupled'), which usually leads to fewer bugs!
Write tests early and often. :)
Update: After you included your output code, I had to comment on this too :)
hexString
has been allocated one byte too small to be a C-string -- you forgot to leave room for the ASCII NUL'\0'
character. If you were printinghexString
by the%c
format specifier, or building a larger string by usingmemcpy(3)
, it might be fine, but yourprintf()
call is treatinghexString
as a string.In general, when you see a
call, be afraid -- the C idiom is
That
+1
is your signal to others (and yourself, in two months) that you've left space for the NUL. If you hide that+1
in another calculation, you're missing an opportunity to memorize a pattern that can catch these bugs every time you read code. (Honestly, I found one of these through this exact pattern on SO just two days ago. :)目标是纯十六进制的,还是函数应可参数化。如果它被限制为十六进制,为什么不利用一个十六进制数字恰好编码四位的事实呢?
我就是这样做的:
Is the target purely hexadecimal, or shall the function be parametizable. If it's constrained to hex, why not exploit the fact, that a single hex digit encodes exactly four bits?
This is how I'd do it:
我制作了一个库来进行十六进制/十进制转换,而不使用
stdio.h
。使用非常简单:这将使用
calloc()
返回一个指向十六进制字符串的指针,这样可以优化内存使用量,所以不要忘记使用free( )
这里是github上的链接:https://github.com/kevmuret/libhex/
I made a librairy to make Hexadecimal / Decimal conversion without the use of
stdio.h
. Very simple to use :This will use
calloc()
to to return a pointer to an hexadecimal string, this way the quantity of memory used is optimized, so don't forget to usefree()
Here the link on github : https://github.com/kevmuret/libhex/
您已经非常接近了 - 进行以下两个小更改,它将运行良好,足以让您完成它:
(1) 将:更改
为:(
您需要转换 0..9值到一个字符,而不仅仅是转换它)。
(2) 将:更改
为:
(inputChar 被视为有符号,这会导致
%
产生不良结果)。一些提示:
对于无效输入,让 getHexValue 返回
'?'
而不是-1
(使调试更容易)编写用于调试的测试工具,例如
You're very close - make the following two small changes and it will be working well enough for you to finish it off:
(1) change:
to:
(you need to convert the 0..9 value to a char, not just cast it).
(2) change:
to:
(inputChar was being treated as signed, which gave undesirable results with
%
).A couple of tips:
have getHexValue return
'?'
rather than-1
for invalid input (make debugging easier)write a test harness for debugging, e.g.
作为对其他好的答案的补充......
如果这些十六进制或十进制字符串表示的数字很大(例如数百位数字),它们将不适合
long long
(或其他任何形式)您的 C 实现提供的最大整数类型)。然后你需要bignums。我建议不要编写自己的实现(制作一个高效的实现是很棘手的),而是使用现有的实现,例如 GMPlibIn complement of the other good answers....
If the numbers represented by these hexadecimal or decimal character strings are huge (e.g. hundreds of digits), they won't fit in a
long long
(or whatever largest integral type your C implementation is providing). Then you'll need bignums. I would suggest not coding your own implementation (it is tricky to make an efficient one), but use an existing one like GMPlib