C ++ ile int'i dizeye dönüştürmenin en kolay yolu


1574

C ++ ' intda eşdeğerine dönüştürmenin en kolay yolu nedir string. İki yöntemin farkındayım. Daha kolay bir yolu var mı?

(1)

int a = 10;
char *intStr = itoa(a);
string str = string(intStr);

(2)

int a = 10;
stringstream ss;
ss << a;
string str = ss.str();

4
Her iki yöntemin de iyi çözümler olduğunu düşünüyorum. nerede yapmanız gerektiği bağlama bağlıdır. Zaten akışlarla çalışıyorsanız, örneğin bir dosyayı okumak veya yazmak için ikinci yönteminiz en iyisidir. Bir işlev bağımsız değişkenine dize olarak int iletmeniz gerekiyorsa, itoa kolay bir yol olabilir. Ancak çoğu zaman, dize dönüştürme, dosyalarla uğraşırken gerçekleşir, bu nedenle akışlar uygundur.
Charles Brunet

41
Seçenek 1 sizin için nasıl çalışır? Benim anlayışım itoa()üç parametre alıyor.
b1nary.atr0phy

1
itoa akış eşdeğerinden daha hızlı olacaktır. Dize arabelleğini itoa yöntemiyle yeniden kullanmanın yolları da vardır (sık sık dizeler oluşturuyorsanız yığın tahsislerinden kaçınma. Örneğin, bazı hızlı güncellenen sayısal çıktılar için). Alternatif olarak, tahsis yükünü vb. Azaltmak için özel bir streambuf oluşturabilirsiniz. Akışın ilk etapta oluşturulması da düşük maliyetli bir girişim değildir.
Pete

6
@Pete: Hangisinin daha hızlı olduğu konusunda endişelenmeye başladığınızda stackoverflow.com/questions/4351371/…
Ben Voigt

20
İtoa () standardının bir parçası değildir ve bu nedenle, tüm derleyiciler desteklemediğinden kodunuzu taşınabilir yapmaz. Linux için, bu işlevi desteklemeyen GCC'den başka bir şey kullanmadığınız sürece kesinlikle dışarıdasınız. C ++ 0x varsa, @Matthieu'nun cevabında önerdiği şeye gidin. Durum böyle değilse, iyi desteklenen bir özellik olduğu ve kodunuzun orada her C ++ derleyicisi ile uyumlu olması gerektiği için stringstream ile gidin. Alternatif olarak her zaman sprintf () ile gidebilirsiniz.
rbaleksandar

Yanıtlar:


2100

C ++ 11, std::stoi(ve her sayısal tip için varyantları) ve std::to_stringC'nin karşılıklarını sunar atoive itoaterimiyle ifade edilir std::string.

#include <string> 

std::string s = std::to_string(42);

bu yüzden düşünebildiğim en kısa yol. autoAnahtar kelimeyi kullanarak türün adını bile atlayabilirsiniz :

auto s = std::to_string(42);

Not: bakınız [string.conversions] ( 21.5 olarak n3242 )


199
to_stringbir stddüzeltme üyesi değil : stackoverflow.com/questions/12975341/…
Ben

36
Veya derleyicinize bağlı olarak, doğru dil standardını ayarlayın:g++ -std=c++11 someFile.cc
Thomas M. DuBuisson

12
@Steve: olması gerekiyordu. Biri stdhariç bildiğim her derleyicinin bir üyesi .
Mooing Duck

5
@Matthiew M. Ben önermek aynı kullanıyorum ama bu hatayı alıyorum: Error : No instance of overloaded function "std::to_string" matches the argument list VS2010 c ++ kullanıyorum

19
@ Uçan: VS2010 altında, dönüştürme tamsayısını aşağıdaki türlerden birine açıkça atmanız gerekir [_Longlong, _ULonglong, long double]; ie:string s = to_string((_ULonglong)i);
Zac

184

