¿Cómo convertir una cadena a una matriz de caracteres en C ++?

103

Me gustaría convertir stringa una charmatriz, pero no char*. Sé cómo convertir cadenas a char*(mediante el uso malloco la forma en que la publiqué en mi código), pero eso no es lo que quiero. Simplemente quiero convertir stringa una char[size]matriz. ¿Es posible?

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;

int main()
{
    // char to string
    char tab[4];
    tab[0] = 'c';
    tab[1] = 'a';
    tab[2] = 't';
    tab[3] = '\0';
    string tmp(tab);
    cout << tmp << "\n";

    // string to char* - but thats not what I want

    char *c = const_cast<char*>(tmp.c_str());
    cout << c << "\n";

    //string to char
    char tab2[1024];
    // ?

    return 0;
}
Brian Brown
fuente
12
Esto parece ser C ++, no C.
Fred Larson
@FredLarson: ok, editado, gracias
Brian Brown
3
posible duplicado de std :: string a char *
cegprakash

Respuestas:

123

La forma más sencilla en la que puedo pensar en hacerlo es:

string temp = "cat";
char tab2[1024];
strcpy(tab2, temp.c_str());

Por seguridad, es posible que prefiera:

string temp = "cat";
char tab2[1024];
strncpy(tab2, temp.c_str(), sizeof(tab2));
tab2[sizeof(tab2) - 1] = 0;

o podría ser de esta manera:

string temp = "cat";
char * tab2 = new char [temp.length()+1];
strcpy (tab2, temp.c_str());
Chowlett
fuente
9
El problema strncpyes que no terminará en nulo si alcanza el tamaño antes de encontrar un nulo en la cadena de origen. ¡Debes tener cuidado con eso también!
Fred Larson
1
Sí, creo que es una forma razonable de manejarlo.
Fred Larson
1
strncpy es por seguridad en el sentido de que strncpy no invadirá el búfer que le proporcione. Además, strcpy_s no está en C99, pero se ha agregado recientemente en C11.
bames53
6
Me encanta la forma en que las personas abusan de la palabra seguridad ... oh, no hay suficiente espacio para la cuerda, así que trunquemos ... oh, accidentalmente eliminamos la información sobre la alergia a medicamentos que amenaza la vida del paciente ... pero no tenemos un búfer saturado más. bueno, supongo que es seguro ...
Karoly Horvath
4
@KarolyHorvath: seguridad en diferentes dominios. Obviamente, debe verificar sus requisitos funcionales y No hacer cosas estúpidas. Pero si sobrepasa el búfer, pierde toda garantía de saber qué sucederá. La codificación correcta garantiza que el programa sea "seguro" para ejecutarse en su sistema operativo. El pensamiento correcto asegura que el programa sea "seguro" para hacer lo que el usuario necesita.
Chowlett
58

Ok, me sorprende que nadie haya dado una buena respuesta, ahora es mi turno. Hay dos casos;

  1. Una matriz de caracteres constante es lo suficientemente buena para usted, así que vaya con,

    const char *array = tmp.c_str();
  2. O necesita modificar la matriz de caracteres para que la constante no esté bien, luego siga con esto

    char *array = &tmp[0];

Ambos son solo operaciones de asignación y la mayoría de las veces eso es justo lo que necesita, si realmente necesita una nueva copia, siga las respuestas de otros compañeros.

rad
fuente
7
Quiere una matriz de caracteres, no un carácter *
harogaston
10
El puntero que creó es lo mismo que una matriz de caracteres. Una variable de matriz en C y C ++ es solo un puntero al primer elemento de la matriz.
JustinCB
@ JustinC.B. ¡realmente no! las variables de matriz pueden descomponerse en punteros pero no son iguales en C ++. por ejemplo, std::size(elem)en C ++ está bien definido cuando elemes un char arraypero no se puede compilar cuando elemes un char*o const char*, puede verlo aquí
aniliitb10
16

La forma más fácil de hacerlo sería esta

std::string myWord = "myWord";
char myArray[myWord.size()+1];//as 1 char space for null is also required
strcpy(myArray, myWord.c_str());
Comunidad
fuente
14
El tamaño de la matriz debe ser una constante en tiempo de compilación en C ++.
interjay
12
str.copy(cstr, str.length()+1); // since C++11
cstr[str.copy(cstr, str.length())] = '\0';  // before C++11
cstr[str.copy(cstr, sizeof(cstr)-1)] = '\0';  // before C++11 (safe)

Es una mejor práctica evitar C en C ++, por lo que std :: string :: copy debería ser la opción en lugar de strcpy .

Youka
fuente
6

Simplemente copie la cadena en la matriz con strcpy.

David Schwartz
fuente
5

Intente de esta manera debería funcionar.

string line="hello world";
char * data = new char[line.size() + 1];
copy(line.begin(), line.end(), data);
data[line.size()] = '\0'; 
Tharindu Dhanushka
fuente
4

Pruebe strcpy (), pero como dijo Fred, esto es C ++, no C

Roedora de médula
fuente
2

Podrías usar strcpy(), así:

strcpy(tab2, tmp.c_str());

Tenga cuidado con el desbordamiento del búfer.

Fred Larson
fuente
2

Si no conoce el tamaño de la cadena de antemano, puede asignar dinámicamente una matriz:

auto tab2 = std::make_unique<char[]>(temp.size() + 1);
std::strcpy(tab2.get(), temp.c_str());
emlai
fuente
0

Bien sé que esto tal vez tonta que y simple, pero creo que debería funcionar:

string n;
cin>> n;
char b[200];
for (int i = 0; i < sizeof(n); i++)
{
    b[i] = n[i];
    cout<< b[i]<< " ";
}
Ardilla
fuente
Bueno en realidad no. Estás asumiendo que nno puede ser más grande que b. Se estrellaría si n>b. Es mejor utilizar la strcpyfunción ya proporcionada. Editar: en algunos casos, podría ser incluso mejor usarlo, strcpy_sya que agrega verificación de punteros NULL (si su plataforma lo admite)
droidballoon
0

Si está usando C ++ 11 o superior, sugeriría usar std::snprintfover std::strcpyo std::strncpydebido a su seguridad (es decir, usted determina cuántos caracteres se pueden escribir en su búfer) y porque termina en nulo la cadena por usted (entonces no tienes que preocuparte por eso). Sería así:

#include <string>
#include <cstdio>

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, sizeof(tab2), "%s", tmp.c_str());

En C ++ 17, tiene esta alternativa:

#include <string>
#include <cstdio>
#include <iterator>

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, std::size(tab2), "%s", tmp.c_str());
luizfls
fuente