Jus*_* L. 94 c++ printf size-t
我有一些C++代码打印出size_t:
size_t a;
printf("%lu", a);
Run Code Online (Sandbox Code Playgroud)
我希望在32位和64位架构上编译时不会发出警告.
如果这是C99,我可以使用printf("%z", a);.但是AFAICT %z在任何标准C++方言中都不存在.所以相反,我必须这样做
printf("%lu", (unsigned long) a);
Run Code Online (Sandbox Code Playgroud)
这真的很难看.
如果没有size_t内置于该语言中的打印功能,我想知道是否可以编写一个printf包装器或类似的东西,这样可以在size_ts 上插入适当的强制转换,以便在保持好的编译器警告的同时消除虚假的编译器警告.
有任何想法吗?
Wil*_*ill 67
该printf格式说明%zu将正常工作在C++系统; 没有必要让它变得更复杂.
dal*_*lle 60
大多数编译器都有自己的说明符size_t和ptrdiff_t参数,例如Visual C++分别使用%Iu和%Id,我认为gcc允许你使用%zu和%zd.
你可以创建一个宏:
#if defined(_MSC_VER) || defined(__MINGW32__) //__MINGW32__ should goes before __GNUC__
#define JL_SIZE_T_SPECIFIER "%Iu"
#define JL_SSIZE_T_SPECIFIER "%Id"
#define JL_PTRDIFF_T_SPECIFIER "%Id"
#elif defined(__GNUC__)
#define JL_SIZE_T_SPECIFIER "%zu"
#define JL_SSIZE_T_SPECIFIER "%zd"
#define JL_PTRDIFF_T_SPECIFIER "%zd"
#else
// TODO figure out which to use.
#if NUMBITS == 32
#define JL_SIZE_T_SPECIFIER something_unsigned
#define JL_SSIZE_T_SPECIFIER something_signed
#define JL_PTRDIFF_T_SPECIFIER something_signed
#else
#define JL_SIZE_T_SPECIFIER something_bigger_unsigned
#define JL_SSIZE_T_SPECIFIER something_bigger_signed
#define JL_PTRDIFF_T_SPECIFIER something-bigger_signed
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
用法:
size_t a;
printf(JL_SIZE_T_SPECIFIER, a);
printf("The size of a is " JL_SIZE_T_SPECIFIER " bytes", a);
Run Code Online (Sandbox Code Playgroud)
Okt*_*ist 17
C++ 11
C++ 11导入C99所以std::printf应该支持C99 %zu格式说明符.
C++ 98
在大多数平台上,size_t并且uintptr_t是等效的,在这种情况下,您可以使用以下PRIuPTR定义的宏<cinttypes>:
size_t a = 42;
printf("If the answer is %" PRIuPTR " then what is the question?\n", a);
Run Code Online (Sandbox Code Playgroud)
如果你真的想要安全,请uintmax_t使用PRIuMAX:
printf("If the answer is %" PRIuMAX " then what is the question?\n", static_cast<uintmax_t>(a));
Run Code Online (Sandbox Code Playgroud)
mei*_*rsd 16
在Windows上和printf的Visual Studio实现
%Iu
Run Code Online (Sandbox Code Playgroud)
适合我.见 msdn
War*_*ung 10
既然你正在使用C++,为什么不使用IOStreams?这应该在没有警告的情况下进行编译并做出正确的类型感知事情,只要你没有使用没有定义operator <<for 的脑死亡的C++实现size_t.
当必须完成实际输出时printf(),您仍然可以将其与IOStream组合以获得类型安全行为:
size_t foo = bar;
ostringstream os;
os << foo;
printf("%s", os.str().c_str());
Run Code Online (Sandbox Code Playgroud)
它不是超级高效的,但上面你的情况是处理文件I/O,所以这是你的瓶颈,而不是这个字符串格式化代码.
fmt库提供了一种快速可移植(且安全)的实现,printf其中包含以下z修饰符size_t:
#include "fmt/printf.h"
size_t a = 42;
int main() {
fmt::printf("%zu", a);
}
Run Code Online (Sandbox Code Playgroud)
除此之外,它还支持类似 Python 的格式字符串语法并捕获类型信息,这样您就不必手动提供它:
fmt::print("{}", a);
Run Code Online (Sandbox Code Playgroud)
它已经过主要编译器的测试,并提供跨平台的一致输出。
免责声明:我是这个库的作者。
这是一个可能的解决方案,但它不是一个漂亮的..
template< class T >
struct GetPrintfID
{
static const char* id;
};
template< class T >
const char* GetPrintfID< T >::id = "%u";
template<>
struct GetPrintfID< unsigned long long > //or whatever the 64bit unsigned is called..
{
static const char* id;
};
const char* GetPrintfID< unsigned long long >::id = "%lu";
//should be repeated for any type size_t can ever have
printf( GetPrintfID< size_t >::id, sizeof( x ) );
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
70782 次 |
| 最近记录: |