2016-09-20 2 views
0

J'ai essayé de créer un programme simple qui boucle les membres d'un tableau et balaye les caractères recherchant un caractère spécifique. J'ai rencontré un problème où strcmp() fonctionne seulement au début de la boucle. J'ai du mal à comprendre pourquoi cela arrive et toute aide serait appréciée.strcmp ne fonctionne qu'au début d'une boucle

char *file[3] = {"!x", "!!x", "x!"}; 

for (int i = 0; i < sizeof(file)/sizeof(file[0]); i++) { 
    char *line = file[i]; 
    printf("\n"); 
    for (int i = 0; i < strlen(line); i = i + 1) { 
    char character = line[i]; 
    if (strcmp("!", &character) == 0) { 
     printf("[YES] %c\n", character); 
    } else { 
     printf("[NO] %c\n", character); 
    } 
    } 
} 

sortie

[YES] ! 
[NO] x 

[YES] ! 
[NO] ! 
[NO] x 

[NO] x 
[NO] ! 
+0

Pourquoi utilisez-vous une fonction de comparaison ** chaîne ** pour comparer des caractères ** uniques **? – Olaf

+0

vous pouvez avoir un comportement indéfini: rien ne garantit que le pointeur sur un char a un zéro à proximité car ce n'est pas une chaîne. –

+0

Les commentaires ici sur une chaîne terminée par un caractère nul sont, bien sûr, corrects. Le comportement semble toujours étrange puisque, dans ce cas, nous savons ce qui vient après '& character' puisque nous connaissons le reste des caractères de la chaîne. Ce n'est pas clair pour moi pourquoi il se comporte mal de cette manière spécifique. – Brick

Répondre

2

La fonction strcmp attend l'adresse d'une chaîne terminée nulle. Au lieu de cela, vous lui passez l'adresse d'un char. strcmp puis tente de lire les emplacements de mémoire passé character, ce qui entraîne undefined behavior.

Le vrai problème est que vous ne voulez pas comparer les chaînes. Vous voulez comparer les caractères.

if (character == '!') { 
0

strcmp() compare les chaînes terminées par un caractère nul. Dans le code:

char character = line[i]; 
if (strcmp("!", &character) == 0) 

la character est pas une chaîne à zéro terminal. C'est accidentel que cela fonctionne du tout.

Vous devez faire quelque chose comme pour comparer des chaînes:

char character[2] = { line[i], '\0' }; 
if (strcmp("!", character) == 0) 

Ou comme celui-ci pour comparer les caractères:

char character = line[i]; 
if (character == '!') 
1

Le problème est, que vous fournissez des mauvais argument strcmp(), la &character n'est pas un pointeur sur une chaîne .

En citant C11, chapitre int strcmp (const char * s1, const char * s2);

int strcmp(const char *s1, const char *s2);

La fonction strcmp compare la chaîne pointée par s1 à la chaîne pointée par s2.

Ainsi, il attend à ce que les deux arguments pour être de type chaîne , qui dans votre cas est pas.

Vous pouvez simplement utiliser l'opérateur de comparaison == pour comparer char s, comme

if (line[i] == '!') //notice the '' s, they are not ""s 

et ainsi de suite.