2010-04-05 4 views
4

J'essaie de créer un menu de chaînes basé sur C où un utilisateur entre une commande et ensuite un bloc de code s'exécute.Lire dans une chaîne et la comparer C

Tout ce que je fais le conditionnel est jamais vrai:

char *input= ""; 
fgets(input, 50, stdin); 
printf("%s",input); 
printf("%d",strcmp(input,"arrive\0")); 
if(strcmp(input,"arrive\0")==0){.... 

Im assez nouveau à c et je suis vraiment trouver des chaînes ennuyeux.

Qu'est-ce que je fais de mal?

Note: le code actuel bloque mon programme :(

+1

+1 pour les chaînes + ennuyeuses :) –

+1

Pensez à utiliser strncmp() sur strcmp(), cela vous évitera beaucoup de maux de tête. –

+0

Pourquoi strcmp() cause des maux de tête? –

Répondre

7

Pourquoi STRCMP toujours retour non 0:

strcmp retournera 0 uniquement lorsque les chaînes sont identiques Quant à savoir pourquoi il est l'évaluation de différents toujours.. il est parce que fgets met un caractère de nouvelle ligne à la fin de votre tampon d'entrée avant la fin nulle.

/*Will print 0 if you type in arrive<enter>*/ 
printf("%d",strcmp(input,"arrive\n")); 

Pourquoi votre programme plante:

Un autre problème est que input devrait être un char buffer. Comme si: char input[1024]; Actuellement, vous avez input comme un pointeur vers une valeur nulle chaîne terminée (qui est en lecture seule mémoire)


suggestion Amical:

Aussi ne met pas la valeur nulle fin \0 intérieur les littéraux de chaîne. Il est implicite automatiquement lorsque vous utilisez un littéral de chaîne. Cela n'a pas d'importance de mettre fin à null en ce qui concerne strcmp, mais cela pourrait causer des problèmes ailleurs dans vos futurs programmes. Et les gens se demanderont pourquoi vous faites une double annulation nulle.

+0

Merci pour la réponse complète –

+0

@ahref: Pas de problème :) –

1

Essayez de remplacer la première ligne avec

char input[50]; 
memset(input, 0, sizeof(input)); 

Edit: Cependant, le vrai problème pourquoi strcmp ne retourne pas 0 est que vous devez « couper » la chaîne lue à partir fgets, qui, dans la plupart des cas, inclut un caractère de nouvelle ligne.

+0

Ou juste 'entrée char [50 ] = {0} 'au lieu de gaspiller des cycles' memset() '-ing tout. –

+0

Pourquoi le memset pour un tampon qui sera écrasé par 'fgets' de toute façon? – msw

+0

C'est juste une convention pour empêcher les apprenants C de se faire attraper avec des pièges courants. – shinkou

3

Essayez:

#define BUFF_LEN 256 

char input[BUFF_LEN]; 

fgets(input, BUFF_LEN, stdin); 

Qu'est-ce que vous avez, *input est un pointeur vers une adresse de mémoire qui n'a pas été attribué, ne peut donc pas être utilisé par votre programme. Le résultat de l'utilisation que vous êtes est indéfini, mais conduit généralement à segmentation fault. Si vous souhaitez accéder en tant que pointeur, vous devez d'abord l'affecter:

char *input = malloc(BUFF_LEN); 

... bien sûr, test pour l'échec (NULL) alors libre() après que vous avez terminé de l'utiliser.

Edit:

au moins en fonction de la single UNIX specification, fgets() est garanti pour mettre fin à annuler la mémoire tampon. Il n'est pas nécessaire d'initialiser l'entrée [].

Comme d'autres l'ont dit, il n'est pas nécessaire d'inclure null/newlines lors de l'utilisation de strcmp().

Je vous conseille vivement fortement de vous habituer à utiliser strncmp() maintenant, tout en commençant à éviter de nombreux problèmes sur la route.

+0

le compte fgets prend en inclut le caractère nul, donc il n'y a pas besoin de '- 1'. –

+0

@Matthew - Correct, édité. Force de l'habitude :) –

+2

Quels sont les problèmes spécifiques sur la route que vous soupçonnez de se produire? Voir [Quel est le problème avec strcmp?] (Http://stackoverflow.com/questions/24353504/whats-wrong-with-strcmp) –

Questions connexes