2

Estoy intentando pedir que se ingrese una palabra y luego crear un espacio de memoria nuevo para copiar allí la palabra ingresada por el usuario pero no se como hacerlo.

Tengo esto:

#include <string.h> // strlen, strcpy, strcmp, strcat
#include <stdio.h> // sprintf, scanf, ungetc, stdin

int main() {

   char palabra[100];

   printf("Palabra: "); 
   scanf("%s", palabra); // guardamos la palabra en el arreglo

   int tam = strlen(palabra); // me guarda el tamaño de la palabra ingresada

   printf("Escribiste: %s\n", palabra); // muestra la palabra

   printf("Tamaño arreglo: %d\n", tam); // muestra el tamaño

   // creamos memoria dinamica, y "nueva" apunta a la primer celda del arreglo
   char *nueva = new char[tam + 1];

   // creamos un puntero auxiliar para recorrer a "nueva" dejando la posibilidad 
      de acceder al primer caracter luego con el puntero "nueva" que ha quedado 
      intacto.
   char *aux = nueva;

   // creamos un puntero para recorrer el arreglo de la palabra ingresada
   char *p = palabra;

   // mientras el caracter de la celda del arreglo de palabra sea distinto a el 
      final de linea 
   while (*p != '\n') {
    // el contenido a donde apunta aux es modificado por el contenido de a donde 
      apunta p
      *aux = *p;

      aux++; // apuntamos a la siguiente celda del arreglo
      p++;
   }

   printf("Nueva palabra: %s\n", nueva); // mostramos la copia

   delete[] nueva; // liberamos memoria de la copia

   // la memoria del arreglo palabra se libera al finalizar el main() automaticamente

   return 0;
}

Pero no funciona asi.

En los comentarios dejo como es mi razonamiento al escribir ese codigo. Y hago comentarios para que me corrigen si digo algo que muestre que estoy equivocado en como entiendo algunas cosas.

Saludos!

Trauma
  • 25,297
  • 4
  • 37
  • 60
EnMiPcFunciona
  • 165
  • 1
  • 16

2 Answers2

3

En tu código indicas que recorres la formación de caracteres mientras el carácter de la celda sea distinto a el final de linea, pero en ningú lado has añadido el final de línea (\n) a la cadena que estás copiando.

Lo puedes arreglar así:

// creamos memoria dinamica, y "nueva" apunta a la primer celda del arreglo
char *nueva = new char[tam + 1];
nueva[tam] = '\n';

Otras cosas a tener en cuenta.

Estás etiquetando la pregunta como y es correcto porque utilizas los operadores new y delete que son exclusivos de C++, pero es lo único que usas de dicho lenguaje en tu código.

Si quieres programar en C++ usando las cabeceras de C, debes usar las versiones adaptadas a C++, en tu caso <cstring> y <cstdio>, lee este hilo para saber más al respecto.


Sin embargo mi consejo es que, si estás programando en C++, abandones por completo las prácticas y cabeceras de C pasando a usar std::cin en lugar de scanf y std::cout en lugar de printf; además de usar std::string. Si necesitas practicar con punteros, tu código podría quedar así:

#include <iostream>
#include <string>

int main() {

    std::string palabra;

    std::cout << "Palabra: "; 
    // guardamos la palabra en el string, sin limite de tamaño!
    std::getline(std::cin, palabra);

    // me guarda el tamaño de la palabra ingresada    
    const auto tam = palabra.length();

    std::cout << "Escribiste: " << palabra            // muestra la palabra
              << "\nTamaño arreglo: " << tam << '\n'; // muestra el tamaño

    // creamos memoria dinamica, y "nueva" apunta a la primer celda del arreglo
    // añadiendo {} al final, toda la memoria se inicializa a 0
    char *nueva = new char[tam + 1]{};
    nueva[tam] = '\n';

    std::copy(palabra.begin(), palabra.end(), nueva);

    std::cout << "Nueva palabra: " << nueva << '\n'; // mostramos la copia

    delete[] nueva; // liberamos memoria de la copia

    return 0;
}

Puedes ver el código funcionando en Wandbox 三へ( へ՞ਊ ՞)へ ハッハッ.


El carácter de final de cadena es 0, cuando imprimes nueva al final de la cadena pueden salirte caracteres extraños, esto se debe a que la consola no ha encontrado final de la cadena (0) si no que ha encontrado salto de línea (\n) y seguirá mostrando caracteres hasta dar con un final de cadena, pertenezca o no a la cadena original.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
2

El problema esta la condición del while. Tenes que cambiar '\n' por '\0'.

while (*p != '\0') // '\0' es el fin de cadena
{
    // el contenido a donde apunta aux es modificado por el contenido de a donde apunta p
    *aux = *p;

    aux++; // apuntamos a la siguiente celda del arreglo
    p++;
}
*aux = '\0'; // Finalizar correctamente la palabra nueva con el caracter nulo
Germán Martínez
  • 1,057
  • 1
  • 9
  • 16