Gemakkelijkste manier om int naar string te converteren in C++

Wat is de gemakkelijkste manier om van int naar equivalente string in C++ te converteren. Ik ken twee methoden. Is er een eenvoudigere manier?

(1)

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

(2)

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

Antwoord 1, autoriteit 100%

C++11 introduceert std::stoi (en varianten voor elk numeriek type) en std::to_string, de tegenhangers van de C atoi en itoa maar uitgedrukt in termen van std::string.

#include <string> 
std::string s = std::to_string(42);

is daarom de kortste manier die ik kan bedenken. U kunt zelfs de naam van het type weglaten met het trefwoord auto:

auto s = std::to_string(42);

Opmerking: zie [string.conversions] (21,5 in n3242)


Antwoord 2, autoriteit 8%

C++20-update: std: :format zou nu de idiomatische manier zijn.


C++17-update:

Een paar jaar later een discussie aangaan met @v.oddou, heeft C++17 eindelijk een manier opgeleverd om de oorspronkelijk macro-gebaseerde type-agnostische oplossing (hieronder bewaard) te doen zonder gaan door macro-lelijkheid.

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

Gebruik:

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 ) );

Origineel (C++98) antwoord:

Sinds "converteren … naar string" een terugkerend probleem is, definieer ik de macro SSTR() altijd in een centrale header van mijn C++-bronnen:

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

Gebruik is zo eenvoudig als maar kan:

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 ) );

Het bovenstaande is compatibel met C++98 (als u C++11 std::to_string niet kunt gebruiken), en heeft geen bijlagen van derden nodig (als u Boost lexical_cast<>); beide andere oplossingen hebben echter betere prestaties.


Antwoord 3, autoriteit 5%

Ik gebruik meestal de volgende methode:

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

Het wordt hier in detail beschreven.


Antwoord 4, autoriteit 4%

Huidige C++

Vanaf C++11 is er een std::to_string functie overbelast voor integer types, dus je kunt code gebruiken zoals:

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

De standaard definieert deze als equivalent aan het uitvoeren van de conversie met sprintf (met behulp van de conversiespecificatie die overeenkomt met het geleverde type object, zoals %d voor int), in een buffer van voldoende grootte en maak vervolgens een std::string van de inhoud van die buffer.

Oude C++

Voor oudere (pre-C++11) compilers is waarschijnlijk de meest gebruikelijke gemakkelijke manier om in wezen uw tweede keuze in een sjabloon te verpakken die gewoonlijk lexical_cast wordt genoemd, zoals die in Boost, dus je code ziet er als volgt uit:

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

Een aardigheid hiervan is dat het ook andere casts ondersteunt (bijvoorbeeld in de tegenovergestelde richting werkt net zo goed).

Houd er ook rekening mee dat hoewel Boost lexical_cast begon als gewoon schrijven naar een stringstream en vervolgens weer uit de stream haalde, het nu een aantal toevoegingen heeft. Allereerst zijn er voor een flink aantal typen specialisaties toegevoegd, dus voor veel veelvoorkomende typen is het aanzienlijk sneller dan het gebruik van een stringstream. Ten tweede controleert het nu het resultaat, dus (bijvoorbeeld) als je converteert van een string naar een int, kan het een uitzondering genereren als de string iets bevat dat niet kan worden geconverteerd naar een int (bijv. 1234 zou slagen, maar 123abc zou gooien).


Antwoord 5, autoriteit 2%

Als je Boost hebt geïnstalleerd (wat je zou moeten doen):

#include <boost/lexical_cast.hpp>
int num = 4;
std::string str = boost::lexical_cast<std::string>(num);

Antwoord 6

Het zou gemakkelijker zijn om stringstreams te gebruiken:

#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

Of maak een functie:

#include <sstream>
string IntToString(int a)
{
    ostringstream temp;
    temp << a;
    return temp.str();
}

Antwoord 7

Niet dat ik weet, in pure C++. Maar een kleine wijziging van wat je noemde

string s = string(itoa(a));

zou moeten werken, en het is vrij kort.


Antwoord 8

Je kunt std::to_string gebruiken, beschikbaar in C++11 als voorgesteld door Matthieu M.:

std::to_string(42);

Of, als de prestaties van cruciaal belang zijn (bijvoorbeeld als u veel conversies uitvoert), kunt u fmt::format_int gebruiken op de {fmt} bibliotheek om een ​​geheel getal te converteren naar std::string:

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

Of een C-tekenreeks:

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

