在没有 sprintf 或 C 库函数的情况下将 void* 转换为 C 样式字符串

Aru*_*pur 1 c string winapi pointers

我正在使用 msvc 编译一个程序/NODEFAULTLIB,所以我不能使用任何 C 库函数。如何创建一个 C 风格的字符串 ( char*),其中包含一个指针 ( void*)的十六进制表示,例如printf("%p\r\n", voidPointer)产生,以便我可以使用 将其写入控制台WriteConsoleW

WriteConsoleW只接收一个指向包含要输出的字符串的缓冲区的指针,以及字符串中的字符数。如何在不使用 C 运行时库函数(如 sprintf)的情况下转换它?但是,我可以使用WinAPI函数,lstrlenW例如 。

Rem*_*eau 7

既然您说可以使用 Win32 API,那么请查看该 API 提供的多个字符串格式化函数:

#include <windows.h>

WCHAR buf[25];
int len = wsprintfW(buf, L"%p\r\n", voidPointer);
DWORD written;
WriteConsole(hConsole, buf, len, &written, NULL);
Run Code Online (Sandbox Code Playgroud)
#include <windows.h>
#include <strsafe.h>

WCHAR buf[25];
StringCbPrintfW(buf, sizeof(buf), L"%p\r\n", voidPointer);
DWORD written;
WriteConsole(hConsole, buf, lstrlenW(buf), &written, NULL);
Run Code Online (Sandbox Code Playgroud)
#include <windows.h>
#include <strsafe.h>

WCHAR buf[25], *end;
StringCbPrintfExW(buf, sizeof(buf), &end, NULL, 0, L"%p\r\n", voidPointer);
DWORD written;
WriteConsole(hConsole, buf, end-buf, &written, NULL);
Run Code Online (Sandbox Code Playgroud)
#include <windows.h>
#include <strsafe.h>

WCHAR buf[25];
StringCchPrintfW(buf, sizeof(buf)/sizeof(WCHAR), L"%p\r\n", voidPointer);
DWORD written;
WriteConsole(hConsole, buf, lstrlenW(buf), &written, NULL);
Run Code Online (Sandbox Code Playgroud)


Dav*_*rtz 6

#include <stdio.h>
#include <stdint.h>

void hexDump(void *ptr, char *buf)
{
    static char hex[16] = {
        '0', '1', '2', '3', '4',
        '5', '6', '7', '8', '9',
        'A', 'B', 'C', 'D', 'E', 'F' };
    *buf++ = '0';
    *buf++ = 'x';

    uintptr_t ip = (uintptr_t) ptr;
    for (int nibble = (2 * sizeof(ptr) - 1); nibble >= 0; --nibble)
        *buf++=hex[(ip >> (4 * nibble)) & 0xf];

    *buf = 0;
    return;        
}

int main()
{
    void *ptr = (void *) 0x1234abcd567890ef;
    char buf[20];
    hexDump(ptr, buf);
    printf("\"%s\"\n", buf);
}
Run Code Online (Sandbox Code Playgroud)

输出:

“0x1234ABCD567890EF”

以下是我可能会真正编写内部代码的方式:

    // To extract the first nibble, we shift right 4 bits less
    // than the size of the pointer. Each subsequent nibble requires
    // Shifting four fewer bits. The last output requires no shift
    for (int shift = sizeof(ptr) * 8 - 4; shift >= 0; shift -= 4)
        *buf++ = hex[(((uintptr_t) ptr) >> shift) & 0xf];
Run Code Online (Sandbox Code Playgroud)

  • +1,但我认为`char buf[16]`对于x64至少应该是`char buf[19]`或者对于x86`char buf[11]`,并且for循环中的`nibble &gt; 1`应该是`nibble &gt;= 0`。 (2认同)