Estoy tratando de obtener un programa para permitir que un usuario ingrese una palabra o carácter, lo almacene y luego lo imprima hasta que el usuario lo vuelva a escribir, saliendo 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);
printf("I will now repeat this until you type it back to me.\n");
while (check != input)
{
printf("%s\n", input);
gets(check);
}
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 (cheque) coincide con el original (entrada). ¿Estoy comparando los dos incorrectamente?
gets( )
fue eliminado de la norma. Usar en sufgets( )
lugar.strcmp()
devuelve cero cuando sus entradas son iguales explica cómo comparar las cadenas de 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 sensibles a mayúsculas y minúsculas son diferentes nuevamente; otras comparaciones especiales (orden de diccionario, por ejemplo) requieren comparadores más especializados, y hay expresiones regulares para comparaciones aún más complejas.gets()
. También se ha eliminado del estándar desde C11 -> Lea ¿Respuestas:
No puede (útilmente) comparar cadenas usando
!=
o==
, debe usarstrcmp
:La razón de esto es porque
!=
, y==
sólo comparar las direcciones base de esas cadenas. No el contenido de las cadenas en sí.fuente
while (strcmp(check, input))
es suficiente y se considera una buena práctica.Ok algunas cosas:
gets
no es seguro y debe reemplazarse confgets(input, sizeof(input), stdin)
para que no se desborde el búfer.Luego, para comparar cadenas, debe usar
strcmp
, donde un valor de retorno de 0 indica que las dos cadenas coinciden. El uso de los operadores de igualdad (es decir!=
) compara la dirección de las dos cadenas, en oposición a las del individuochar
dentro de ellas.Y también tenga en cuenta que, si bien en este ejemplo no causará ningún problema,
fgets
almacena el carácter de nueva línea, también'\n'
en los búferes;gets()
no. Si compara la entrada del usuario desdefgets()
un literal de cadena como"abc"
nunca coincidiría (a menos que el búfer fuera demasiado pequeño para que'\n'
no entrara).fuente
fgets()
, entonces la cadena podría ser"abc\n"
porquefgets()
mantiene la nueva línea. Si compara 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 hacerlo en una línea esbuffer[strcspn(buffer, "\n")] = '\0';
tener 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 zapping de la nueva línea se bloquean fácilmente.Uso
strcmp
.Esto está en la
string.h
biblioteca, y es muy popular.strcmp
devuelve 0 si las cadenas son iguales. Vea esto para una mejor explicación de lo questrcmp
regresa.Básicamente, tienes que hacer:
o
o
Puedes consultar esto , un tutorial sobre
strcmp
.fuente
No puedes comparar matrices directamente como esta
Deberías compararlos char-by-char; para esto puede usar una función y devolver un valor booleano (True: 1, False: 0). Luego puede usarlo en la condición de prueba del ciclo while.
Prueba esto:
fuente
checker
encuentra'\0'
en una de las cadenas, no verifica la otra cadena'\0'
. La función devuelve1
("igual") incluso si una cadena es solo el prefijo de la otra (por ejemplo,"foo"
y"foobar"
).||
lugar de&&
.Bienvenido al concepto del puntero.Generaciones de programadores principiantes han encontrado el concepto evasivo, pero si desea convertirse en un programador competente, debe dominar este concepto y, además, ya está haciendo la pregunta correcta. Eso es bueno.
¿Está claro qué es una dirección? Ver este diagrama:
En el diagrama, el entero 1 se almacena en la memoria en la dirección 0x4000. ¿Por qué en una dirección? Debido a que la memoria es grande y puede almacenar muchos enteros, así como 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 por una dirección , ya que cada casa se identifica 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, "4000 Elm St."). El entero 7 reside en la ubicación de la memoria en la dirección 0x4004 (piense, "4004 Elm St.").
Pensaste que tu 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?
Los dos enteros son iguales pero las direcciones difieren. Su programa compara las direcciones.
fuente
Siempre que intentes comparar las cadenas, compáralas con respecto a cada personaje. Para esto, puede utilizar la función de cadena integrada llamada strcmp (input1, input2); y deberías usar el archivo de encabezado llamado
#include<string.h>
Prueba este código:
fuente
Profundicemos más para ver por qué
check != input
no es suficiente .En C, la cadena es una especificación de biblioteca estándar.
input
arriba no es una cadena .input
es la matriz 40 de char .El contenido de
input
puede convertirse en una cadena .En la mayoría de los casos, cuando se usa una matriz en una expresión, se convierte a la dirección de su primer elemento.
El siguiente se convierte
check
yinput
a sus respectivas direcciones del primer elemento, luego se comparan esas direcciones.Para comparar cadenas , necesitamos usar esas direcciones y luego mirar los datos que señalan.
strcmp()
hace el trabajo . §7.23.4.2El código no solo puede encontrar si las cadenas son de los mismos datos, sino cuál es mayor / menor cuando difieren.
Lo siguiente es cierto cuando la cadena difiere.
Para obtener información, vea Crear mi propia
strcmp()
funciónfuente
Esta es una solución muy simple en la que obtendrá su salida como desee.
fuente
gets();
no forma parte del estándar C desde C11.strcmp(s1,s2)
es UB ya que loss2
contenidos no se especifican al principio.