Birkaç yıl sonra @ v.oddou ile bir tartışma toplarken, C ++ 17 nihayet (aşağıda korunmuş) orijinal olarak makro bazlı tip-agnostik bir çözüm yapmak için bir yol teslim etti olmadan makro uglyness geçiyor.

// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
    std::ostringstream sstr;
    // fold expression
    ( sstr << std::dec << ... << args );
    return sstr.str();
}

Kullanımı:

int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );

Orijinal cevap:

"... dize dönüştürme" yinelenen bir sorun olduğundan, her zaman S + () makro C ++ kaynaklarının merkezi üstbilgisinde tanımlamak :

#include <sstream>

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

Kullanımı olabildiğince kolaydır:

int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );

Yukarıdaki C ++ 98 uyumludur (C ++ 11 kullanamıyorsanız std::to_string) ve herhangi bir üçüncü taraf içermesi gerekmez (Boost kullanamıyorsanız lexical_cast<>); her iki çözüm de daha iyi bir performans sergiliyor.


2
Çok aşina dynamic_castdeğilim ama derlemek için clang kullanıyorum bu yüzden şikayet ediyor. Sadece atlarsam, dynamic_casto zaman iyi derler; dynamic_castbu durumda hangi amaca hizmet eder? Biz zaten bir yaratıyoruz ostringstream, neden döktük?
Mathew

2
@ Mathew: Cevabımdaki bağlantı, yapının her bir parçasının ayrıntılı bir açıklamasına yol açıyor. Biz ise oluşturulan bir ostringstreambiz denilen operator<<()hangi döner, üzerinde ostream &hangi - .str()tanımlı değil. Gerçekten clang'ın bu çalışmayı oyuncu olmadan nasıl yapacağını merak ediyorum (veya neden onunla bir hata oluşturuyor). Bu yapı birçok yerde yayınlandı ve MSVC, GCC ve XLC de dahil olmak üzere birçok farklı derleyicide on yıldan fazla bir süredir kullandım, bu yüzden clang balks'ı şaşırttım.
DevSolar

5
Sadece merak için partiye geldi ve indirildi. Sebep: zarif olmayan ve muhtemelen yavaş olan bir çözüm için çok fazla oy. 1. makro kullanımı. Herhangi bir makroda sistematik olarak kaşlarını çatmam, ama bu çok kısa ve son müşteriler her zaman argümanın tekrarlanmasından korkuyor, korumasız çok satırlı makrolar için korkunun üstünde. (do {} ile korunmuyorsa (0)) 2. dynamic_cast. kütüphanenin gerçekten umduğunuz gibi uygulandığını iddia etmek istemiyorsanız, burada yalnızca static_cast'e ihtiyacınız var gibi görünüyor. bu durumda bunun yerine boost :: polymorphic_downcast kullanmalısınız.
v.oddou

2
@ v.oddou: Elbette eleştirmekte özgürsün. Ancak 1. geçersiz - makro tek bir ifadedir, do { } while( 0 )hiçbir şey eklemez. 2. ve 3. ile muhtemelen bir nokta var - bu statik bir döküm ile yapılabilir, ve belki orada şablon sihirbazlarından biri "güzel" bir arayüz ile gelebilir. Ama dediğim gibi, bu hiçbir şekilde kendimin bir icadı değildir. Etrafına bak, bu makro (makro!) Oldukça yaygın. Bu kendi içinde bir POLA vakası. Ben daha "aerodinamik" yapmak için bu biraz oyuncak olabilir.
DevSolar

1
@ v.oddou: C ++ 17'nin bize getirdiği şeyler arasında bulduğum şeye bak. :-) Umarım güncellenmiş cevabı beğenirsiniz.
DevSolar

109

Genellikle aşağıdaki yöntemi kullanırım:

#include <sstream>

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }

Bu ayrıntılar açıklanmıştır burada .


2
Kullanmadan önce ssihtiyacınız ss.clear()var. Bu başlatma olmadan beklenmedik sonuçlar gördüm.
ömür boyu

