2008-10-22 10 views
30

Mam kilka liczb o różnej długości (np. 1, 999, 76492 itd.) I chcę przekonwertować je wszystkie na ciągi o wspólnej długości (na przykład, jeśli długość wynosi 6, wtedy te łańcuchy będą następujące: "000001", "000999", "076492").Konwertuj liczbę na łańcuch o określonej długości w C++

Innymi słowy, potrzebuję dodać prawidłową liczbę zer wiodących do liczby.

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

Czy istnieje taka funkcja w C++?

+12

Co z niektórymi przykładami z następujących: http://www.codeproject.com/KB/recipes/Tokenizer.aspx Są bardzo wydajne i nieco eleganckie. –

Odpowiedz

44

lub używając stringstreams:

#include <sstream> 
#include <iomanip> 

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

Skompilowałem informacje znalazłem na arachnoid.com bo lubię typu bezpieczny sposób iostreams więcej. Poza tym możesz w równym stopniu używać tego kodu w dowolnym innym strumieniu wyjściowym.

+7

FYI - to wymaga obejmuje pliki 'sstream' i' iomanip'. – Gareth

+1

Oraz 'stringstream',' setw' i 'setfill' (jak również' string') znajdują się w przestrzeni nazw 'std'. – rafalcieslak

2

Istnieje wiele sposobów na zrobienie tego. Najprostszy będzie:

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

All hail sprintf! –

+0

w tym przypadku możesz chcieć użyć: sprintf (bufor, "% 06d", n); zanotuj cyfrę 0 przed 6, które należy uzupełnić zerami –

+0

Bufor o rozmiarze 256 to overway w tym celu. Mimo że liczba może przepełnić 7 znaków (z którymi odpowiada odpowiedź Isaka, używając snprintf), to jednak żaden int, jaki znam, nie przyjmuje 256 znaków. :-P –

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

Zobacz snprintf

+0

Chociaż dobrą praktyką jest zawsze używać snprintf(), jest to jedno z niewielu miejsc, w których można bezpiecznie używać sprintf(). –

+0

Tak, wiem. Ale zawsze używam snprintf, ponieważ tak naprawdę nie ma powodu, aby tego nie robić (różnica w wydajności jest znikoma). –

+4

arg # 2 jest size_t, nie len, więc jest 7, nie 6. Lepsze wykorzystanie sizeof jednak. –

3

Ta metoda nie używa strumieni ani sprintf. Poza problemami z blokowaniem strumienie powodują wzrost wydajności i są naprawdę przesadą. W przypadku strumieni narzut wynika z potrzeby budowy bufora pary i strumienia. W przypadku sprintf narzut wynika z konieczności interpretacji ciągu formatów. Działa to nawet wtedy, gdy n ma wartość ujemną lub gdy reprezentacja ciągu n jest dłuższa niż len. To jest NAJNOWSZE rozwiązanie.

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

Jedną rzeczą, którą może chcą mieć świadomość jest potencjał blokujący, który może trwać podczas korzystania z podejścia stringstream. W STL, który jest dostarczany z Visual Studio 2008, jest przynajmniej wiele blokad wyjętych i zwolnionych, ponieważ podczas formatowania używane są różne informacje o lokalizacji. To może, czy nie może być problemem dla Ciebie w zależności od tego, ile masz wątków, które mogą być równocześnie konwersji liczb na łańcuchy ...

Wersja sprintf nie podejmuje żadnych blokad (przynajmniej zgodnie z zamkiem narzędzie do monitorowania, które rozwijam w tej chwili ...) i może być "lepsze" do użycia w sytuacjach współbieżnych.

Zauważyłem to tylko dlatego, że moje narzędzie ostatnio wypluło blokady "locale" jako jeden z najbardziej rywalizujących o blokady w moim systemie serwera; było to trochę zaskakujące i może spowodować zmianę podejścia, które stosuję (tj. cofnąć się w kierunku sprintf z stringstream) ...

+0

Ma sens, że używane jest ustawienie regionalne, ale w rzeczywistości jest ono zablokowane ... Wartościowe informacje! – xtofl

+0

Może to być tylko Visual Studio STL, które to zrobiłem, nie sprawdziłem z programem testowym zbudowanym przy pomocy STLPort. Nie zbadałem też, dlaczego jest zablokowany. –

+0

STLPort 5.1.5 nie wykazuje problemu z krzyżową nitką, ale konwersja sprintf jest wciąż około 3 razy szybsza ... –

Powiązane problemy