Respostas:
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);
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 por c_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
string str = "some string" ;
char *cstr = &str[0];
Se eu precisar de uma cópia bruta mutável do conteúdo de uma string do c ++, faça o seguinte:
std::string str = "string";
char* chr = strdup(str.c_str());
e depois:
free(chr);
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 []!
strdup
é.
(Esta resposta se aplica apenas ao C ++ 98.)
Por favor, não use cru char*
.
std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
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é que string
seja alterado ou destruído. Isso também implica que ele retorna o mesmo valor em chamadas subseqüentes, desde que string
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 usar c_str()
e pronto.
Se você deseja apenas uma string no estilo C representando o mesmo conteúdo:
char const* ca = str.c_str();
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:
char* ca = new char[str.size()+1];
std::copy(str.begin(), str.end(), ca);
ca[str.size()] = '\0';
Não esqueça delete[]
disso mais tarde.
Se você deseja uma matriz de tamanho limitado alocada estaticamente, em vez disso:
size_t const MAX = 80; // maximum number of chars
char ca[MAX] = {};
std::copy(str.begin(), (str.size() >= MAX ? str.begin() + MAX : str.end()), ca);
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:
vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
&str.front(), &str.back()
que (que não estão presentes no C ++ 03) em vez dos mais comuns str.begin()
e str.end()
?
str.begin()
, ou mesmo std::begin(str)
, iterator-like? Eu não acredito que string
tenha qualquer obrigação de estar na memória contígua vector
, 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
para char*
explicitamente sem const, const_cast
é seu amigo.
std::string str = "string";
char* chr = const_cast<char*>(str.c_str());
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
.
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 ().
Por uma questão de completude, não esqueça std::string::copy()
.
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
str.copy(chrs, MAX);
std::string::copy()
NUL não termina. Se você precisar garantir um terminador NUL para uso nas funções da string C:
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
Aqui está uma versão mais robusta do Protocol Buffer
char* string_as_array(string* str)
{
return str->empty() ? NULL : &*str->begin();
}
// test codes
std::string mystr("you are here");
char* pstr = string_as_array(&mystr);
cout << pstr << endl; // you are here
if (str[str.length()-1] != 0) str.push_back(0)
Conversão no estilo OOP
converter.hpp
class StringConverter {
public: static char * strToChar(std::string str);
};
converter.cpp
char * StringConverter::strToChar(std::string str)
{
return (char*)str.c_str();
}
uso
StringConverter::strToChar("converted string")
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());
Como alternativa, você pode usar vetores para obter um caractere gravável *, conforme demonstrado abaixo;
//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .push_back ('\0');
char* cstring = &writable[0] //or &*writable.begin ()
//Goodluck
Para obter um const char *
de um std::string
uso, a c_str()
função de membro:
std::string str = "string";
const char* chr = str.c_str();
Para obter um não-const char *
de um, std::string
você pode usar a data()
função de membro que retorna um ponteiro não-const desde C ++ 17:
std::string str = "string";
char* chr = str.data();
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:
std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();
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 usar c_str()
aqui, porque naquela época std::string
não havia garantia de que o nulo terminasse até que c_str()
fosse chamado.
Isso também vai funcionar
std::string s;
std::cout<<"Enter the String";
std::getline(std::cin, s);
char *a=new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());
std::cout<<a;
c_str
loucura completamente.