14
@lifebalance: Hiç böyle bir davranış görmedim.
Rasoul

18
@lifebalance: clear()Yeni oluşturulan bir ostringstreamnesneye ihtiyacınız yoktur . clear()error / eof işaretlerini sıfırlar ve henüz herhangi bir error / eof koşulu oluşturulmamıştır.
Remy Lebeau

2
@Rasoul NumberToString(23213.123)üretir 23213.1iken std::to_string(23213.123)üretir 23213.123000orada ne olur?
Killzone Kid

1
@KillzoneKid Bunun nedeni, std 'ostream öğesinin durum bilgisi olması (bu, ondalık basamak sayısı gibi önceki durum değişikliklerinin tutulması anlamına gelir) ve bu yöntem varsayılan bir durumla başlar.
xryl669

85

Muhtemelen en yaygın kolay yolu adında bir şablona esasen ikinci seçim sarar lexical_castböyle de biri olarak, Boost böyle kodunuzu görünüyor böylece:

int a = 10;
string s = lexical_cast<string>(a);

Bunun bir özelliği, diğer dökümleri de desteklemesidir (örneğin, ters yönde de çalışır).

Ayrıca Boost lexical_cast sadece bir dize akışına yazmaya başladıktan sonra akıştan geri çekilmesine rağmen, şimdi birkaç ekleme olduğunu unutmayın. Her şeyden önce, birkaç tür için uzmanlık eklenmiştir, bu nedenle birçok yaygın tür için, bir dize akışı kullanmaktan çok daha hızlıdır. İkincisi, şimdi sonucu kontrol eder, bu nedenle (örneğin) bir dizeden a dönüştürürseniz, dize bir dönüştürülemeyen bir intşey içeriyorsa bir istisna atabilir int(örneğin 1234başarılı olur, ancak 123abcatar) .

C ++ 11'den itibaren, std::to_stringtamsayı türleri için aşırı yüklenmiş bir işlev vardır, böylece aşağıdaki gibi kod kullanabilirsiniz:

int a = 20;
std::string s = std::to_string(a);
// or: auto s = std::to_string(a);

İle dönüştürme yapmak için eşdeğer olarak tanımlamış, bu sprintf(örneğin nesnenin verilen türü, kibrit dönüşüm belirteci kullanarak %diçin intdaha sonra bir oluşturma, yeterli büyüklükte bir tampon içine) std::stringbu tamponun içindekiler.


2
Güzel, içerme ve ad alanını gösterdiği halde Kevin'in cevabını tercih ediyorum. Sadece küçük bir sancı. :) İyi iş olsa!
Jason R.Mick

4
C ++ 11 desteğine sahip değilseniz, bu gitmek için yol olduğunu söyleyebilirim.
Alex

40

Boost yüklediyseniz (yapmanız gerekir):

#include <boost/lexical_cast.hpp>

int num = 4;
std::string str = boost::lexical_cast<std::string>(num);

4
Boost kurulumunda anlaşmaya varıldı. Ben sık sık bir daha dize biçimlendireceğini düşünüyorum. Bu amaçla takviye :: formatı tercih ederim örneğin format ("% 02d", sayı) .str ()
Werner Erasmus

28

Dize akışlarını kullanmak daha kolay olurdu:

#include <sstream>

int x = 42;          // The integer
string str;          // The string
ostringstream temp;  // 'temp' as in temporary
temp << x;
str = temp.str();    // str is 'temp' as string

Veya bir işlev yapın:

#include <sstream>

string IntToString(int a)
{
    ostringstream temp;
    temp << a;
    return temp.str();
}

18

Bildiğim gibi değil, saf C ++. Ama bahsettiklerinizin biraz değiştirilmesi

string s = string(itoa(a));

çalışmalı ve oldukça kısa.


55
itoa()standart bir işlev değildir!
karikatürist

4
@cartoonist: O zaman nedir?
user541686

20
Bu işlev ANSI-C ve C ++ 'da tanımlanmamıştır. Bu yüzden g ++ gibi bazı derleyiciler tarafından desteklenmez.
karikatürist