De laatste doet geen dynamische geheugentoewijzingen en is meer dan 70% sneller dan std::to_string op Boost Karma-benchmarks. Zie Honderd miljoen gehele getallen converteren naar tekenreeksen per seconde voor meer details.

Houd er rekening mee dat beide thread-safe zijn.

In tegenstelling tot std::to_string, vereist fmt::format_int geen C++11 en werkt het met elke C++ compiler.

Disclaimer: ik ben de auteur van de {fmt}-bibliotheek.


Antwoord 9

sprintf() is redelijk goed voor formaatconversie. U kunt dan de resulterende C-tekenreeks toewijzen aan de C++-tekenreeks zoals u deed in 1.


Antwoord 10

Eerst opnemen:

#include <string>
#include <sstream>

Voeg vervolgens de methode toe:

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

Gebruik de methode als volgt:

NumberToString(69);

of

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

Antwoord 11

Het gebruik van stringstream voor nummerconversie is gevaarlijk!

Zie http://www.cplusplus.com/reference /ostream/ostream/operator%3C%3C/ waar het vertelt dat operator<< geformatteerde uitvoer invoegt.

Afhankelijk van uw huidige landinstelling kan een geheel getal groter dan 3 cijfers worden omgezet in een reeks van 4 cijfers, waarbij een extra scheidingsteken voor duizendtallen wordt toegevoegd.

Bijvoorbeeld int = 1000 kan worden geconverteerd naar een tekenreeks 1.001. Hierdoor kunnen vergelijkingsbewerkingen helemaal niet werken.

Dus ik zou sterk aanbevelen om de std::to_string manier te gebruiken. Het is makkelijker en doet wat je verwacht.

Bijgewerkt (zie opmerkingen hieronder):

C++17 biedt std::to_chars als een hogere prestatie
locale-onafhankelijk alternatief


Antwoord 12

Voor C++98 zijn er een paar opties:

boost/lexical_cast

Boost maakt geen deel uit van de C++-bibliotheek, maar bevat veel nuttige bibliotheekextensies.

De functiesjabloon lexical_cast biedt een handige en consistente vorm voor het ondersteunen van algemene conversies van en naar willekeurige typen wanneer ze worden weergegeven als tekst.
Boost-documentatie

#include "boost/lexical_cast.hpp"
#include <string>
int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast<std::string>(x);
    return 0;
}

Wat de runtime betreft, de bewerking lexical_cast duurt ongeveer 80 microseconden (op mijn computer) bij de eerste conversie, en versnelt daarna aanzienlijk als het redundant wordt uitgevoerd.


itoa

Deze functie is niet gedefinieerd in ANSI-C en maakt geen deel uit van C++, maar wordt door sommige compilers ondersteund.
cplusplus.com

Dit betekent dat gcc/g++ geen code kan compileren met 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;
}

Geen runtime te melden. Ik heb Visual Studio niet geïnstalleerd, wat naar verluidt in staat is om itoa.


sprintf

sprintf is een C-standaardbibliotheekfunctie die werkt op C-strings en is een perfect geldig alternatief.

Stelt een tekenreeks samen met dezelfde tekst die zou worden afgedrukt als het formaat zou worden gebruikt op printf, maar in plaats van te worden afgedrukt, wordt de inhoud opgeslagen als een C-tekenreeks in de buffer die wordt aangeduid door str.
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;
}

De kop stdio.h is misschien niet nodig. Wat runtime betreft, de bewerking sprintf duurt ongeveer 40 microseconden (op mijn computer) bij de eerste conversie, en versnelt daarna aanzienlijk als het redundant wordt uitgevoerd.


stringstream

Dit is de belangrijkste manier van de C++-bibliotheek om gehele getallen naar tekenreeksen te converteren en vice versa. Er zijn vergelijkbare zusterfuncties als stringstream die het beoogde gebruik van de stream verder beperken, zoals ostringstream. Het gebruik van ostringstream vertelt de lezer van uw code specifiek dat u in wezen alleen de operator << wilt gebruiken. Deze functie is alles wat in het bijzonder nodig is om een ​​geheel getal naar een tekenreeks te converteren. Zie deze vraag voor een uitgebreidere discussie.

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

Wat runtime betreft, de bewerking ostringstream duurt ongeveer 71 microseconden (op mijn machine), en versnelt daarna aanzienlijk als het redundant wordt gedaan, maar niet zoveel als de vorige functies.


Natuurlijk zijn er andere opties, en je kunt er zelfs een in je eigen functie stoppen, maar dit biedt een analytische kijk op enkele van de populaire.


Antwoord 13

C++17 biedt std::to_chars als een beter presterend locale-onafhankelijk alternatief.


