2011-04-16 20 views
15

std :: dizesi oluştururken hızlı, kolay biçimlendirme yapmanın hızlı ve kolay bir yolu var mı? Bir şey gibi ...Hızlı biçimlendirilmiş dizeler C++ içinde

std::string foo("A number (%d) and a character (%c).\n", 18, 'a'); 
+0

Çözümüme bir göz atın. Bu C++ Stil çözümü. Destekleme gibi "% d" ve "% c" içeren C stili biçim dizgisine bağlı değildir. – Nawaz

cevap

15

dize ait yapıcı yerleşik değil ama boost format kontrol etmek isteyebilirsiniz. Onun daha kibar bir sprintf stili dize biçimlendirme. Bununla beraber, en azından bunu yapabilirsiniz:

std::string foo = 
    boost::str(boost::format("A number (%d) and a character (%c)\n") % 18 % 'a'); 
+0

Bu mükemmel, teşekkürler! – slezica

+0

Bir 'uint8_t' yerine literal '18' - yerleştirin ve Boost çıktınız tamamen bozulur: karakterle sayı yerine iki karakter alırsınız. –

10

Ben kullanabileceğiniz bir stringbuilder sınıfı yazdık ve ben bunun aksine olarak daha iyi boost::format olduğunu düşünüyorum, stringbuilder%d gibi C tarzı biçim dizesi kullanmak ETMEZ , %c. vb

İşte

stringbuilder sadece bir satırda size nasıl yardımcı olabileceğini geçerli: http://ideone.com/J9ALB


: ideone de

struct stringbuilder 
{ 
    std::stringstream ss; 
    template<typename T> 
    stringbuilder & operator << (const T &data) 
    { 
     ss << data; 
     return *this; 
    } 
    operator std::string() { return ss.str(); } 
}; 

Demo:

stringbuilder uygulanması çok basit
std::string s=stringbuilder() << "A number " << 18 <<" and a character " <<'a'; 

olduğunu

Kısa bir süre önce aşağıdaki blogu yazdım g stringbuilder kullanımının birçok farklı yolu.

+7

+1 Paylaşım için teşekkürler :) ama C tarzı biçimlendirme sözdizimini daha çok beğeniyorum. Ben şahsen bu parçayı parça parça bir araya getirerek daha rahat biçimlendirmek için "bu benim dizgim, uygun belirteçleri değiştirme" yaklaşımını buluyorum. – slezica

+0

@Santiago: Fakat C-Stil formatlarının güvenli olmadığını biliyorsunuz, bu yüzden C++ onları kullanmıyor ve bunun yerine “cout” ve “cin” ve diğer güvenli sınıflar ile geliyordu. – Nawaz

+4

@Nawaz: Ayrıca, printf gibi biçimlendirilmiş ve iostream kadar güvenli olan boost :: formatının geliştirilmesinin nedeni de budur. –

1

Bu nasıl bu Printf doğrudan kullanır:

std::string foo(fmt::sprintf("A number (%d) and a character (%c).\n", 18, 'a')); 

Bu:

#include <stdio.h> 
#include <stdarg.h> 

std::string format(const char *fmt, ...) 
{ 
    va_list ap; 
    va_start(ap, fmt); 

    const size_t SIZE = 512; 
    char buffer[SIZE] = { 0 }; 
    vsnprintf(buffer, SIZE, fmt, ap); 

    va_end(ap); 

    return std::string(buffer); 
} 
+0

512 karakterde kesmek yerine, sağ boyutlu bir arabellek ayırmak için 'vsnprintf' dönüş değerine bakmak daha iyidir. Ya da Linux'ta ['asprintf'] (http://linux.die.net/man/3/vasprintf) kullanın. Ayrıca, [gcc stili işlev öznitelikleri] 'ni (http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html) kullanın, böylece argümanlarda hala bir tür güvenlik elde edersiniz. – poolie

7

C++ Format library bir dize döndürür güvenli bir sprintf uygulamasını sağlar kütüphane de P destekler ython en str.format sözdizimi:

std::string foo(fmt::format("A number ({}) and a character ({}).\n", 18, 'a')); 

O Biçim Artıracak amaç benzer ancak, oldukça küçük much faster ve standart C++ kitaplığı dışında dış bağımlılıkları yoktur.

Yasal Uyarı: Bu kütüphanenin yazarıyım.

İlgili konular