c++ - 通过定制的 printf 函数跨平台打印 64 位整数

标签 c++

有一个调试类,用于根据级别打印出调试语句。级别越高,您收到的消息越详细。当我尝试打印出 uint64_t 时出现问题。在使用 printf 样式的不同平台上,它可以是 %li 或 %lli。我希望它变得便携。然而,基于this ,我可以包括一个 PRId64,它会相应地调整。问题是因为我的消息是自定义的,它接受一个 const char *。我无法处理诸如 "Calling based on pts %"PRId64, mv.pts 之类的消息,因为它需要一个没有字符 * 的字符。解决这个问题的其他方法是什么?

主要代码内部

#include "debug.h"
#include <inttypes.h>    

#define P_DBG(level, format, ...) DBGPRINT(level, ("%-5d%s::%s() - " format "\n", __LINE__, str().c_str    (), __FUNCTION__, __VA_ARGS__))
#define P_ALL(format, ...) P_DBG(P_ALWAYS, format, __VA_ARGS__)
class Something 
{
    Something::Print(uint64_t a) {
        P_ALL("Calling based on %"PRId64 "\n", a)
}

内部调试.h

class vdebugPrint {
class vdebugPrint(int ID, int level) : v_id(ID), v_level(level) {}
int Print(const char* formatString, ...) __attribute__((__format(printf,2,3)));
}
...
#define VPRINT3(level, msg)    VdebugPrint(ID, level).Print msg
#define PRINT(level, msg)     VPRINT##level(level,msg)
#define DBGPRINT(level, msg)     PRINT(level,msg)
...

内部调试.cpp

...
VdebugPrint::Print(const char* format, ...)
{
    va_list argumentList;
    va_start(argumentList, formatString);
    vprintf(formatString, argumentList);
    va_end(argumentList);
}

准确的错误信息是

error: expected ‘)’ before ‘PRId64’
     AV_TRACE("Calling based on %"PRId64"\n", mv.pts);
                                  ^
/.../debug.h:140:94: note: in definition of macro ‘VPRINT3’
 #define VPRINT3(level, msg)      VdebugPrint(ID, level).DebugPrint msg

/.../debug.h:146:45: note: in expansion of macro ‘DBGPRINT’
 #define DBGPRINT(level, msg)            PRINT(level, msg)
                                         ^
/.../file.h:54:41: note: in expansion of macro ‘DBGPRINT’
#define P_PBD(level, format, args...)  DBGPRINT(level, ("%-5d%s::%s() - " format "\n", __LINE__, str().c_str(), __FUNCTION__, ##args))

编辑:

我试过 Olaf 的建议但没有成功。这是我所做的。除了主要代码外,其他一切都是一样的。

...
class Something
{
    Something::Print(uint64_t a) {
        const char* message = "Calling based on %";
        size_t mlen = strlen(message);
        char buf[mlen + strlen(PRId64) + 1];
        strcpy(buf, message);
        strcpy(buf + mlen, PRId64);

        P_ALL(buf, a);
    }
}

我得到的错误是

error: ‘PRId64’ was not declared in this scope
     char buf[mlen + strlen(PRId64) + 1];
                            ^

EDIT2:所以我解决了找不到 PRId64 的问题。我必须从 here 定义 __STDC_FORMAT_MACROS在包括 inttypes 之前。这现在解决了问题并且可以编译!

最佳答案

inttypes.h 中定义的宏是带有适当 printf 的字符串文字类型说明符。所以你必须将它附加到格式字符串。正常用法是使用字符串文字连接

如果您的格式字符串是可变的,您必须将说明符附加到字符串:

char buf[strlen[format] + strlen[PRId64] + 1];
strcpy(buff, format);
strcat(buff, PRId64);

请注意,这可以使用 strcpy 对两者进行优化:

size_t flen = strlen(format);
char buf[flen + strlen[PRId64] + 1];
strcpy(buff, format);
strcpy(buff + flen, PRId64);

注意:格式字符串必须以 NUL 结尾!

更新:

最初的答案是 C,因为它是语言标签之一,代码看起来更像 C 而不是 C++。然而,根据评论,如果你#define __STDC_FORMAT_MACROS,你也可以将它用于 C++11(检查你的编译器的支持)。 之前 #include <inttypes.h> . (请注意,include 可能会出现在其他 header 中,因此您应该尽早在文件中定义宏。)

关于c++ - 通过定制的 printf 函数跨平台打印 64 位整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30915767/

相关文章:

c++ - Fruchterman Reingold 的吸引力如何与 Boost Graph Library 一起工作

c++ - 海湾合作委员会,C++ : static string member variarible causes heap corruption/segmentation fault

c++ - 如何在 C++ 中对函数进行排序?

c++ - 代表模板类型的名称应该是单个字符吗?

c++ - 关于一般网络编程中的write buffer

c++ - 使用 GCC 程序集向左/向右旋转移动次数

c++ - C++中的动态二维数组,需要在每一行和整个数组中乘以偶数

c++ - 创建一个类来存储线程并调用它们

c++ - 使用 while 循环和 for 循环排序?

c++ - ADL 没有找到模板化的自由函数