我正在处理我自己的printf
代码,我遇到了2个问题,希望您能帮助我。
第一个是%p
选项:
此选项为我提供了十六进制形式的void*
的指针地址。
所以我正在做的是:
void printp(void *thing)
{
dectohex((long)&thing, 1);
}
其中dectohex
只是将decimal
转换为hex
的函数。
除最后3个字符外,结果始终是正确的。总是。例如:
me : 0x5903d8b8 , printf : 0x5903da28.
这些角色经常不会改变,而另一部分在每次通话时都会发生变化,就像它应该的那样。
我遇到的另一个问题是%O
选项。我无法将签名的int转换为unsigned int
。 printf
为negative int's
打印了大量数字,并且没有任何演员似乎有效,因为无论如何我都无法存储它。
编辑: 非常感谢你的答案,所以显然对于第一个问题我只是有点愚蠢。对于第二个问题,我将尝试您给我的不同解决方案,如果我设法做到这一点,请更新您。
再次非常感谢您的时间和耐心,并对我的回复延迟感到抱歉,我检查了电子邮件提醒以获得任何答案,但它显然不起作用。
REEDIT:在仔细阅读了我的第二个问题的答案之后,我想你们有些人认为我问过%o或%0。我真的在谈论%O,就像我认为的那样。在那个人告诉我"%O:long int参数被转换为无符号八进制"。我的问题是在将long int转换为八进制之前,我需要将它转换为无符号的东西。
答案 0 :(得分:3)
如果定义了uintptr_t/intmax_t
(它是可选的),将指针转换为该整数类型然后打印。
否则,如果sizeof(uintmax_t) >= sizeof (void *)
,请转换为uintmax_t
。 uintmax_t
是必需的类型,但可能不够大。
void printp(void *thing) {
uintptr_t j = (uintptr_t) thing;
char lst[(sizeof j * CHAR_BIT + 3)/ 4 + 1]; // Size needed to print in base 16
char *p = &lst[sizeof lst] - 1;
*p = '\0';
do {
p--;
*p = "0123456789ABCDEF"[j%16];
j /= 16;
} while (p > lst);
fputs(p, stdout);
}
%O
问题可能是签名延期问题。 (@mafso)确保使用的贵重物品是未签名的,例如unsigned
和unsigned long
。没有看到代码很难确定。
答案 1 :(得分:2)
关于你要做的第一个问题,只是为了确保你想打印东西的地址(注意事物本身就是一个指针)或事物origin
的地址(指向指针的指针)?
您当前正在打印指针指针。
更改
dectohex((long)&thing, 1);
到
dectohex((long)thing, 1);
如果是这样的话。
关于%O
问题,您能举一个代码示例吗?
答案 2 :(得分:1)
你的演员阵容需要“unsigned long long”。
指针是未签名的,但签名很长。
任何数据类型中的位数都取决于实现;但是现在长期和无符号长整数通常是32位。
编辑:为了更清楚,你不能指望C,C ++或Objective-C中的位数,它总是依赖于实现。例如,有一次共有九位字节和三十六位字。这就是为什么互联网协议总是指定“八位字节” - 八个一组的组 - 而不是“字节”。
这是Java的一个优点,因为每种数据类型中的位数都是严格确定的。
答案 3 :(得分:0)
关于零填充和负整数的第二个问题,这似乎与关于十六进制输出的第一个问题完全分开。你可以处理这样的负数(虽然在32位中它不能用值-2147483648,即0x80000000)。
#include <stdio.h>
#define MAXDIGITS 21
int printint(int value, int zeropad, int width)
{
int i, z, len = 0;
char strg [MAXDIGITS+1];
strg [MAXDIGITS] = 0;
if (value < 0) {
value = - value;
putchar ('-');
len = 1;
}
for (i=MAXDIGITS-1; i>=0; i--) {
strg [i] = '0' + value % 10;
if ((value /= 10) == 0)
break;
}
if (zeropad)
for (z=MAXDIGITS-i; z<width; z++) {
putchar ('0');
len++;
}
for (; i<MAXDIGITS; i++) {
putchar (strg [i]);
len++;
}
return len;
}
int main (int argc, char *argv[])
{
int num = 0, len;
if (argc > 1) {
sscanf (argv[1], "%d", &num);
// try the equivalent of printf("%4d, num);
len = printint (num, 0, 4);
printf (" length %d\n", len);
// try the equivalent of printf("%04d, num);
len = printint (num, 1, 4);
printf (" length %d\n", len);
}
return 0;
}