在我的C ++代码中经常使用以下类型的辅助函数:
static inline std::string stringf(const char *fmt, ...)
{
std::string ret;
// Deal with varargs
va_list args;
va_start(args, fmt);
// Resize our string based on the arguments
ret.resize(vsnprintf(0, 0, fmt, args));
// End the varargs and restart because vsnprintf mucked up our args
va_end(args);
va_start(args, fmt);
// Fill the string
if(!ret.empty())
{
vsnprintf(&ret.front(), ret.size() + 1, fmt, args);
}
// End of variadic section
va_end(args);
// Return the string
return ret;
}
它有一些好处:
现在,我遇到了一些问题:
有人知道更好的方法吗?
答案 0 :(得分:5)
你结婚了(双关语)std::sprintf()
?如果您正在使用C ++和现代std::string
,为什么不充分利用新的语言功能并使用可变参数模板来执行返回sprintf
的类型安全std::string
?
看看这个非常好看的实现:https://github.com/c42f/tinyformat。我想这可以解决你所有的问题。
答案 1 :(得分:3)
当您添加标记c++11
时,我认为您可以使用它。然后,您可以将代码简化为:
namespace fmt {
template< class ...Args >
std::string sprintf( const char * f, Args && ...args ) {
int size = snprintf( nullptr, 0, f, args... );
std::string res;
res.resize( size );
snprintf( & res[ 0 ], size + 1, f, args... );
return res;
}
}
int main() {
cout << fmt::sprintf( "%s %d %.1f\n", "Hello", 42, 33.22 );
return 0;
}
答案 2 :(得分:1)
不要使用大小为0的第一个$ ./bin/getline_rdfile dat/damages.txt
Lines in file:
array [ 0] Personal injury damage awards are unliquidated
array [ 1] and are not capable of certain measurement; thus, the
array [ 2] jury has broad discretion in assessing the amount of
array [ 3] damages in a personal injury case. Yet, at the same
array [ 4] time, a factual sufficiency review insures that the
array [ 5] evidence supports the jury's award; and, although
array [ 6] difficult, the law requires appellate courts to conduct
array [ 7] factual sufficiency reviews on damage awards in
array [ 8] personal injury cases. Thus, while a jury has latitude in
array [ 9] assessing intangible damages in personal injury cases,
array [ 10] a jury's damage award does not escape the scrutiny of
array [ 11] appellate review.
array [ 12]
array [ 13] Because Texas law applies no physical manifestation
array [ 14] rule to restrict wrongful death recoveries, a
array [ 15] trial court in a death case is prudent when it chooses
array [ 16] to submit the issues of mental anguish and loss of
array [ 17] society and companionship. While there is a
array [ 18] presumption of mental anguish for the wrongful death
array [ 19] beneficiary, the Texas Supreme Court has not indicated
array [ 20] that reviewing courts should presume that the mental
array [ 21] anguish is sufficient to support a large award. Testimony
array [ 22] that proves the beneficiary suffered severe mental
array [ 23] anguish or severe grief should be a significant and
array [ 24] sometimes determining factor in a factual sufficiency
array [ 25] analysis of large non-pecuniary damage awards.
。而是使用具有一些可能大小的堆栈缓冲区(例如64到4096之间的东西),如果适合,则将其复制到返回值中。
您对$ valgrind ./bin/getline_rdfile dat/damages.txt
==14321== Memcheck, a memory error detector
==14321== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==14321== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==14321== Command: ./bin/getline_rdfile dat/damages.txt
==14321==
Lines in file:
array [ 0] Personal injury damage awards are unliquidated
<snip>
...
array [ 25] analysis of large non-pecuniary damage awards.
==14321==
==14321== HEAP SUMMARY:
==14321== in use at exit: 0 bytes in 0 blocks
==14321== total heap usage: 29 allocs, 29 frees, 3,997 bytes allocated
==14321==
==14321== All heap blocks were freed -- no leaks are possible
==14321==
==14321== For counts of detected and suppressed errors, rerun with: -v
==14321== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
邻居的担忧是错误的。它是明确的,完全可以依赖。
最后 - 我想回顾一下编译时格式检查库会更好。你需要C ++ 14才能获得全部功能,但是C ++ 11支持足够多,你应该能够vsnprintf
一些头代码而不会丢失任何表达。请记住考虑std::string
!