C++

2008-10-22 8 views
30

'da belirtilen uzunluktaki bir dizgiye bir sayı dönüştürüyorum Bazı farklı uzunluklarda (1, 999, 76492 vb.) Var ve bunları ortak bir uzunluğa sahip dizelere dönüştürmek istiyorum (örneğin, uzunluk 6, sonra bu dizeler şöyle olacaktır: '000001', '000999', '076492'). Başka bir deyişle, numaraya doğru miktarda sıfır sayıda sıfır eklemem gerekir.C++

int n = 999; 
string str = some_function(n,6); 
//str = '000999' 

C++ 'da böyle bir işlev var mı?

+12

Aşağıdakilerden bazı örnekler hakkında: http://www.codeproject.com/KB/recipes/Tokenizer.aspx Çok verimli ve biraz zarifler. –

cevap

44

veya kullanan stringstreams bakın. Ayrıca, bu kodu diğer çıkış akışlarında da eşit olarak kullanabilirsiniz.

+7

buf' sstream 've' iomanip' dosyalarını içerir. – Gareth

+1

Ve "stringstream", "setw" ve "setfill" (ayrıca "string") de "std" ad alanı içinde. – rafalcieslak

2

Bunu yapmanın birçok yolu vardır. En basit olacaktır:

int n = 999; 
char buffer[256]; sprintf(buffer, "%06d", n); 
string str(buffer); 
+0

Tüm dolu sprintf! Bu durumda –

+0

'u kullanmak isteyebilirsiniz: sprintf (buffer, "% 06d", n); not Eğer sıfır –

+0

büyüklüğü 256 A tampon ile PADD gereken 6 önünde 0 bu amaçla _way_ overkill. Sayı, 7 karaktere sahip olsa da (Isak'ın cevabı snprintf kullanarak), yine de bildiğim hiçbir şey 256 karaktere sahip değil. : -P –

1

sprintf da C++ çalıştığı, bunu yapmanın C benzeri bir yoldur.

C++ 'da, stringstream ve stream çıkış formatlarının bir kombinasyonu (bkz. http://www.arachnoid.com/cpptutor/student3.html) işi yapar. Daha iostreams tipi güvenlikli yolu gibi çünkü ben arachnoid.com bulunan bilgileri derlenmiş

#include <sstream> 
#include <iomanip> 

std::stringstream ss; 
ss << std::setw(10) << std::setfill('0') << i; 
std::string s = ss.str(); 

:

9
char str[7]; 
snprintf (buf, 7, "%06d", n); 

snprintf

+0

Her zaman snprintf() öğesini kullanmak iyi bir uygulama olsa da, bu, sprintf() işlevini güvenle kullanabileceğiniz birkaç yerden biridir. –

+0

Evet biliyorum. Ama ben her zaman snprintf kullanmaya eğilimliyim çünkü gerçekte hiçbir sebep yok (performans farkı ihmal edilebilir). –

+4

arg # 2 bir size_t, bir len değil, yani 7, 6 değil. Bu gerektirir - Bir şeyler kaçırıyorum, ama aynı zamanda biçim dizesinde türünü gerektiğini düşünüyorum, bu yüzden "% 06D" veya snprintf benzer –

3

Bu yöntem, akışları ve sprintf kullanmaz. Kilitleme problemleri dışında, akışlar bir performans yüküne maruz kalır ve gerçekten aşırı bir sıkıntıdır. Akarsular için tepegöz, buhar ve akış tamponu oluşturma ihtiyacından gelmektedir. Sprintf için, ek yükü format dizesini yorumlamaya gerek kalmadan geliyor. Bu, n negatif olduğunda veya n dize gösterimi len'dan daha uzun olduğunda bile çalışır. Bu en kötü çözümdür. Eğer farkında olmak isteyebilirsiniz

inline string some_function(int n, int len) 
{ 
    string result(len--, '0'); 
    for (int val=(n<0)?-n:n; len>=0&&val!=0; --len,val/=10) 
     result[len]='0'+val%10; 
    if (len>=0&&n<0) result[0]='-'; 
    return result; 
} 
8

Bir şey stringstream yaklaşımı kullandığınızda devam edebilir olası kilitleme olduğunu. Visual Studio 2008 ile birlikte gelen STL'de, en azından biçimlendirme sırasında çeşitli yerel bilgiler kullanıldığında çıkarılmış ve serbest bırakılmış birçok kilit vardır. Aynı anda kaç tane iş parçacığına sahip olduğunuza bağlı olarak bir sorun olabilir veya sayıları dizelere dönüştürür ...

sprintf sürümü herhangi bir kilit almaz (en azından kilitle Şu anda geliştirdiğim izleme aracı ...) ve benzer durumlarda kullanım için 'daha iyi' olabilir.

Bunu fark ettim çünkü aracım son zamanlarda 'locale' kilitlerini sunucu sistemimde kilitler için en çok öne çıkarıyor; Bir sürpriz olarak geldi ve benim aldığım yaklaşımı gözden geçirmeme sebep olabilir (yani stringstream'dan sprintf'a doğru geri dönün) ...

+0

Yerel ayarın kullanıldığını, ancak gerçekten de kilitli olduğunu anlamış ... Değerli bilgi! – xtofl

+0

Sadece bunu yapan Visual Studio STL'leri olabilir, STLPort ile oluşturulmuş bir test programını kontrol etmedim. Ayrıca neden kilitlendiğini görmek için araştırılmamıştım. –

+0

STLPort 5.1.5 Bu çapraz iplik çekişme sorunu gösteren, ancak dönüşüm sprintf stili 3 kat daha hızlı etrafında hala ... İşte –