17

Matthieu M tarafından önerildiğistd::to_string gibi C ++ 11'de kullanabilirsiniz :

std::to_string(42);

Veya performans kritikse (örneğin, çok sayıda dönüşüm yaparsanız), bir tamsayıyı şuna dönüştürmek fmt::format_intiçin {fmt} kitaplığından kullanabilirsiniz std::string:

fmt::format_int(42).str();

Veya bir C dizesi:

fmt::format_int f(42);
f.c_str();

İkincisi dinamik bellek ayırma yapmaz ve std::to_stringBoost Karma kriterlerinden 10 kat daha hızlıdır . Daha fazla bilgi için bkz. C ++ 'da hızlı tamsayıdan dizeye dönüştürme .

Her ikisinin de iş parçacığı için güvenli olduğunu unutmayın.

Aksine std::to_string, fmt::format_intC ++ 11 gerektirmez ve herhangi bir C ++ derleyicisiyle çalışır.

Feragatname: {fmt} kütüphanesinin yazarıyım.


2
Ben threadsafe (yeniden-giriş) kalır iken herhangi bir dinamik bellek ayırma sahip olmadığı iddia merak ediyordum, bu yüzden kodunuzu okudum - sınıf c_str()içinde bildirilen bir arabellek için bir işaretçi döndürür fmt::FormatInt- böylece dönen işaretçi geçersiz olacaktır noktalı virgül - ayrıca bkz. stackoverflow.com/questions/4214153/lifetime-of-temporaries
Soren

1
Evet, ile aynı davranış std::string::c_str()(böylece adlandırma). Tam ifade dışında kullanmak istiyorsanız bir nesne oluşturun FormatInt f(42);O zaman f.c_str()yok olma tehlikesi olmadan kullanabilirsiniz .
vitaut

1
Std :: to_string (num) kullanarak int'ten dizeye dönüştürmeye çalıştığımda garip bir şey alıyorum. Sonucu bir değişkende saklarsam ve n arttıkça stringNum [1] veya stringNum [n] gibi erişmeye çalışırsam çöp alırım.
user8951490

1
Bu sorunun kesin cevabı bu: durum bilgisi olmayan verimli ve standart kod.
xryl669

16

sprintf()biçim dönüştürme için oldukça iyidir. Ardından, ortaya çıkan C dizesini 1'de yaptığınız gibi C ++ dizesine atayabilirsiniz.


1
Heh, evet. Ancak, genellikle C stringleri işlerken sonuç için herhangi bir şey için snprintf () ve arkadaşlarına güveniyorum.
Throwback1986

1
@MatthieuM. Yorumunuz daha ileri olduğunu kanıtlıyor. Çıktı bu sınır nedeniyle kesilmişse, dönüş değeri, yeterli alan varsa son dizeye yazılan karakter sayısıdır (sonlandırıcı boş bayt hariç). Böylece, boyut veya daha büyük bir dönüş değeri, çıktının kesildiği anlamına gelir. Böylece NULL, gerekli arabellek boyutunu elde etmek için ve sıfır boyutuyla çağırırsınız .
user1095108

2
@ user1095108: Sanırım yanlış gidiyorsun snprintf( SNP önekini sprintfnot et ) ve ( SP önekini not et ). Boyutu öncekine geçirirsiniz ve taşmamaya dikkat eder, ancak ikincisi tamponun boyutunu bilmez ve bu nedenle taşabilir.
Matthieu M.

1
Fikir, önce bir snprintfvaryant ve sprintfbundan sonra bir varyant çağırmaktır . Arabellek boyutu o zamandan beri bilindiği gibi, arama sprintftamamen güvenli hale gelir.
user1095108

1
@ user1095108 Ah, evet. Snprintf için ilk arabellek yetersizse, dönüş değeri size neyin yeterli olacağını söyler. Yine de ikinci çağrı için snprintf kullanırım, çünkü sprintf ve snprintf uygulamalarına uymak gereksiz derecede tehlikelidir.
mabraham

