2010-11-20 32 views
14

Mon programme est le suivant:Pourquoi l'utilisation du mauvais spécificateur de format en C plante-t-elle mon programme sous Windows 7?

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
     char string[] = "Gentlemen start your engines!"; 
     printf("That string is %s characters long.\r\n", strlen(string)); 
     return 0; 
} 

Je compile sous gcc, et bien qu'il ne me donne pas d'erreur le programme se bloque à chaque fois que je le lance. Le code semble être bon à partir d'exemples que j'ai vus. Ce serait génial de savoir si je fais quelque chose de mal.

Merci.

+0

Merci à tous. J'aurais dû le voir, je viens juste de commencer avec C et j'ai joué avec des programmes de texte en utilisant des chaînes de caractères uniquement jusqu'à maintenant, donc% s vient automatiquement à l'esprit. – austinprete

+4

+1 parce que j'ai appris que j'aurais dû utiliser% zu tout au long de la journée plutôt que simplement% u ou même% d –

+1

Si vous utilisez GCC, augmentez vos erreurs avec "-Wall" ou peut-être "-Wextra" ou peut-être '-Werror'. GCC est capable de vérifier la chaîne de format et d'avertir des arguments incorrects pour les fonctions 'printf'-,' scanf'-, 'strftime'- et' strfmon'. –

Répondre

16

L'utilisation spécificateur de format incorrect dans printf() Comportement non défini invoque. Correct spécificateur de format devrait être %zu (non %d) parce que le type de retour de strlen() est size_t

Note: modification de la longueur z dans %zu représente un nombre entier de même longueur que size_t

+0

Quand gcc sur Windows a-t-il arrêté d'utiliser Microsoft CRT? J'ai eu des erreurs la dernière fois que j'ai utilisé% zu sur MinGW, ou y at-il une autre version de gcc qui utilise glib? –

+0

@Pete: Vous ne devriez pas avoir une telle erreur. Assurez-vous que vous utilisez la dernière version de MinGW avec le support C99. –

+0

Doux! N'importe quel ETA pour MingW implémentant l'environnement UTF-8 émulé au-dessus des fonctions '_wfopen' etc. de fenêtres? –

2
printf("That string is %d characters long.\r\n", strlen(string)); 

à la place:

printf("That string is %s characters long.\r\n", strlen(string)); 
+0

un quelque chose, changez le nom de variable "chaîne" à quelqu'un d'autre. "chaîne" est un mot réservé. –

+0

Ok, merci.J'ai utilisé 'string' pour lancer un programme rapide qui a une longueur de chaîne, car j'écris un programme qui détecte les palindromes et je voulais avoir une idée de comment je le ferais. Je vais garder à l'esprit de ne pas l'utiliser à l'avenir cependant. – austinprete

+0

Syntaxiquement, 'string' n'est pas un mot-clé. Il est cependant, comme tous les noms commençant par 'str',' mem' ou 'wcs'," réservé pour une utilisation future "comme une fonction de chaîne dans l'en-tête' '. (source: ISO C99, 7.26.11) –

7

Vous avez spécificateur format incorrect. %s est utilisé pour les chaînes mais vous transmettez size_t (strlen(string)). L'utilisation d'un spécificateur de format incorrect dans printf() appelle comportement indéfini. Utilisez plutôt %zu car le type de retour de strlen() est size_t.

donc changer

printf("That string is %s characters long.\r\n", strlen(string)); 

à:

printf("That string is %zu characters long.\r\n", strlen(string)); 

Puisque vous utilisez gcc un coup d'oeil here pour plus d'information ce qui peut être passé à printf

+1

L'utilisation de 'gcc' pour la compilation ne signifie pas nécessairement que vous utilisez la glibc pour exécuter votre code. –

2

Vous avez un problème ici printf("That string is %s characters long.\r\n", strlen(string));

mis

printf("That string is %d characters long.\r\n", strlen(string)); % d parce que vous voulez printthe longueur de str (rendement strlen nombre)

1

plantages du programme parce que le formatage tente de routine pour accéder à une chaîne à l'adresse 0x0000001D qui est le résultat de strlen() où est rien comme une ficelle et probablement pas de mémoire accessible du tout.