convert - string to char cast c++




Come convertire uno std:: string in const char*o char*? (6)

C ++ 17

C ++ 17 (imminente standard) modifica la sinossi del modello basic_string aggiungendo un sovraccarico non basic_string di data() :

charT* data() noexcept;

Restituisce: un puntatore p tale che p + i == e operatore per ogni i in [0, size ()].

CharT const * da std::basic_string<CharT>

std::string const cstr = { "..." };
char const * p = cstr.data(); // or .c_str()

CharT * da std::basic_string<CharT>

std::string str = { "..." };
char * p = str.data();

C ++ 11

CharT const * da std::basic_string<CharT>

std::string str = { "..." };
str.c_str();

CharT * da std::basic_string<CharT>

Da C ++ 11 in poi, lo standard dice:

  1. Gli oggetti char-like in un oggetto basic_string devono essere memorizzati in modo contiguo. Cioè, per ogni oggetto basic_string s , l'identità &*(s.begin() + n) == &*s.begin() + n deve contenere per tutti i valori di n tali che 0 <= n < s.size() .
  1. const_reference operator[](size_type pos) const;
    reference operator[](size_type pos);

    Restituisce: *(begin() + pos) se pos < size() , altrimenti un riferimento a un oggetto di tipo CharT con valore CharT() ; il valore di riferimento non deve essere modificato.

  1. const charT* c_str() const noexcept;
    const charT* data() const noexcept;

    Restituisce: un puntatore p tale che p + i == &operator[](i) per ogni i in [0,size()] .

Esistono diversi modi possibili per ottenere un puntatore di caratteri non const.

1. Utilizzare la memoria contigua di C ++ 11

std::string foo{"text"};
auto p = &*foo.begin();

professionista

  • Semplice e breve
  • Veloce (solo metodo senza copia in questione)

Contro

  • Final '\0' non deve essere modificato / non fa necessariamente parte della memoria non const.

2. Usa std::vector<CharT>

std::string foo{"text"};
std::vector<char> fcv(foo.data(), foo.data()+foo.size()+1u);
auto p = fcv.data();

professionista

  • Semplice
  • Gestione automatica della memoria
  • Dinamico

Contro

  • Richiede una copia di stringa

3. Usa std::array<CharT, N> se N è costante di tempo di compilazione (e abbastanza piccola)

std::string foo{"text"};
std::array<char, 5u> fca;
std::copy(foo.data(), foo.data()+foo.size()+1u, fca.begin());

professionista

  • Semplice
  • Gestisce la memoria dello stack

Contro

  • Statico
  • Richiede una copia di stringa

4. Assegnazione di memoria non elaborata con cancellazione automatica della memoria

std::string foo{ "text" };
auto p = std::make_unique<char[]>(foo.size()+1u);
std::copy(foo.data(), foo.data() + foo.size() + 1u, &p[0]);

professionista

  • Piccolo ingombro di memoria
  • Cancellazione automatica
  • Semplice

Contro

  • Richiede una copia di stringa
  • Statico (l'uso dinamico richiede molto più codice)
  • Meno funzioni del vettore o dell'array

5. Assegnazione di memoria non elaborata con gestione manuale

std::string foo{ "text" };
char * p = nullptr;
try
{
  p = new char[foo.size() + 1u];
  std::copy(foo.data(), foo.data() + foo.size() + 1u, p);
  // handle stuff with p
  delete[] p;
}
catch (...)
{
  if (p) { delete[] p; }
  throw;
}

professionista

  • Massimo 'controllo'

contro

  • Richiede una copia di stringa
  • Responsabilità massima / suscettibilità per errori
  • Complesso

Come posso convertire una std::string in un char* o in un const char* ?


Basta vedere questo:

string str1("");
const char * str2 = str1.c_str();

Tuttavia, si noti che questo restituirà un const char * . Per un char * , usare strcpy per copiarlo in un altro array di char .


Prova questo

std::string s(reinterpret_cast<const char *>(Data), Size);

Se vuoi solo passare una std::string a una funzione che ha bisogno di const char* puoi usare

std::string str;
const char * c = str.c_str();

Se vuoi ottenere una copia scrivibile, come char * , puoi farlo con questo:

std::string str;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0

// don't forget to free the string after finished using it
delete[] writable;

Modifica : si noti che quanto sopra non è eccezionalmente sicuro. Se qualcosa tra la new chiamata e la chiamata di delete viene lanciata, si verificherà una perdita di memoria, poiché nulla chiamerà automaticamente l' delete . Ci sono due modi immediati per risolvere questo problema.

boost :: scoped_array

boost::scoped_array cancellerà la memoria per te uscendo dall'ambito di applicazione:

std::string str;
boost::scoped_array<char> writable(new char[str.size() + 1]);
std::copy(str.begin(), str.end(), writable.get());
writable[str.size()] = '\0'; // don't forget the terminating 0

// get the char* using writable.get()

// memory is automatically freed if the smart pointer goes 
// out of scope

std :: vector

Questo è il modo standard (non richiede alcuna libreria esterna). std::vector , che gestisce completamente la memoria per te.

std::string str;
std::vector<char> writable(str.begin(), str.end());
writable.push_back('\0');

// get the char* using &writable[0] or &*writable.begin()

Usa il metodo .c_str() per const char * .

Puoi usare &mystring[0] per ottenere un puntatore char * , ma ci sono un paio di gotcha: non avrai necessariamente una stringa terminata da zero e non sarai in grado di cambiare la dimensione della stringa. In particolare, devi fare attenzione a non aggiungere caratteri oltre la fine della stringa o otterrai un sovraccarico del buffer (e un probabile arresto anomalo).

Non c'era alcuna garanzia che tutti i personaggi fossero parte dello stesso buffer contiguo fino al C ++ 11, ma in pratica tutte le implementazioni conosciute di std::string funzionavano in quel modo comunque; see Il comando "& s [0]" punta a caratteri contigui in una stringa std :: string? .

Si noti che molte funzioni dei membri della string rialloca il buffer interno e invalida tutti i puntatori che si potrebbero aver salvato. Meglio usarli immediatamente e poi scartarli.


char* result = strcpy((char*)malloc(str.length()+1), str.c_str());




const