11

İlk olarak şunları içerir:

#include <string>
#include <sstream>

İkinci yöntemi ekleyin:

template <typename T>
string NumberToString(T pNumber)
{
 ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

Bunun gibi bir yöntem kullanın:

NumberToString(69);

veya

int x = 69;
string vStr = NumberToString(x) + " Hello word!."

10

Sayı dönüştürme için stringstream kullanmak tehlikelidir!

Biçimlendirilmiş çıktı eklediğini söyleyen http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/ adresine bakın operator<<.

Geçerli yerel ayarınıza bağlı olarak 3 basamaktan büyük bir tam sayı, 4 basamaklı bir dizeye dönüşerek fazladan bir binlik ayırıcı ekleyebilir.

Örneğin, int = 1000bir dizeye dönüştürülebilir 1.001. Bu karşılaştırma işlemlerinin hiç çalışmamasına neden olabilir.

Bu yüzden std::to_stringyolu kullanmanızı şiddetle tavsiye ederim . Daha kolay ve beklediğiniz şeyi yapar.

Güncellenmiş (aşağıdaki yorumlara bakın) :

C ++ 17, std::to_charsdaha yüksek performanslı bir konumdan bağımsız alternatif olarak sunulur


2
Veri alışverişi yapmanız gerekiyorsa bunun ciddi bir sorun olduğunu kabul ediyorum. Ne yazık ki, std::to_stringgeçerli yerel ayarı da kullanır (bkz. En.cppreference.com/w/cpp/string/basic_string/to_string , 'Notlar' bölümü). Hemen hemen tüm standart araçlar (dize akışlarından sprintf, aynı zamanda sscanfvb.) Geçerli yerel ayarı kullanır. Son zamanlara kadar beni vurana kadar bunun farkında değildim. Şu anda evde yetiştirilen şeyleri kullanmak, yapmak zor değil.
Bert Bril

Yukarıdaki bağlantıda ayrıca C ++ 17'nin daha yüksek performanslı yerel ayardan bağımsız bir alternatif olarak std :: to_chars sağladığı statettir.
EvetThatIsMyName

Ne yazık ki, gelecek yıl (lar) için C ++ 11 ile sıkışmış (neyse ki, zaten bir gelişme).
Bert Bril

1
from_chars ve to_chars mükemmel olurdu ama ne yazık ki bir wchar_t varyantı sunmadılar.
gast128

8

C ++ 98 için birkaç seçenek vardır:

boost/lexical_cast

Boost, C ++ kütüphanesinin bir parçası değildir, ancak birçok yararlı kütüphane uzantısı içerir.

lexical_castFonksiyon şablonu ve onlar metin olarak temsil edilir keyfi türlerinden ortak dönüşümleri desteklemek için uygun ve tutarlı formu sunuyor.
- Boost Belgeleri

#include "boost/lexical_cast.hpp"
#include <string>

int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast<std::string>(x);
    return 0;
}

Çalışma zamanı gelince, lexical_castişlem ilk dönüşümde yaklaşık 80 mikrosaniye (makinemde) alır ve daha sonra yedekli olarak yapılırsa önemli ölçüde hızlanır.


itoa

Bu işlev ANSI-C'de tanımlanmamıştır ve C ++ 'ın bir parçası değildir, ancak bazı derleyiciler tarafından desteklenir.
- cplusplus.com

Bu, kodu kullanarak gcc/ g++derleyemeyeceğiniz anlamına gelir itoa.

#include <stdlib.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    x_str = itoa(x, x_str, 10); // base 10
    return 0;
}

Rapor etmek için çalışma zamanı yok. Derlenmiş olduğu bildirilen Visual Studio yüklü değil itoa.


sprintf

sprintf C dizeleri üzerinde çalışan ve standart olarak mükemmel bir alternatif olan C standart kitaplık işlevidir.

