首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用printf格式字符串打印可变字节数

用printf格式字符串打印可变字节数
EN

Stack Overflow用户
提问于 2021-11-27 11:52:29
回答 3查看 717关注 0票数 2

目标:使用单一格式说明符打印变量字节数。

环境:在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

到目前为止我尝试过的:

不幸的是,

  1. %khhx,只会导致k-1空白,后面跟着两个十六进制字符( data).
  2. %kx,的一个字节,我希望它会打印k/2字节,解释为一个数字)。这只会打印8个十六进制字符(4个字节),加上k-8空格。

打印的非空白字符数量与格式说明符的长度相匹配,即%hhx的预期长度为2,这也是打印的非空白字符的数量。%x的情况也是如此,预计它将打印8个字符。

问题:是否有可能得到所需的行为?如果是这样的话,是怎么做的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-11-27 12:01:46

是否有可能得到所需的行为?如果是这样的话,是怎么做的?

不存在printf格式说明符来做您想做的事情。

可能的

编写支持所需内容的自己的printf实现。使用implementation-specific tools创建您自己的printf格式说明符。你可以从linux kernel printk %*phN format speciifer那里得到灵感。

票数 3
EN

Stack Overflow用户

发布于 2021-11-27 12:33:29

不可能使用标准printf。您需要编写自己的函数并自定义printf函数。

http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html

示例(简单转储):

代码语言:javascript
复制
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

输出:

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2021-11-27 13:55:28

您没有标准的转换说明符,但是您可以使用辅助函数和动态数组在C99中实现您的目标:

代码语言:javascript
复制
#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

您可以使用宏进行更简单的调用:

代码语言:javascript
复制
#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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70134527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档