Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: Jay en 26 Abril 2021, 18:29 PM

Título: Problema con comparar cadenas
Publicado por: 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, 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");
}






Título: Re: Problema con comparar cadenas
Publicado por: MAFUS en 28 Abril 2021, 18:52 PM
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.
Título: Re: Problema con comparar cadenas
Publicado por: K-YreX en 28 Abril 2021, 21:04 PM
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:
Título: Re: Problema con comparar cadenas
Publicado por: MAFUS en 29 Abril 2021, 11:03 AM
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.