2017-02-26 90 views
-1

如何仅使用write()函数将指针的地址写入标准输出。 (类似printf()函数中的%p标志。)C:在标准输出中写入指针的地址?

我不允许使用'write''malloc'和'free'以外的任何其他内容。

+1

*只有*写功能?你不能用'sprintf'来准备输出吗? – StoryTeller

+0

您是否尝试过使用'snprintf'?如果是的话,它是怎么回事?如果没有,请尝试!如果你不能使用它,那么你需要使用其他(可能是你自己的)函数将一个数字转换为一个字符串,但是原理是一样的。 – hyde

+0

我不允许使用'write''malloc'和'free'。 –

回答

2

如果你有一个像char *p;一个指针变量,那么你可以使用

write(filedescriptor, &p, sizeof(p)); 

写它就像真的写任何其他变量。

如果你想将它写成一个字符串,那么你需要先格式化为一个字符串,并写入字符串:作为一个字符串使用

char pstr[sizeof(p) * 2 + 2 + 1]; // Each byte of the pointer is two hexadecimal character, plus a potential 0x, plus terminator 
snprintf(pstr, sizeof(pstr), "%p", (void *) p); 
write(filedescriptor, pstr, strlen(pstr)); 

可以write,将指针视为一个正常的整数值,并循环指针变量中的所有字节,并使用模和分或移位来获取每个字节,然后使用字节掩码和移位来获取每个字节的每个半字节,并将其转换为字符来编写。如果您将指针值复制到一个字节数组中进行迭代,则可能会更容易,因为您不必执行模/分区,只需进行掩码和移位即可实现每个半字节。


随着中说,我真的很好奇,为什么会想这样的事情?由于无法将指针保存到文件中并在另一个程序中使用它(或者甚至是相同的程序,但作为新进程运行),因此无法通过管道或套接字将其发送到另一个进程。

+0

我想重新编码printf函数。 –

+3

'sizeof(p)* 2 + 1'可能没有足够的空间来存放由'%p'生成的指针值的文本表示。一个'0x'前缀经常出现,标准为执行架构留下了很大的空间来进行特定的选择。你应该声明一个更大的缓冲区并使用'snprintf'来避免潜在的缓冲区溢出。 – chqrlie

+0

@chqrlie你说得对,我应该从头开始使用'snprintf'。 –

2

如果您尝试重新编码printf,则可能需要执行%p。使用以下步骤:

  • 从参数va_list中检索指针的值。
  • 将该指针转换为uintptr_t或其他无符号整数类型适用于目标体系结构上的指针大小。
  • 将此整数转换为十六进制格式的字符串,其前缀为0x,与%#x格式相同。
  • 将结果字符串写入输出文件。
+0

'uintptr_t'是唯一保存指针值的类型。但是除了分配给/来自同一个'void *'(以及间接的其他指针类型)之外的任何事情都是特定于实现的。正如输出格式一样(他也可以将字节打印为字符)。 – Olaf