Printf'de biçim kullanıldıysa yazdırılacak aynı metne sahip bir dize oluşturur, ancak yazdırılmak yerine, içerik str ile gösterilen arabellekte C dizesi olarak saklanır.
- cplusplus.com

#include <stdio.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    int chars_written = sprintf(x_str, "%d", x);
    return 0;
}

stdio.hBaşlık gerekli olmayabilir. sprintfÇalışma zamanına gelince, işlem ilk dönüşümde yaklaşık 40 mikrosaniye (makinemde) alır ve daha sonra yedekli olarak yapılırsa önemli ölçüde hızlanır.


stringstream

Bu, C ++ kitaplığının tamsayıları dizelere dönüştürmenin ana yoludur ve tersi de geçerlidir. stringstreamAkımın kullanım amacını daha da sınırlayan benzer kardeş işlevleri vardır ostringstream. Özellikle kullanmak ostringstream, kod okuyucusuna yalnızca <<operatörü kullanmak istediğinizi söyler . Bu işlev özellikle bir tamsayıyı dizeye dönüştürmek için gerekli olan tek şeydir. Daha ayrıntılı bir tartışma için bu soruya bakın .

#include <sstream>
#include <string>

int main() {
    int x = 5;
    std::ostringstream stream;
    stream << x;
    std::string x_str = stream.str();
    return 0;
}

Çalışma süresine gelince, ostringstreamişlem yaklaşık 71 mikrosaniye (makinemde) alır ve daha sonra yedekli olarak yapılırsa, ancak önceki işlevler kadar değil , önemli ölçüde hızlanır .


Tabii ki başka seçenekler de var ve bunlardan birini kendi işlevinize bile sarabilirsiniz, ancak bu popüler olanlardan bazılarına analitik bir bakış sunar.


Bize baktığınız için teşekkürler (C ++ 98 kullanıcısı)
A. B

@AB Hala C ++ 98 kullanıcısı kaldığına inanamıyorum.
Kotauskas

@VladislavToncharov İşiniz yalnızca eski ekipmanı ve kodu desteklemek olduğunda, eski sektörlere daha taze endüstri standartlarını kullanarak giriyorsunuz. Bir yaz önce Python 2.3'te kod yazıyordum.
Joshua Detwiler

@JoshuaDetwiler Oh, unutmuşum, üzgünüm.
Kotauskas


3

Akarsu benzeri bir şekilde anında dizeler oluşturmanıza izin veren bazı sözdizimsel şeker eklemek oldukça kolaydır.

#include <string>
#include <sstream>

struct strmake {
    std::stringstream s;
    template <typename T> strmake& operator << (const T& x) {
        s << x; return *this;
    }   
    operator std::string() {return s.str();}
};

Artık (operatörün << (std::ostream& ..)bunun için tanımlanması koşuluyla) istediğinizi ekleyebilir strmake()ve yerine bir kullanabilirsiniz std::string.

Misal:

#include <iostream>

int main() {
    std::string x =
      strmake() << "Current time is " << 5+5 << ":" << 5*5 << " GST";
    std::cout << x << std::endl;
}

2

REDAKTE. Sabit bir sayıya sahip bir tamsayının '0' ile sola doldurulmuş char * ' a hızlı dönüştürülmesine ihtiyacınız varsa , bu küçük endian mimarileri (tümü x86, x86_64 ve diğerleri) için örnektir:

İki basamaklı bir sayıyı dönüştürüyorsanız:

int32_t s = 0x3030 | (n/10) | (n%10) << 8;

Üç basamaklı bir sayıyı dönüştürüyorsanız:

int32_t s = 0x303030 | (n/100) | (n/10%10) << 8 | (n%10) << 16;

Dört basamaklı bir sayıyı dönüştürüyorsanız:

int64_t s = 0x30303030 | (n/1000) | (n/100%10)<<8 | (n/10%10)<<16 | (n%10)<<24;

