26 ŞUBAT 2010, Cuma
::std sprintf gibi dize biçimlendirme
sprintf
std::string
biçimine ve dosya akışı göndermek zorundayım. Bunu nasıl yapabilirim?
CEVAP
11 Kasım 2011, Cuma
#include <stdarg.h> // For va_start, etc.
std::string string_format(const std::string fmt, ...) {
int size = ((int)fmt.size()) * 2 50; // Use a rubric appropriate for your code
std::string str;
va_list ap;
while (1) { // Maximum two passes on a POSIX system...
str.resize(size);
va_start(ap, fmt);
int n = vsnprintf((char *)str.data(), size, fmt.c_str(), ap);
va_end(ap);
if (n > -1 && n < size) { // Everything worked
str.resize(n);
return str;
}
if (n > -1) // Needed size returned
size = n 1; // For null char
else
size *= 2; // Guess at a larger size (OS specific)
}
return str;
}
Daha güvenli ve daha verimli (test ettim, ve daha hızlı) bir yaklaşım
#include <stdarg.h> // For va_start, etc.
#include <memory> // For std::unique_ptr
std::string string_format(const std::string fmt_str, ...) {
int final_n, n = ((int)fmt_str.size()) * 2; /* Reserve two times as much as the length of the fmt_str */
std::string str;
std::unique_ptr<char[]> formatted;
va_list ap;
while(1) {
formatted.reset(new char[n]); /* Wrap the plain char array into the unique_ptr */
strcpy(&formatted[0], fmt_str.c_str());
va_start(ap, fmt_str);
final_n = vsnprintf(&formatted[0], n, fmt_str.c_str(), ap);
va_end(ap);
if (final_n < 0 || final_n >= n)
n = abs(final_n - n 1);
else
break;
}
return std::string(formatted.get());
}
Bu fmt_str va_start gereklerine uygun değer geçirilir.
NOT: daha güvenli ve daha hızlı sürümü bazı sistemlerde çalışmıyor. Dolayısıyla her ikisi de hala listelenmiştir. Ayrıca," tamamen preallocation adım doğru olmasına bağlıdır, aksi takdirde strcpy daha yavaş işler. "daha hızlı
Bunu Paylaş:
C# neden Dize değeri bir tür gibi davr...
Kasa GİBİ bir ifade kullanmak için, SQ...
Nasıl özel bir dize ile numaralama bağ...
Bir dize biçimlendirme zaman aynı değe...
Dize biçimlendirme parametreleri adınd...