J'essaie d'obtenir un programme pour permettre à un utilisateur d'entrer un mot ou un caractère, de le stocker, puis de l'imprimer jusqu'à ce que l'utilisateur le saisisse à nouveau, quittant le programme. Mon code ressemble à ceci:
#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;
}
Le problème est que je continue à obtenir l'impression de la chaîne d'entrée, même lorsque l'entrée de l'utilisateur (chèque) correspond à l'original (entrée). Est-ce que je compare les deux de manière incorrecte?
gets( )
a été retiré de la norme. Utilisezfgets( )
plutôt.strcmp()
renvoie zéro lorsque ses entrées sont égales explique comment comparer des chaînes pour l'égalité, l'inégalité, inférieure à, supérieure à, inférieure ou égale et supérieure ou égale. Toutes les comparaisons de chaînes ne sont pas pour l'égalité. Les comparaisons sensibles à la casse sont à nouveau différentes; d'autres comparaisons spéciales (ordre du dictionnaire, par exemple) nécessitent des comparateurs plus spécialisés, et il existe des expressions régulières pour des comparaisons encore plus complexes.gets()
est interdite. Elle a également été supprimée de la norme depuis C11 -> Veuillez lire Pourquoi la fonction gets est-elle si dangereuse qu'elle ne devrait pas être utilisée?Réponses:
Vous ne pouvez pas (utilement) comparer des chaînes en utilisant
!=
ou==
, vous devez utiliserstrcmp
:La raison en est que
!=
et==
ne comparera que les adresses de base de ces chaînes. Pas le contenu des chaînes elles-mêmes.la source
while (strcmp(check, input))
est suffisante et est considérée comme une bonne pratique.Ok, quelques trucs:
gets
est dangereux et doit être remplacé parfgets(input, sizeof(input), stdin)
pour ne pas avoir de débordement de tampon.Ensuite, pour comparer des chaînes, vous devez utiliser
strcmp
, où une valeur de retour de 0 indique que les deux chaînes correspondent. L'utilisation des opérateurs d'égalité (ie.!=
) Compare l'adresse des deux chaînes, par opposition à l'individuchar
s à l'intérieur.Et notez également que, bien que dans cet exemple cela ne pose pas de problème,
fgets
stocke le caractère de nouvelle ligne,'\n'
dans les tampons également;gets()
ne fait pas. Si vous comparez l'entrée utilisateur defgets()
à une chaîne littérale telle"abc"
qu'elle ne correspondrait jamais (à moins que le tampon ne soit trop petit pour que le'\n'
ne tienne pas dedans).la source
fgets()
, la chaîne peut être"abc\n"
carfgets()
conserve la nouvelle ligne. Si vous comparez cela avec"abc"
, vous obtiendrez «pas égal» en raison de la différence entre un octet nul se terminant"abc"
et la nouvelle ligne dans les données lues. Donc, vous devez zapper la nouvelle ligne. La manière fiable de le faire sur une seule ligne est cellebuffer[strcspn(buffer, "\n")] = '\0';
qui a le mérite de fonctionner correctement, qu'il y ait ou non des données dans la mémoire tampon, ou que ces données se terminent par une nouvelle ligne ou non. D'autres façons de zapper la nouvelle ligne se bloquent facilement.Utilisez
strcmp
.Ceci est dans la
string.h
bibliothèque et est très populaire.strcmp
renvoie 0 si les chaînes sont égales. Voir ceci pour une meilleure explication de ce quistrcmp
revient.En gros, vous devez faire:
ou
ou
Vous pouvez vérifier ceci , un tutoriel sur
strcmp
.la source
Vous ne pouvez pas comparer directement des tableaux comme celui-ci
Vous devriez les comparer caractère par caractère; pour cela, vous pouvez utiliser une fonction et renvoyer une valeur booléenne (True: 1, False: 0). Ensuite, vous pouvez l'utiliser dans la condition de test de la boucle while.
Essaye ça:
la source
checker
trouvé'\0'
dans l'une des chaînes, il ne recherche pas l'autre chaîne'\0'
. La fonction renvoie1
("égal") même si une chaîne n'est que le préfixe de l'autre (par exemple,"foo"
et"foobar"
).||
place de&&
.Bienvenue dans le concept du pointeur. Des générations de programmeurs débutants ont trouvé le concept insaisissable, mais si vous souhaitez devenir un programmeur compétent, vous devez finalement maîtriser ce concept - et de plus, vous vous posez déjà la bonne question. C'est bon.
Est-ce que c'est clair pour vous ce qu'est une adresse? Voir ce diagramme:
Dans le diagramme, l'entier 1 est stocké en mémoire à l' adresse 0x4000. Pourquoi à une adresse? Parce que la mémoire est grande et peut stocker de nombreux nombres entiers, tout comme une ville est grande et peut héberger de nombreuses familles. Chaque entier est stocké dans un emplacement mémoire, car chaque famille réside dans une maison. Chaque emplacement mémoire est identifié par une adresse , chaque maison étant identifiée par une adresse.
Les deux cases du diagramme représentent deux emplacements de mémoire distincts. Vous pouvez les considérer comme des maisons. L'entier 1 réside dans l'emplacement de mémoire à l'adresse 0x4000 (pensez, "4000 Elm St."). L'entier 7 réside dans l'emplacement de mémoire à l'adresse 0x4004 (pensez, "4004 Elm St.").
Vous pensiez que votre programme comparait le 1 au 7, mais ce n'était pas le cas. Il comparait le 0x4000 au 0x4004. Alors, que se passe-t-il lorsque vous avez cette situation?
Les deux entiers sont les mêmes mais les adresses diffèrent. Votre programme compare les adresses.
la source
Chaque fois que vous essayez de comparer les chaînes, comparez-les par rapport à chaque caractère. Pour cela, vous pouvez utiliser la fonction de chaîne intégrée appelée strcmp (input1, input2); et vous devez utiliser le fichier d'en-tête appelé
#include<string.h>
Essayez ce code:
la source
Creusons plus profondément pour voir pourquoi ce
check != input
n'est pas suffisant .En C, string est une spécification de bibliothèque standard.
input
ci-dessus n'est pas une chaîne .input
est le tableau 40 de char .Le contenu de
input
peut devenir une chaîne .Dans la plupart des cas, lorsqu'un tableau est utilisé dans une expression, il est converti en l'adresse de son 1er élément.
Le ci-dessous convertit
check
etinput
à leurs adresses respectives du premier élément, puis ces adresses sont comparées.Pour comparer des chaînes , nous devons utiliser ces adresses, puis examiner les données vers lesquelles elles pointent.
strcmp()
fait le travail . §7.23.4.2Non seulement le code peut trouver si les chaînes sont des mêmes données, mais laquelle est supérieure / inférieure lorsqu'elles diffèrent.
Ce qui suit est vrai lorsque la chaîne diffère.
Pour plus d'informations, voir Créer ma propre
strcmp()
fonctionla source
C'est une solution très simple dans laquelle vous obtiendrez votre sortie comme vous le souhaitez.
la source
gets();
ne fait pas partie de la norme C depuis C11.strcmp(s1,s2)
est UB car les2
contenu n'est pas spécifié au début.