Ve böylece yedi basamaklı sayılara kadar. Bu örnekte nbelirli bir tam sayı verilmiştir. Dönüşümden sonra dize temsiline şu şekilde erişilebilir (char*)&s:

std::cout << (char*)&s << std::endl;

NOT: Büyük endian bayt sırasına ihtiyacınız varsa, test etmedim, ancak burada bir örnek var: üç basamaklı sayı int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8;için dört basamaklı sayılar içindir (64 bit kemer): int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32;Sanırım çalışması gerekir.


2
Bayt sırası ne olacak?
shjeff

Bu işaretçi takma adı nedeniyle tanımlanmamış bir davranış değil mi?
dgnuff

1
@ shjeff yorum için teşekkürler, cevaba endianness hakkında bir not ekledim.
Alek

@ dgnuff bunu işaret ettiğiniz için teşekkürler, bununla ilgili bir sorunum olmasa da haklısınız. Cevabı Sıkı Örtüşme Kurallarına uyması için biraz değiştirdim, teşekkürler.
Alek

1

kullanın:

#define convertToString(x) #x

int main()
{
    convertToString(42); // Returns const char* equivalent of 42
}

3
Yalnızca gerçek sayılarla çalışır, bazen yararlı olsa da değişken içeriği değerlendirmez.
Kurt

Sağ. Ama kesinlikle kullanışlı zaman
maverick9888

1
Sadece değişmez sabit sayıları ile derleme zamanında çalışır, ben OP değişken tamsayılar kullanarak, dinamik bir dönüşüm ister
Ing. Gerardo Sánchez

0

Kullanırım:

int myint = 0;
long double myLD = 0.0;

string myint_str = static_cast<ostringstream*>(&(ostringstream() << myint))->str();
string myLD_str = static_cast<ostringstream*>(&(ostringstream() << myLD))->str();

Windows ve Linux g ++ derleyicilerimde çalışır.


0

İşte yapmanın başka bir kolay yolu

char str[100];
sprintf(str, "%d", 101);
string s = str;

sprintf gerekli formattaki bir dizeye veri eklemek için iyi bilinen bir bilgidir.

Bir char *diziyi üçüncü satırda gösterildiği gibi bir dizeye dönüştürebilirsiniz .


0

Bu benim için çalıştı -

Kodum:

#include <iostream>
using namespace std;

int main()
{
    int n = 32;
    string s = to_string(n);
    cout << "string: " + s  << endl;
    return 0;
}

Esasen ne kullanıyorsunuz? stringstream?
Peter Mortensen

@PeterMortensen Dikkatlice bakın, bustd::to_string()
Kotauskas

Ben var using namespace std;:)
Gonçalo Garrido

0

std::to_string()Sayısal türler için C ++ 11 tanıtıldı :

int n = 123; // Input, signed/unsigned short/int/long/long long/float/double
std::string str = std::to_string(n); // Output, std::string

4
Selam! Bunun soruya neden ve nasıl cevap verdiğine dair bir açıklama ekleyebilir misiniz?
anothernode

0

kullanın:

#include<iostream>
#include<string>

std::string intToString(int num);

int main()
{
    int integer = 4782151;

    std::string integerAsStr = intToString(integer);

    std::cout << "integer = " << integer << std::endl;
    std::cout << "integerAsStr = " << integerAsStr << std::endl;

    return 0;
}

std::string intToString(int num)
{
    std::string numAsStr;

    while (num)
    {
        char toInsert = (num % 10) + 48;
        numAsStr.insert(0, 1, toInsert);

        num /= 10;
    }
    return numAsStr;
}

1
Tamamen başarısız oldu ≤0
Toby Speight

