Problema con comparar cadenas

Iniciado por Jay, 26 Abril 2021, 18:29 PM

0 Miembros y 1 Visitante están viendo este tema.

Jay

Hola tengo una duda al final quiero comaprar las cadenas lenguaje con cadena pero me dice que no es igual no tengo idea por que es, otra duda es en que en el do while no lo toma en cuenta para volver a a comparar es decir si le das a la opcion 1 no repite el proceso


#include <stdio.h>
#include <string.h>
#include<time.h>
#include<stdlib.h>
#include<ctype.h>
#include <unistd.h>


int subCadena(char *cad, char *subCad, int ini, int fin)
{
   int iC, iS;

   if((ini>fin)|| (ini<0) || (fin>=strlen(cad)))
       return 0;

   iS = 0;
   for (iC = ini; iC<=fin; iC+=10){
       subCad[iS] = cad[iC];
       iS++;
   }

   subCad[iS] = '\0';

   return 1;

}


char *invertir(char cadena[]) {
 int longitud = strlen(cadena);
 char temporal;
 for (int izquierda = 0, derecha = longitud - 1; izquierda < (longitud / 2);
      izquierda++, derecha--) {
   temporal = cadena[izquierda];
   cadena[izquierda] = cadena[derecha];
   cadena[derecha] = temporal;
 }
 return cadena;
}

char *strstr(const char *haystack, const char *needle);

int strcmp(const char * s1,const char * s2);

int main()

{

srand(time(NULL));
int n = 1 + rand()% (3 - 1);
int n3;
int op;
int n2 = n*2;
char *alfabeto = "1599024 jonathan adrian gutierrez alvarado";
char i[7];
char w[10];
char winv[8];
char j[16];
char cadena[30];
char lenguaje[40];
char fraseN[sizeof(w) * n+1];
   strcpy(fraseN, w);
char fraseM[sizeof(winv) * n2];
   strcpy(fraseM,winv);

printf("El Alfabeto es: %s\n", alfabeto);

strncpy(i,&alfabeto[0],7);
  i[7] = '\0';

strncpy(j,&alfabeto[8],16);
  j[8] = '\0';

if(subCadena(alfabeto,w,24,35) == 0){

       printf("Error");
   }

if(subCadena(alfabeto,winv,24,35) == 0){

       printf("Error");
   }


       for(int i = 0; i < n; ++i){
               strcat(fraseN, w);
           }
       for(int i = 0; i < n2; ++i){
               strcat(fraseM, winv);
           }

       strcat(lenguaje, i);
       strcat(lenguaje, fraseN);
       strcat(lenguaje, i);
       strcat(lenguaje, invertir(fraseM));
       strcat(lenguaje, j);
       strcat(lenguaje, j);
       printf("\nEste es el lenguaje: %s\n", lenguaje);


do{
  printf("\nIntroduce la cadena a verificar: \n");
       gets(cadena);

       if (strcmp(lenguaje, cadena)== 0) {
           printf("\nSon iguales", cadena);
           } else {
               printf("\nNo son iguales", cadena);
           }
       printf("\nDesea introducir otra cadena: \n1) SI \n2)NO\n");
       scanf("%d", &op);

}while(op < 2);



   system("\n pause");
}







MAFUS

Entiendo que cuándo eliges sí el problema es que no te pide otra cadena.

Cambia la cadena del scanf  de la selección por scanf("%d%*c", &op);

Un asterisco después del % hace que se consuma esa entrada pero no la cargue en ninguna variable. En este caso se consume el último carácter que es el '\n' del return. Si no lo haces se queda en la caché del teclado y el siguiente scanf (que en tu caso pide una nueva cadena) encuentra el carácter de nueva línea y lo carga en la variable.

K-YreX

Cita de: Jay en 26 Abril 2021, 18:29 PM
Hola tengo una duda al final quiero comaprar las cadenas lenguaje con cadena pero me dice que no es igual no tengo idea por que es
El problema con las cadenas es el siguiente:

const int MAX_SIZE = 20;

int main() {
  char *cadena1 = "hola"; // Se guarda "hola\0" -> '\0' es el caracter de fin de cadena siempre
  char cadena2[MAX_SIZE];
  // fgets() es la recomendacion sobre gets() para evitar problemas de desbordamiento
  fgets(cadena2, MAX_SIZE, stdin); // Introduces: "hola" y pulsas Enter '\n' -> Se guarda: "hola\n\0"
  if(strcmp(cadena1, cadena2) == 0) { // "hola\0" y "hola\n\0" no son iguales
    ...
  }
}


Una solución que me gusta usar porque además de eliminar el Enter del final también deja el buffer limpio es:

fgets(cadena2, MAX_SIZE, stdin);
if(cadena2[strlen(cadena2) - 1] == '\n') // Si el ultimo caracter de la cadena es Enter -> No queda nada en el buffer...
  cadena2[strlen(cadena2) - 1] = '\0'; // ...y elimino el Enter sustituyendolo por el caracter de fin de cadena
else // Si el ultimo caracter de la cadena no es Enter -> No cabia en el array y se ha quedado en el buffer (solo o con otros caracteres antes)
  while(getchar() != '\n'); // Consumo todos los caracteres del buffer hasta consumir el Enter que va a ser el ultimo -> Buffer limpio

Así consigues que la cadena siempre quede sin el Enter al final y el buffer siempre quede limpio.

Otra posible solución es comparar hasta el final de la cadena que no tiene el Enter, así no lo tendrás en cuenta:

if(strncmp(cadena1, cadena2, strlen(cadena1)) == 0) {
  ...
}

Inconvenientes:
  • Tienes que controlar manualmente cuál será la cadena que no tenga el Enter.
  • Cuando utilices la cadena2 para otra cosa, seguirá teniendo el Enter y tendrás que acordarte de manejarlo correctamente.



    Además la opción del:
    while(getchar() != '\n');
    también sirve como método después de un scanf() para dejar el buffer limpio. Esto sería una alternativa a la respuesta de MAFUS para que la siguiente entrada funcione correctamente.
    Además si pides un número "%d" y el usuario introduce letras, el bucle se encargará de dejar limpio el buffer eliminando todas las letras que no se hayan podido procesar en la entrada.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

MAFUS

En según qué construcciones a mi me gusta usar la función fseek después de un scanf:


#include <stdio.h>

int main() {
    char str[1024];
    printf("> ");
    scanf("%1024[^\n]", str);
    printf("%s\n", str);
   
    fseek(stdin, 0, SEEK_END);
   
    puts("");
    printf("> ");
    scanf("%1024[^\n]", str);
    printf("%s\n", str);
}


fseek lleva el puntero al final del archivo stdin, pero como es un stream lo que ocurre es que se descarta todo su contenido y queda preparado para nuevas entradas. El ejemplo anterior funciona para gcc y su contrapartida MinGW64 de Windows. Desconozco si otros compiladores aceptan esta instrucción.