¿Cómo comparo correctamente las cadenas en C?

6 minutos de lectura

avatar de usuario
nmagerko

Estoy tratando de obtener un programa que le permita al usuario ingresar una palabra o un carácter, almacenarlo y luego imprimirlo hasta que el usuario lo escriba nuevamente y salga del programa. Mi código se ve así:

#include <stdio.h>

int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a word or character:\n");
    gets(input);   /* obsolete function: do not use!! */
    printf("I will now repeat this until you type it back to me.\n");

    while (check != input)
    {
        printf("%s\n", input);
        gets(check);   /* obsolete function: do not use!! */
    }

    printf("Good bye!");
    

    return 0;
}

El problema es que sigo obteniendo la impresión de la cadena de entrada, incluso cuando la entrada del usuario (verificación) coincide con la original (entrada). ¿Estoy comparando los dos incorrectamente?

  • gets( ) fue eliminado de la norma. Usar fgets( ) en cambio.

    –Edward Karak

    29 de enero de 2015 a las 2:31

  • Tenga en cuenta que esta respuesta a ¿Por qué strcmp() devolver cero cuando sus entradas son iguales explica cómo comparar cadenas para igualdad, desigualdad, menor que, mayor que, menor que o igual, y mayor que o igual. No todas las comparaciones de cadenas son para la igualdad. Las comparaciones entre mayúsculas y minúsculas vuelven a ser diferentes; otras comparaciones especiales (el orden del diccionario, por ejemplo) requieren comparadores más especializados, y existen expresiones regulares para comparaciones aún más complejas.

    –Jonathan Leffler

    22 de noviembre de 2016 a las 22:44

  • Tenga en cuenta también que hay una pregunta esencialmente duplicada ¿Cómo compruebo si un valor coincide con una cadena que se preguntó años antes de esto?

    –Jonathan Leffler

    10 de febrero de 2017 a las 5:24

  • ¿Responde esto a tu pregunta? ¿Cómo verifico si un valor coincide con una cadena?

    – Andreas

    16 de enero de 2020 a las 3:37

  • Esta pregunta es buena, pero el uso de gets() es un no-go. También se eliminó del estándar desde C11 -> Lea ¿Por qué la función gets es tan peligrosa que no debería usarse?

    – RobertS apoya a Mónica Cellio

    30 de mayo de 2020 a las 9:50

avatar de usuario
AusCBloque

bueno algunas cosas: gets no es seguro y debe ser reemplazado por fgets(input, sizeof(input), stdin) para que no se desborde el búfer.

A continuación, para comparar cadenas, debe utilizar strcmp, donde un valor devuelto de 0 indica que las dos cadenas coinciden. Utilizando los operadores de igualdad (es decir, !=) compara la dirección de las dos cadenas, a diferencia de la individual chars dentro de ellos.

Y también tenga en cuenta que, aunque en este ejemplo no causará ningún problema, fgets almacena el carácter de nueva línea, '\n' en los tampones también; gets() no es. Si comparó la entrada del usuario de fgets() a un literal de cadena como "abc" nunca coincidiría (a menos que el búfer fuera demasiado pequeño para que el '\n' no encajaría en él).

  • ¿Puede aclarar la relación/problema de “\n” y el literal de cadena? No obtengo un resultado igual al comparar cadenas (línea) de un archivo con otro archivo completo.

    – incompetente

    17 de julio de 2019 a las 16:32

  • @incompetente: si lee una línea de un archivo con fgets()entonces la cadena podría ser "abc\n" porque fgets() mantiene la nueva línea. Si comparas eso con "abc"obtendrá ‘no igual’ debido a la diferencia entre un byte nulo que termina "abc" y la nueva línea en los datos leídos. Entonces, tienes que eliminar la nueva línea. La forma confiable de una sola línea para hacerlo es buffer[strcspn(buffer, "\n")] = '\0'; que tiene el mérito de funcionar correctamente independientemente de si hay datos en el búfer, o si esos datos terminan con una nueva línea o no. Otras formas de eliminar la nueva línea fallan fácilmente.

    –Jonathan Leffler

    16 de enero de 2020 a las 3:39

  • Esta respuesta aborda los problemas del código con precisión, mientras que la respuesta más votada y aceptada cubre solo para responder el título de la pregunta. Sobre todo mencionar el último párrafo es genial. +1

    – RobertS apoya a Mónica Cellio

    30 de mayo de 2020 a las 9:49

