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:
- Gli oggetti char-like in un oggetto
basic_string
devono essere memorizzati in modo contiguo. Cioè, per ogni oggettobasic_string
s
, l'identità&*(s.begin() + n) == &*s.begin() + n
deve contenere per tutti i valori din
tali che0 <= n < s.size()
.
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
Restituisce:
*(begin() + pos)
sepos < size()
, altrimenti un riferimento a un oggetto di tipoCharT
con valoreCharT()
; il valore di riferimento non deve essere modificato.
const charT* c_str() const noexcept;
const charT* data() const noexcept;
Restituisce: un puntatore p tale che
p + i == &operator[](i)
per ognii
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());