0

Tengo que hacer una función que reciba una cadena y reemplace las palabras que se encuentran en la cadena (palabras pertenecientes a una base de datos) por otras palabras mas cortas, básicamente sinónimos.

El problema principal es que a veces el código funciona y otras veces no, varia dependiendo de cuantas palabras a cambiar contenga la cadena o de en que lugar se ubiquen dichas palabras.

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

char *encriptador(char *cad, int b);

//Base de datos
struct palabras{
    char clave[15], sinonimo[15];
}palabra[10];

int main() {

    int n, i=0;
    printf("Ingrese datos a la base de datos del encriptador\n");
    do{
        printf("\nPalabra clave:");scanf("%s",palabra[i].clave);
        printf("Sinonimo:");scanf("%s",palabra[i].sinonimo);
        i++;
        printf("\nPara seguir ingresando datos presione 1:");scanf("%d",&n);
    } while(n==1);
    //Ingreso de cadena a encriptar
    char *cadena;
    cadena=(char*)calloc(70, sizeof(char));
    printf("\nIngrese la cadena que desea encriptar:");
    fflush(stdin);
    gets(cadena);
    fflush(stdin);
    printf("\nLa cadena original es:%s",cadena);
    printf("\nLa cadena encriptada es:");
    fflush(stdin);
    puts(encriptador(cadena,i));
    return 0;
}

char *encriptador(char *cad, int b){
    int j, longitud, longitud2, longitud3, bandera=0, posicion;
    char *resultado, *cad_encriptada, *cad_aux, *cad_aux2,*encriptada_1;
    //Se define e inicializa la variable donde se guardara la cadena encriptada
    cad_encriptada=(char*)calloc(70, sizeof(char));
    //Se definen cadenas que luego se concatenaran
    encriptada_1=(char*)calloc(70, sizeof(char));
    //Se buscan coincidencias y se reemplazan
    for(j=0;j<b;j++){
        resultado=strstr(cad,palabra[j].clave);
        if(resultado!=NULL){
            bandera=1;
            longitud=strlen(palabra[j].clave);
            longitud2=strlen(palabra[j].sinonimo);
            posicion= resultado-cad;
            //Se copia la cadena original antes de la palabra a cambiar
            strncpy(cad_encriptada,cad,posicion);
            strcpy(encriptada_1,cad_encriptada);
            //Se copia la palabra en el espacio indicado
            cad_encriptada=cad_encriptada+posicion;
            strncpy(cad_encriptada,palabra[j].sinonimo, longitud2);
            strcat(encriptada_1,cad_encriptada);
            //Se copia el resto de la cadena original luego de la palabra colocada;
            cad_aux=(char*)calloc(70, sizeof(char));
            strcpy(cad_aux,cad);
            longitud3=70-(longitud+posicion);
            cad_aux=cad_aux+longitud+posicion;
            cad_encriptada=cad_encriptada+longitud2;
            strncpy(cad_encriptada,cad_aux,longitud3);
            strcat(encriptada_1,cad_encriptada);
            //Se utilizan los *strcat* para unir las partes de la cadena
            //Se guarda la cadena encriptada en cad para repetir el procedimiento con otra palabra
            cad=encriptada_1;
        }
    }
    if(bandera==1){
        return encriptada_1;
    }else{
        return 0;
        printf("No se encontraron datos para encriptar");
    }
    
}

Bueno, en la base de datos cargo palabras y sus respectivos sinonimos, luego pido al usuario que ingrese una cadena y llamo a la función donde se realizan todos los reemplazos. En la función el mayor problema que tuve fue que cuando pegaba las partes de la cadena en cad_encriptada se borraba la parte anterior, por ello utilice la función strcat para concatenar las partes de la cadena.

Incluyo aqui un caso para el que no funciona correctamente: Palabras ingresadas: (utilizar;usar) (perro;dog) (mendoza;mza) Cadena ingresada: voy a utilizar esta correa con mi perro en mendoza hoy

  • 1
    ¡Bienvenido a SO en español! ¿Podrías proveernos un caso que no genere el resultado esperado? Para hacer esto por favor **edita** tu pregunta. – FranAcuna May 05 '21 at 20:27
  • Hola ya agregue un caso en el que no funcione, gracias. – Martin Bottino May 05 '21 at 21:03
  • Cuándo quiero dejar de ingresar más palabras e ingreso un número diferente de 1 el programa termina su ejecución sin si quiera que pueda ingresar la cadena a encriptar. Lo probé [acá](https://www.onlinegdb.com/online_c++_compiler). – FranAcuna May 05 '21 at 21:14
  • En mi compilador (zinjai) si funciona, tal vez en ese compilador falle el fflush(stdin) para limpiar el buffer del teclado. – Martin Bottino May 05 '21 at 21:17

1 Answers1

0

Selecciona todo tu código y bórralo. Sólo dos líneas de todo el código que presentas es .

  • Las cabeceras <stdlib.h>, <stdio.h>, <conio.h> y <string.h> son de C y no deben ser usadas en C++, lee este hilo para saber más del tema.
  • En C++ las cadenas se gestionan con el objeto std::string, no con punteros.
  • En C++ la comunicación con la consola se hace con std::cin y std::cout.

Crea una función que reciba tres cadenas: aquella que debe cambiarse, la palabra y su reemplazo, devuelve un booleano para informar de si se ha realizado algún cambio (por si hay palabras repetidas):

bool reemplaza(std::string &original, const std::string &busca, const std::string &reemplazo)
{
    auto posicion = original.find(busca);
    if (posicion != std::string::npos)
    {
        const auto cabeza = original.substr(0, posicion);
        const auto cola = original.substr(posicion + busca.length());
        original = cabeza + reemplazo + cola;
        return true;
    }

    return false;
}

Con este cambio, y programando con C++ moderno, tu código podría parecerse a:

struct palabra
{
    std::string clave, sinonimo;
};

int main()
{
    std::vector<palabra> reemplazos
    {
        {"utilizar", "usar"},
        {"perro", "dog"},
        {"mendoza", "mza"},
    };

    std::string texto;
    std::cout << "Introduce el texto: ";
    std::getline(std::cin, texto);

    for (const auto &reemplazo : reemplazos)
    {
        while (reemplaza(texto, reemplazo.clave, reemplazo.sinonimo));
    }

    std::cout << texto;

    return 0;
}

Puedes ver el código funcionando en Try it online!.

PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82