avatar de usuario
Vishwanath Tallalli

Siempre que intente comparar las cadenas, compárelas con respecto a cada carácter. Para esto, puede usar la función de cadena integrada llamada strcmp (input1, input2); y debe usar el archivo de encabezado llamado #include<string.h>

Prueba este código:

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h>  

int main() 
{ 
    char s[]="STACKOVERFLOW";
    char s1[200];
    printf("Enter the string to be checked\n");//enter the input string
    scanf("%s",s1);
    if(strcmp(s,s1)==0)//compare both the strings  
    {
        printf("Both the Strings match\n"); 
    } 
    else
    {
        printf("Entered String does not match\n");  
    } 
    system("pause");  
} 

avatar de usuario
gracias

Bienvenido al concepto de la puntero. Generaciones de programadores principiantes han encontrado el concepto esquivo, pero si desea convertirse en un programador competente, eventualmente debe dominar este concepto y, además, ya está haciendo la pregunta correcta. Eso es bueno.

¿Te quedó claro qué es una dirección? Vea este diagrama:

----------     ----------
| 0x4000 |     | 0x4004 |
|    1   |     |    7   |
----------     ----------

En el diagrama, el entero 1 se almacena en la memoria en dirección 0x4000. ¿Por qué en una dirección? Porque la memoria es grande y puede almacenar muchos números enteros, al igual que una ciudad es grande y puede albergar a muchas familias. Cada número entero se almacena en una ubicación de memoria, ya que cada familia reside en una casa. Cada ubicación de memoria se identifica mediante un direcciónya que cada casa está identificada por una dirección.

Los dos cuadros en el diagrama representan dos ubicaciones de memoria distintas. Puedes pensar en ellos como si fueran casas. El número entero 1 reside en la ubicación de la memoria en la dirección 0x4000 (piense en “4000 Elm St.”). El número entero 7 reside en la ubicación de la memoria en la dirección 0x4004 (piense en “4004 Elm St.”).

Pensó que su programa estaba comparando el 1 con el 7, pero no fue así. Estaba comparando el 0x4000 con el 0x4004. Entonces, ¿qué sucede cuando tienes esta situación?

----------     ----------
| 0x4000 |     | 0x4004 |
|    1   |     |    1   |
----------     ----------

Los dos enteros son iguales pero las direcciones difieren. Su programa compara las direcciones.

avatar de usuario
Shubham

No puedes comparar arreglos directamente así

array1==array2

Debe compararlos carácter por carácter; para esto, puede usar una función y devolver un valor booleano (Verdadero: 1, Falso: 0). Luego puede usarlo en la condición de prueba del ciclo while.

Prueba esto:

#include <stdio.h>
int checker(char input[],char check[]);
int main()
{
    char input[40];
    char check[40];
    int i=0;
    printf("Hello!\nPlease enter a word or character:\n");
    scanf("%s",input);
    printf("I will now repeat this until you type it back to me.\n");
    scanf("%s",check);

    while (!checker(input,check))
    {
        printf("%s\n", input);
        scanf("%s",check);
    }

    printf("Good bye!");

    return 0;
}

int checker(char input[],char check[])
{
    int i,result=1;
    for(i=0; input[i]!='\0' || check[i]!='\0'; i++) {
        if(input[i] != check[i]) {
            result=0;
            break;
        }
    }
    return result;
}

Puede:

Usar strcmp() desde string.hque es la versión más fácil

O si quieres hacer el tuyo propio, puedes usar algo como esto:

int strcmp(char *s1, char *s2)
{
    int i;
    while(s1[i] != '\0' && s2[i] != '\0')
    {
        if(s1[i] != s2[i])
        {
            return 1;
        }
        i++;
    }
    return 0;
}

yo usaría strcmp() de una manera como esta:

while(strcmp(check, input))
{
    // code here
}

  • Probablemente quisiste poner un return 0; al final de la función strcmp

    – Harrison

    19/07/2021 a las 22:50

  • No es necesario, pero sí, es una buena práctica.

    – Anic17

    20 de julio de 2021 a las 15:19

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad