C 编写自己的printf函数,尝试包含%p。

C 编写自己的printf函数,尝试包含%p。,c,printf,C,Printf,所以我正在编写自己的printf函数,所以我使用stdarg.h和系统调用write()。但我不知道如何在函数中输入错误的%p。%X会产生相同的结果吗 我已按此方式完成%x: 'x': x=va_arg(argp,argp, unsigned int); char *temp = convert(x,16); write(1, temp, lengthOFtemp); break; char *convert(unsigned int, int) { stati

所以我正在编写自己的printf函数,所以我使用stdarg.h和系统调用write()。但我不知道如何在函数中输入错误的%p。%X会产生相同的结果吗

我已按此方式完成%x:

'x': x=va_arg(argp,argp, unsigned int); 
     char *temp = convert(x,16);
     write(1, temp, lengthOFtemp);
     break;

char *convert(unsigned int, int)
{
static char buf[33];
char *ptr;

ptr=&buf[sizeof(buff)-1];
*ptr='\0';
do
{
*--ptr="0123456789abcdef"[num%base];
num/=base;
}while(num!=0);

return(ptr);
}

%p和%X之间的区别在于指针大小是特定于平台的-64位平台上为8字节,32位平台上为4字节。因此,必须使用“unsigned long”变量来处理来自va_args的指针参数,而不是“unsigned int”,它在某些64位平台上保留4个字节

否则是的,非常像上面的%X代码。

您可能需要使用

void * pv = va_arg(va, void*)
从可变参数列表中提取指针

要以这种方式安全地接收指针,变量函数的调用者(如上图所示进行拉取)需要将指针传递到
void*

然后进行整数转换,如下所示:

#include <inttypes.h>
...
uintptr_t uipv = (uintptr_t) pv;
与:


相关:您需要选择一个可以容纳指针的整数类型,并将指针强制转换为该类型。这本质上是不可移植的。在64位系统上,您可能必须使用
无符号长整型
%llX
或类似功能。在32位系统上,
无符号整型
%X
可以工作。如何检查系统是64位还是32位?@n.m.:对于支持
的系统,包括C99兼容系统和MSVC,您可以使用
uintptr\t
。这是可移植的。您的示例代码不可编译,甚至不接近。你有没有名字的参数,混合了
buf
buff
,还有越来越多的参数。谢谢。如何检查系统平台(X位),然后运行%p?无需检查,只需使用“unsigned long”。对于ILP32和LP64(32位和64位)系统,它将相应地调整大小;两者都能用吗?然后我只需要进行转换(p,16)?您必须确保使用va_arg从堆栈中读取正确的字节数。因此,如果参数为%X,则需要一个4字节的整数。如果参数是%p,则需要一个指针,正如我所解释的。因此,您需要为每种类型调用不同的va_arg。使用
intptr_t
uintptr_t
以可移植的方式将指向void(
void*
)的指针存储为整数值。
char buff[64] = {0};
char * pc = convert_uintptr(uipv, 16);
char * convert_uintptr(uintptr_t uipv, unsigned base);