Antwoord 14

Het is vrij eenvoudig om wat syntactische suiker toe te voegen waarmee je strijkers on-the-fly kunt componeren op een stroomachtige manier

#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();}
};

Je kunt nu alles toevoegen wat je wilt (op voorwaarde dat er een operator << (std::ostream& ..) voor is gedefinieerd) aan strmake() en gebruik het in plaats van een std::string.

Voorbeeld:

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

Antwoord 15

BEWERKT. Als u snelle conversie van een geheel getal met een vast aantal cijfers naar char* links met ‘0’ nodig heeft, is dit het voorbeeld voor little-endian-architecturen (alle x86, x86_64 en andere):

Als u een getal van twee cijfers omrekent:

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

Als u een getal van drie cijfers omrekent:

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

Als u een getal van vier cijfers omrekent:

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

En zo verder tot zevencijferige nummers. In dit voorbeeld is n een gegeven geheel getal. Na conversie is de tekenreeksweergave toegankelijk als (char*)&s:

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

OPMERKING: als je het nodig hebt op big-endian bytevolgorde, hoewel ik het niet heb getest, maar hier is een voorbeeld: voor een driecijferig nummer is het int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8; voor viercijferige getallen (64-bits boog): int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32; Ik denk dat het zou moeten werken.


Antwoord 16

Gebruik:

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

Antwoord 17

Ik gebruik:

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();

Het werkt op mijn Windows en Linux g++ compilers.


Antwoord 18

Hier is nog een gemakkelijke manier om dit te doen

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

sprintf is een bekende methode om gegevens in te voegen in een string van het vereiste formaat.

Je kunt een char * array converteren naar een string zoals getoond in de derde regel.


Antwoord 19

Dit werkte voor mij –

Mijn code:

#include <iostream>
using namespace std;
int main()
{
    int n = 32;
    string s = to_string(n);
    cout << "string: " + s  << endl;
    return 0;
}

Antwoord 20

C++11 introduceerde std::to_string() voor numerieke typen:

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

Antwoord 21

int i = 255;
std::string s = std::to_string(i);

In c++ maakt to_string() een stringobject van de integerwaarde door de waarde weer te geven als een reeks tekens.


Antwoord 22

Met behulp van de gewone standaard stdio header, kun je het gehele getal over sprintf casten in een buffer, zoals:

#include <stdio.h>
int main()
  {
  int x=23;
  char y[2]; //the output buffer
  sprintf(y,"%d",x);
  printf("%s",y)
  }

Vergeet niet om voor uw buffergrootte te zorgen volgens uw behoeften [de tekenreeksuitvoergrootte]


Antwoord 23

Gebruik:

#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;
    bool isNegative = num < 0;
    if(isNegative) num*=-1;
    do
    {
       char toInsert = (num % 10) + 48;
       numAsStr.insert(0, 1, toInsert);
       num /= 10;
    }while (num);
    return isNegative? numAsStr.insert(0, 1, '-') : numAsStr;
}

Antwoord 24

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;
}

Antwoord 25

Als je MFC, je kunt CString gebruiken:

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

Antwoord 26

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

Antwoord 27

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));
    }
}

Je kunt nu to_string(5) gebruiken.


Antwoord 28

Ik denk dat het gebruik van stringstream vrij eenvoudig is:

 string toString(int n)
 {
     stringstream ss(n);
     ss << n;
     return ss.str();
 }
 int main()
 {
    int n;
    cin >> n;
    cout << toString(n) << endl;
    return 0;
 }

Antwoord 29

U gebruikt een algoritme van het type teller om te converteren naar een tekenreeks. Ik heb deze techniek gekregen door Commodore 64 computers te programmeren. Het is ook goed voor het programmeren van games.

  • Je neemt het gehele getal en neemt elk cijfer dat is gewogen met machten van 10. Dus neem aan dat het gehele getal 950 is.

    • Als het gehele getal gelijk is aan of groter is dan 100.000, trek dan 100.000 af en verhoog de teller in de string op [“000000”];
      blijf het doen totdat er geen nummers meer op positie 100.000 staan.
      Laat nog een macht van tien vallen.

    • Als het gehele getal gelijk is aan of groter is dan 10.000, trek dan 10.000 af en verhoog de teller in de tekenreeks op [“000000”] + 1 positie;
      blijf het doen totdat er geen nummers meer op positie 10.000 staan.

  • Laat nog een macht van tien vallen

  • Herhaal het patroon

Ik weet dat 950 te klein is om als voorbeeld te gebruiken, maar ik hoop dat je het idee begrijpt.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes