目标:使用单一格式说明符打印变量字节数。
环境:在x86-64主机上运行于VM中的 x86-64 Ubuntu20.04.3LTS。
示例:
让%kmagic成为我正在寻找的格式说明符,通过从堆栈中弹出它们并将它们添加到输出中来打印k字节。然后,对于指向内存中保存字节的区域的%rsp,我希望printf("Next 4 bytes on the stack: %4magic")打印Next 4 bytes on the stack: deadbeef。
到目前为止我尝试过的:
不幸的是,
%khhx,只会导致k-1空白,后面跟着两个十六进制字符( data).%kx,的一个字节,我希望它会打印k/2字节,解释为一个数字)。这只会打印8个十六进制字符(4个字节),加上k-8空格。打印的非空白字符数量与格式说明符的长度相匹配,即%hhx的预期长度为2,这也是打印的非空白字符的数量。%x的情况也是如此,预计它将打印8个字符。
问题:是否有可能得到所需的行为?如果是这样的话,是怎么做的?
发布于 2021-11-27 12:01:46
是否有可能得到所需的行为?如果是这样的话,是怎么做的?
不存在printf格式说明符来做您想做的事情。
是可能的吗
编写支持所需内容的自己的printf实现。使用implementation-specific tools创建您自己的printf格式说明符。你可以从linux kernel printk %*phN format speciifer那里得到灵感。
发布于 2021-11-27 12:33:29
不可能使用标准printf。您需要编写自己的函数并自定义printf函数。
http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html
示例(简单转储):
int printdump (FILE *stream, const struct printf_info *info, const void *const *args)
{
const unsigned char *ptr = *(const unsigned char **)args[0];
size_t size = *(size_t*)args[1];
for(size_t i = 1; i <= size; i++)
{
fprintf(stream, "%02X%c", ptr[i-1], i % 8 ? ' ' : '\n');
}
return 1;
}
int printdumpargs (const struct printf_info *info, size_t n, int *argtypes)
{
if (n == 2)
argtypes[0] = PA_POINTER;
argtypes[1] = PA_INT;
return 2;
}
int main(void)
{
double x[4] = {456543645.6786e45, 456543654, 1e345, -345.56e67};
register_printf_function ('Y', printdump, printdumpargs);
printf("%Y\n", &x, sizeof(x));
}据我所见,现在它已经贬值了(可能没有人使用它)。
https://godbolt.org/z/qKs6e1d9q
输出:
30 18 CB 5A EF 10 13 4B
00 00 00 A6 4D 36 BB 41
00 00 00 00 00 00 F0 7F
C4 5D ED 48 9C 05 60 CE发布于 2021-11-27 13:55:28
您没有标准的转换说明符,但是您可以使用辅助函数和动态数组在C99中实现您的目标:
#include <stdio.h>
char *dump_bytes(char *buf, const void *p, size_t count) {
const unsigned char *src = p;
char *dest = buf;
while (count --> 0) {
dest += sprintf(dest, "%.2X", *src++);
if (count)
*dest++ = ' ';
}
*dest = '\0'; // return an empty sting for an empty memory chunk
return buf;
}
int main() {
long n = 0x12345;
printf("n is at address %p with contents: %s\n",
(void *)&n,
dump_bytes((char[3 * sizeof(n)]){""}, &n, sizeof(n)));
return 0;
}输出:n is at address 0x7fff523f57d8 with contents: 45 23 01 00 00 00 00 00
您可以使用宏进行更简单的调用:
#define DUMPBYTES(p, n) dump_bytes((char[3 * (n)]){""}, p, n)
int main() {
char *p = malloc(5);
printf("allocated 5 bytes at address %p with contents: %s\n",
p, DUMPBYTES(p, 5));
free(p);
return 0;
}https://stackoverflow.com/questions/70134527
复制相似问题