-1
string number_to_string(int x) {

    if (!x)
        return "0";

    string s, s2;
    while(x) {
        s.push_back(x%10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return s;
}

1
Kısa süreli sınırlı yardım sağlayabilecek bu kod snippet'i için teşekkür ederiz. Düzgün bir açıklama , bunun neden problem için iyi bir çözüm olduğunu göstererek uzun vadeli değerini büyük ölçüde artıracak ve diğer benzer sorularla gelecekteki okuyucular için daha yararlı hale getirecektir. Yaptığınız varsayımlar dahil bazı açıklamalar eklemek için lütfen yanıtınızı düzenleyin .
Toby Speight

Tamamen başarısız oldu ≤0
Toby Speight

Yorum ekleyin, cevabınızı açıklayın, nasıl cevap vereceğinizi okuyun .
Aksen P

-1

MFC kullanıyorsanız şunları kullanabilirsiniz CString:

int a = 10;
CString strA;
strA.Format("%d", a);

8
Bunun yalnızca Microsoft'a ait bir uzantı olduğunu unutmayın: msdn.microsoft.com/en-us/library/ms174288.aspx
JonnyJD

1
CString :: Format () fikrini seviyorum. Talihsiz sadece taşınabilir MS değil.
Nick

1
Cevabımı, @JonnyJD'deki yorumunuzu içerecek şekilde güncelledim, çünkü 5 yıl sonra bunun için aşağı indirilmeye devam ediyorum ..
Tur1ng

-2
char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs, "%d", timeStart.elapsed()/1000);
sprintf(bufMs, "%d", timeStart.elapsed()%1000);

12
bellek sızdırıyor, benden -1
paulm

Bu arabellek taşması gibi kokuyor.
Kotauskas

-2
namespace std
{
    inline string to_string(int _Val)
    {   // Convert long long to string
        char _Buf[2 * _MAX_INT_DIG];
        snprintf(_Buf, "%d", _Val);
        return (string(_Buf));
    }
}

Şimdi kullanabilirsiniz to_string(5).


10
Bu çözüm çalışırken, kesinlikle önerilmez! Alt çizgi ile başlayan isimler ve büyük harf derleyici için ayrılmıştır, bunları asla kullanmamalısınız. İşlevleri stdad alanına enjekte etmek de yapmanız gereken bir şey değildir. Ayrıca, _MAX_INT_DIGstandart bir makro gibi görünmemektedir , bu nedenle yanlış tanımlanırsa, bu kod tanımlanmamış davranışı tetikleme konusunda büyük bir potansiyele sahiptir. -1
iFreilicht

6
_MAX_INT_DIG nedir ve neden iki katına çıkar?
paulm

-2

Bence stringstreamkullanımı oldukça kolay:

 string toString(int n)
 {
     stringstream ss(n);
     ss << n;
     return ss.str();
 }

 int main()
 {
    int n;
    cin >> n;
    cout << toString(n) << endl;
    return 0;
 }

Bu soruda belirtildi ve maalesef oldukça yavaş.
Kotauskas

-3

Bir dizeye dönüştürmek için sayaç tipi bir algoritma kullanırsınız. Bu tekniği Commodore 64 bilgisayarlarını programlayarak aldım . Oyun programlama için de iyidir.

  • Tamsayıyı alırsınız ve 10'luk güçlerle ağırlıklandırılmış her basamağı alırsınız. Yani tamsayı 950 olduğunu varsayın.

    • Eğer tamsayı 100.000'e eşit veya 100.000'den büyükse, 100.000 değerini çıkarın ve dizedeki sayacı ["000000"] 'de artırın;
      100.000 konumunda daha fazla sayı kalmayıncaya kadar yapmaya devam edin. On güç daha düşür.

    • Tamsayı 10.000'e eşit veya 10'dan büyükse, 10.000 değerini çıkarın ve dizedeki sayacı ["000000"] + 1 konumunda artırın;
      10.000 konumunda daha fazla numara kalmayıncaya kadar yapmaya devam edin.

  • On güç daha düşür

  • Deseni tekrarlayın

950'nin örnek olarak kullanmak için çok küçük olduğunu biliyorum, ama umarım bu fikri anlarsınız.


Kodda bir örnek göstermek yerine bir algoritmayı tanımlamak çok yararlı değildir.
cdeerinck
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.