Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Kaxperday en 6 Noviembre 2015, 11:01 am



Título: Pasar de char* a string pérdida de datos
Publicado por: Kaxperday en 6 Noviembre 2015, 11:01 am
Si char* tiene un caracter nulo en mitad de la secuencia al construir la string se corta allí:

Código
  1. char *e = "aisjiajisfj\0buenas";
  2. cout << string(e);

Y pierdo el poder convertir el char* en string, ¿no hay alguna solución para poderlo hacer?.

Saludos.

Bueno, quizás si nos aseguramos de lo que vamos a leer no contiene caracteres nulos hasta el final.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: class_OpenGL en 6 Noviembre 2015, 12:10 pm
Lo que delimita el tamaño de una cadena de caracteres es precisamente el carácter nulo. Si no hubiera un carácter nulo, entonces no sabríamos cual es el tamaño de la cadena. Entonces, cuando un objeto de tipo std::string toma los datos, lo hace hasta que encuentra un carácter nulo (repito, no hay otra forma segura de hacerlo). Lo único que puedes hacer es saber a ciencia cierta el tamaño de la cadena (el tamaño podría estar almacenado en una variable, por ejemplo). Una vez sabido esto, podrías reemplazar todos los caracteres nulos por otro carácter a tu elección:

Código
  1. std::string cString;
  2. char *lpbyData = "aisjiajisfj\0buenas";
  3. size_t nNumCharacters = 19; // No contamos el carácter nulo del final
  4.  
  5. for(size_t i = 0; i < nNumCharacters; i++ {
  6.    if(lpbyData[i] == '\0')
  7.        lpbyData[i] = '~'; // Pon el carácter de tu elección
  8. }
  9.  
  10. cString = lpbyData;


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: Kaxperday en 6 Noviembre 2015, 19:23 pm
Una vez sabido esto, podrías reemplazar todos los caracteres nulos por otro carácter a tu elección

Es lo que pensé pero podría fallar, ya que lo que hago es cifrar un archivo donde escribo bytes (u_char*), para llamar a write de ofstream debo usar un char* entonces hago la conversión, pero si algún byte vale nulo, valdrá \0 en la conversión y me cortará la cadena, podría sustiruirlo por otro carácter, aunque al final creo que lo mejor es usar fwrite.

Y aprovecho para preguntar si alguien conoce alguna clase de C++ para escribir bytes, ya que ofstream.write() en teoria es solo para char*. Y se corta en el primer carácter nulo.

Un saludo.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: class_OpenGL en 6 Noviembre 2015, 19:30 pm
Entonces, lo único que se me ocurre es que almacenes la cadena en un vector de chars:

Código
  1. std::vector<char> cData;
  2. const char *lpbyData = "aisjiajisfj\0buenas";
  3. size_t uNumCharacters = 19;
  4.  
  5. cData.reserve(uNumCharacters);
  6.  
  7. for(int i = 0; i < uNumCharacters; i++) {
  8.    cData[i] = lpbyData[i];
  9. }


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: ivancea96 en 7 Noviembre 2015, 00:41 am
string no se basa siempre en los caracteres nulos para iniicalizarse mediante un puntero a char.
string tiene un constructor que recibe como primer parámetro el puntero a char, y como segundo parámetro la longitud de la cadena. Es uno de los constructores posibles cuando se trabaja con cadenas de datos binarios.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: Kaxperday en 7 Noviembre 2015, 18:27 pm
Si pero luego al llamar a c_str() se cortará en el primer \0 ¿no?, luego no habría valido para nada.

Código
  1. struct datos{u_char *contenido; int tamaño;};//vector<u_char>
  2.  
  3. void almacen::escribir(datos _datos)
  4. {
  5. ofstream archivo;
  6. archivo.open(directorio, ofstream::app | ofstream::binary);
  7. _datos = encriptador.encriptar_AES(_datos);
  8. archivo.write(reinterpret_cast<char*>(_datos.contenido), _datos.tamaño);
  9. //archivo.write(string((char*)_datos.contenido, _datos.tamaño).c_str(), _datos.tamaño);
  10. archivo.close();
  11. }

Ahí dejo el code problemático.

Saludos.

Edito: lo que dice ivancea es verdad gracias por la informacion del constructor, pero al pasar a c_str() se corta en la primera \0 como es de esperar, luego para escribir bytes con ofstream.write() no podemos hacerlo, puesto que necesitamos char* y si hay algun byte nulo se nos cortara la cadena.

Seguramente pase a fwrite.

Saludos.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: ivancea96 en 8 Noviembre 2015, 01:47 am
c_str() retorna la cadena completa. Y size() retorna el tamaño de la cadena. Así pues, no, no corta nada. Pero eso sí, si trabajar con cadenas binarias, trabajas siempre con métodos para ese tipo de cadenas. ni ostream::operator<<, ni strlen, ni otras funciones o métodos que se valgan de '\0' directa o indirectamente para determinar la longitud de la cadena.
Lo único que hace c_str(), al igual que data() a partir de C++11, es agregar un caracter nulo al final, siendo el tamaño real de la cadena devuelta de size()+1. Pero si trabajas con datos binarios, ese caracter nulo final es suplerfluo.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: Kaxperday en 8 Noviembre 2015, 12:14 pm
Buenas socio, me recomiendas usar fwrite y fread para trabajar con bytes en C++, ¿o conoces algo mejor?.

Por lo que has dicho, ¿esto no se cortaría?:

Código
  1. string cadena = reinterpret_cast<char*>(_datos.contenido);
  2. archivo.write(cadena.c_str(), cadena.size());

?? Saludos.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: ivancea96 en 8 Noviembre 2015, 12:25 pm
Buenas socio, me recomiendas usar fwrite y fread para trabajar con bytes en C++, ¿o conoces algo mejor?.

Por lo que has dicho, ¿esto no se cortaría?:

Código
  1. string cadena = reinterpret_cast<char*>(_datos.contenido);
  2. archivo.write(cadena.c_str(), cadena.size());

?? Saludos.

Estás construyendo mal la string. Estás construyendola pasándole solo un char*.

Citar
string tiene un constructor que recibe como primer parámetro el puntero a char, y como segundo parámetro la longitud de la cadena. Es uno de los constructores posibles cuando se trabaja con cadenas de datos binarios.



Título: Re: Pasar de char* a string pérdida de datos
Publicado por: Kaxperday en 8 Noviembre 2015, 12:33 pm
Ah si perdon, se me escapó, pero si la construyo con 2 argumentos (char*, tamaño) pasa lo mismo, pues el c_str() corta al primer \0, aunque le digamos escribe 50 char, cuando el write encuentra el primer \0 deja de escribir ¿no?.

Saludos.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: ivancea96 en 8 Noviembre 2015, 13:50 pm
El write en un archivo binario, escribe todos los bytes que le envíes. Para más información, consulta los métodos en una referencia de C++.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: Kaxperday en 8 Noviembre 2015, 17:02 pm
El write en un archivo binario, escribe todos los bytes que le envíes. Para más información, consulta los métodos en una referencia de C++.

Escribe char* es lo que recibe como argumento, y al pasar u_char* a char* se corta en el primer \0, luego escribe hasta el primer \0:

Código
  1. void almacen::escribir(datos _datos)
  2. {
  3. ofstream archivo;
  4. archivo.open(directorio, ofstream::app | ofstream::binary);
  5. _datos = encriptador.encriptar_AES(_datos);
  6. archivo.write(reinterpret_cast<char*>(_datos.contenido), _datos.tamaño);
  7. //archivo.write(string((char*)_datos.contenido, _datos.tamaño).c_str(), _datos.tamaño);
  8. archivo.close();
  9. }

Si hay un byte nulo a la mitad, escribe solo la mitad independientemente de el tamaño que ponga en el segundo argumento, ¿me equivoco?.

Saludos.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: ivancea96 en 8 Noviembre 2015, 17:35 pm
ostream::write escribe bytes, cogiendo como fuente el puntero del primer argumento, y escribe tantos bytes como le envías en el segundo argumento.
Olvídate del caracter nulo. El caracter nulo solo sirve para texto. No estás trabajando texto, el caracter nulo no existe ya para ti. No son caracteres lo que escribes, son datos, son bytes, y la forma que tienen los métodos y funciones de saber el tamaño de los bufferes que les pasas, es dándoselo tú.


Título: Re: Pasar de char* a string pérdida de datos
Publicado por: Kaxperday en 8 Noviembre 2015, 17:57 pm
okey ya te comentaré como me va, pero creo que no me escribía lo que le ordenaba, ya probaré de nuevo, gracias.