2010-11-20 17 views
14

Mi programa es el siguiente;¿Por qué el uso del especificador de formato incorrecto en C bloquea mi programa en 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; 
} 

Estoy compilando bajo gcc, y aunque no me da ningún error el programa se bloquea cada vez que lo ejecute. El código parece estar bien a partir de los ejemplos que he visto. Sería genial saber si estoy haciendo algo mal.

Gracias.

+0

Gracias a todos. Debería haber visto eso, recién comencé con C y había estado jugando con programas de texto que usaban cadenas solo hasta el momento, así que% s simplemente me vino a la mente. – austinprete

+4

+1 porque me enteré de que debería haber estado usando% zu todo el tiempo en lugar de simplemente% u o incluso% d –

+1

Si está utilizando GCC, suba sus errores con '-Wall' o tal vez' -Wextra' o tal vez '-Werror'. GCC puede verificar la cadena de formato y advertir sobre argumentos incorrectos para las funciones 'printf'-,' scanf'-, 'strftime'- y' strfmon'. –

Respuesta

16

Usando especificador de formato incorrecto en printf() invoca un comportamiento indefinido. especificador de formato correcto debería ser %zu (no %d) debido a que el tipo de retorno de strlen() es size_t

Nota: modificador de longitud z en %zu representa un número entero de longitud igual a size_t

+0

¿Cuándo gcc en Windows dejó de usar Microsoft CRT? Recibí errores la última vez que utilicé% zu en MinGW, o ¿hay otra versión de gcc que use glib? –

+0

@Pete: no debería recibir ningún error de este tipo. Asegúrese de estar utilizando la última versión de MinGW con soporte C99. –

+0

¡Dulce! ¿Alguna ETA para MingW implementando la configuración UTF-8 emulada en la parte superior de las funciones de Windows '_wfopen' etc.? –

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

lugar:

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

una cosa más, cambie el nombre de la variable "cadena" a otra persona. "cadena" es palabra reservada. –

+0

Ok, gracias.Usé 'cadena' para crear un programa rápido que tuviera longitud de cadena, ya que estoy escribiendo un programa que detecta palíndromos y quería saber cómo lo haría. Sin embargo, tendré presente que no lo usaré en el futuro. – austinprete

+0

Sintácticamente, 'string' no es una palabra clave. Sin embargo, todos los nombres comienzan con 'str',' mem' o 'wcs'," reservados para uso futuro "como una función de cadena en el encabezado' '. (fuente: ISO C99, 7.26.11) –

7

Tienes especificador de formato incorrecto. %s se utiliza para cadenas pero está pasando size_t (strlen(string)). El uso de especificador de formato incorrecto en printf() invoca comportamiento indefinido. Use %zu en su lugar porque el tipo de devolución de strlen() es size_t.

Así que cambia

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

a:

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

dado que está utilizando gcc echar un vistazo here para obtener más información sobre lo que se puede pasar a printf

+1

El uso de 'gcc' para la compilación no significa necesariamente que estés usando el glibc para ejecutar tu código. –

2

Usted tiene un problema aquí printf("That string is %s characters long.\r\n", strlen(string));

poner

printf("That string is %d characters long.\r\n", strlen(string)); % d porque quiere printthe longitud de str (strlen número de devolución)

1

programa se bloquea porque el formato de rutina intenta acceder a una cadena en dirección 0x0000001D que es el resultado de strlen() donde no es nada como una cuerda y es probable que no haya memoria accesible.

Cuestiones relacionadas