Scanset entrée / sortie en c

#include int main() { char str[50]={'\0'}; scanf("%[AZ]s",str); printf("%s",str); return 0; } 

1) entrée:

Bonjour le monde

sortie:

2) entrée:

Bonjour le monde

sortie:

ENFER

Dans la sortie 1, je m’attendais à la sortie en tant que “WORLD” mais elle ne donnait aucune sortie. À partir de la sortie 2, j’ai compris que cela ne fonctionne que si les premiers caractères sont en majuscule.

Pouvez-vous s’il vous plaît expliquer comment cela fonctionne réellement?

Quand tu fais

 scanf("%[AZ]s",str); 

Il faut entrer tant que vous entrez des lettres majuscules. Et puisque vous définissez tout le tableau sur '\0' , printf() arrêtera d’imprimer lorsqu’il en rencontrera un.

Par conséquent, la première entrée est vide et la seconde est en cours d’impression jusqu’à la fin de la chaîne en majuscule.

Interprétation des scansets

Quand il reçoit helloWORLD , la spécification de conversion %[AZ] échoue immédiatement car h n’est pas une lettre majuscule. Par conséquent, scanf() renvoie 0, indiquant qu’il n’a rien converti. Si vous testiez la valeur de retour, vous le sauriez.

Quand on lui donne HELLoworlD , le scanset correspond à l’ HELL et s’arrête au premier o . La chaîne de format tente également de faire correspondre un s littéral, mais scanf() ne scanf() aucun moyen pour signaler qu’il ne correspond pas à cela après la correspondance avec HELL .


Débordement de tampon

Notez que %[AZ] est en général dangereux (de même que %s ) car il n’y a pas de contrainte sur le nombre de caractères lus. Si tu as:

 char str[50]; 

alors vous devriez utiliser:

 if (scanf("%49[AZ]", str) != 1) ...some problem in the scan... 

Notez également qu’il existe une “différence d’un” entre la longueur déclarée de str et le nombre dans la chaîne de format. C’est gênant; il n’y a aucun moyen de fournir ce nombre comme argument à scanf() séparément de la chaîne de formatage (contrairement à printf() ), vous pouvez donc créer la chaîne de formatage à la volée:

 int scan_upper(char *buffer, size_t buflen) { char format[16]; if (buflen < 2) return EOF; // Or other error indication snprintf(format, sizeof(format), "%%%zu[AZ]", buflen-1); // Check this too!? return scanf(format, buffer); }