Quero converter um std :: string em um tipo de dados char * ou char [] .
std::string str = "string";
char* chr = str;
Resultados em: “erro: não é possível converter 'std :: string' em 'char' ...” .
Quais métodos existem para fazer isso?
Não será convertido automaticamente (graças a Deus). Você precisará usar o método c_str()
para obter a versão da string C.
std::string str = "string";
const char *cstr = str.c_str();
Observe que ele retorna a const char *
; você não tem permissão para alterar a string do estilo C retornada por c_str()
. Se você quiser processá-lo, precisará copiá-lo primeiro:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
Ou no C ++ moderno:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
c_str
loucura completamente.vector
foi inventado precisamente como um invólucro para matrizes dinâmicas; portanto, não usá-lo parece uma oportunidade perdida na melhor das hipóteses, e violando o espírito do C ++ na pior das hipóteses.std::string
seria convertido automaticamente) e depois explico o que ele deve usar, com um pequeno exemplo de código. Pensando no futuro, também explico alguns efeitos colaterais do uso dessa função, dos quais um é que você não pode editar a string retornada porc_str()
. Por engano, você vê meus pequenos exemplos como um código real de solução de problemas, o que não é.std::vector<char>
).Mais detalhes aqui e aqui, mas você pode usar
fonte
Se eu precisar de uma cópia bruta mutável do conteúdo de uma string do c ++, faça o seguinte:
e depois:
Então, por que não brinco com std :: vector ou new [] como qualquer outra pessoa? Porque quando eu preciso de uma seqüência de caracteres char * mutável do estilo C, porque desejo chamar o código C, que altera a sequência e o código C desaloca as coisas com free () e aloca com malloc () (strdup usa malloc) . Portanto, se eu passar minha string bruta para alguma função X escrita em C , pode haver uma restrição no argumento de que ela deve ser alocada no heap (por exemplo, se a função desejar chamar realloc no parâmetro). Mas é altamente improvável que ele espere um argumento alocado com (alguns redefinidos pelo usuário) new []!
fonte
strdup
é.(Esta resposta se aplica apenas ao C ++ 98.)
Por favor, não use cru
char*
.fonte
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
, sem atribuir o ponteiro de char a um temporário?std::basic_string<>::c_str()
é válido até questring
seja alterado ou destruído. Isso também implica que ele retorna o mesmo valor em chamadas subseqüentes, desde questring
não seja modificado.vector
dessa maneira. E se alguém escrevesse código com exceção de segurança sem um mecanismo RAII (ou seja, usando ponteiros brutos), a complexidade do código seria muito maior do que essa simples linha.vector
possui uma enorme quantidade de sobrecarga e complexidade. Se o seu requisito é que você tenha uma matriz de caracteres mutável , na verdade um vetor de caracteres é praticamente o wrapper C ++ ideal. Se o seu requisito realmente exige apenas um ponteiro const-char, basta usarc_str()
e pronto.Se você deseja apenas uma string no estilo C representando o mesmo conteúdo:
Se você deseja uma string no estilo C com novos conteúdos, uma maneira (desde que você não saiba o tamanho da string no tempo de compilação) é a alocação dinâmica:
Não esqueça
delete[]
disso mais tarde.Se você deseja uma matriz de tamanho limitado alocada estaticamente, em vez disso:
std::string
não se converte implicitamente nesses tipos pelo simples motivo de que a necessidade de fazer isso geralmente é um cheiro de design. Certifique-se de que você realmente precisa.Se você definitivamente precisa de um
char*
, a melhor maneira é provavelmente:fonte
&str.front(), &str.back()
que (que não estão presentes no C ++ 03) em vez dos mais comunsstr.begin()
estr.end()
?str.begin()
, ou mesmostd::begin(str)
, iterator-like? Eu não acredito questring
tenha qualquer obrigação de estar na memória contíguavector
, ou tem?&back() + 1
, não&back()
Isso seria melhor como um comentário sobre a resposta de bobobobo, mas não tenho o representante para isso. Ele realiza a mesma coisa, mas com melhores práticas.
Embora as outras respostas sejam úteis, se você precisar converter
std::string
parachar*
explicitamente sem const,const_cast
é seu amigo.Observe que isso não fornecerá uma cópia dos dados; isso lhe dará um ponteiro para a string. Assim, se você modificar um elemento de
chr
, modificarástr
.fonte
Supondo que você só precise de uma string no estilo C para passar como entrada:
fonte
Para ser estritamente pedante, você não pode "converter uma std :: string em um tipo de dados char * ou char []".
Como as outras respostas mostraram, você pode copiar o conteúdo do std :: string para uma matriz char ou criar um const char * para o conteúdo do std :: string, para que você possa acessá-lo no "estilo C" .
Se você está tentando alterar o conteúdo do std :: string, o tipo std :: string possui todos os métodos para fazer qualquer coisa que você possa precisar fazer.
Se você está tentando passar para alguma função que aceita um caractere *, há std :: string :: c_str ().
fonte
Por uma questão de completude, não esqueça
std::string::copy()
.std::string::copy()
NUL não termina. Se você precisar garantir um terminador NUL para uso nas funções da string C:fonte
Aqui está uma versão mais robusta do
Protocol Buffer
fonte
if (str[str.length()-1] != 0) str.push_back(0)
Conversão no estilo OOP
converter.hpp
converter.cpp
uso
fonte
fonte
Como alternativa, você pode usar vetores para obter um caractere gravável *, conforme demonstrado abaixo;
fonte
Você pode fazer isso usando o iterador.
Boa sorte.
fonte
Uma versão segura da resposta char * do orlp usando unique_ptr:
fonte
Para obter um
const char *
de umstd::string
uso, ac_str()
função de membro:Para obter um não-const
char *
de um,std::string
você pode usar adata()
função de membro que retorna um ponteiro não-const desde C ++ 17:Para versões mais antigas do idioma, você pode usar a construção de intervalo para copiar a sequência em um vetor do qual um ponteiro não-const pode ser obtido:
Mas lembre-se de que isso não permitirá que você modifique a string contida
str
, apenas os dados da cópia podem ser alterados dessa maneira. Observe que é especialmente importante nas versões mais antigas do idioma usarc_str()
aqui, porque naquela épocastd::string
não havia garantia de que o nulo terminasse até quec_str()
fosse chamado.fonte
Isso também vai funcionar
fonte