2012-01-18 20 views
5

Tengo una pregunta sobre fgets y fscanf en C. ¿Cuál es exactamente la diferencia entre estos dos? Por ejemplo:Diferencia entre fgets y fscanf?

char str[10]; 
while(fgets(str,10,ptr)) 
{ 
counter++; 
... 

y el segundo ejemplo:

char str[10]; 
while(fscanf(ptr,"%s",str)) 
{ 
counter++; 
... 

al tener un archivo de texto que contiene cadenas que están separados por un espacio vacío, por ejemplo: AB1234 AC5423 AS1433. En el primer ejemplo, el "contador" en el ciclo while no dará el mismo resultado que en el segundo ejemplo. Al cambiar el "10" en la función de Fgets, el contador siempre dará resultados diferentes. ¿Cuál es la razón para esto? ¿Puede alguien explicar también qué hace exactamente el fscanf, cuánto dura la cuerda en cada ciclo while?

Respuesta

5

La función fgets lee hasta una nueva línea (y también la almacena). fscanf con el especificador %s lee hasta cualquier espacio en blanco y no lo almacena ...

Como nota al margen, no está especificando el tamaño del búfer en scanf y no es seguro. Pruebe:

fscanf(ptr, "%9s", str) 
+0

Gracias por su respuesta, ¿esto también es similar para fputs y fprintf? ¿O cuál es la diferencia entre ellos? – phpheini

+0

No, esos son diferentes. Por ejemplo '% s' no se detiene en espacios en blanco en printf. Lee el manual. – cnicutar

3

fgets lee a una nueva línea. fscanf solo lee en espacios en blanco.

1

fgets lea toda la línea. fscanf con %s lee una cadena, separada por espacio (o \ n, \ t, etc ...). De todos modos, no debe usarlos a menos que esté seguro de que la matriz que lee es lo suficientemente grande como para contener la entrada. Usted escribió When changing the "10" in the fgets function the counter will always give different results. Tenga en cuenta que fgets y scanf no saben cuántos bytes leer. deberías decirles. cambiando el "10" simplemente agranda el búfer al que escriben estas funciones.

1

En su ejemplo, fgets leerá hasta un máximo de 9 caracteres de la secuencia de entrada y los guardará en str, junto con un terminador 0. No saltará los espacios en blanco principales. Se detendrá si ve una nueva línea (que se guardará en str) o EOF antes de la cantidad máxima de caracteres.

fscanf con el especificador de conversión %s se saltará espacios en blanco, y luego lee todos los caracteres no está en blanco, guardándolos en str seguido de un 0 terminador. Dejará de leer en el siguiente carácter de espacio en blanco o EOF. Sin un ancho de campo explícito, leerá tantos caracteres que no sean de espacios en blanco como los que están en la secuencia, lo que podría sobrepasar el búfer de destino.

Por lo tanto, imagine que la secuencia de entrada se ve así: "\t abcdef\n<EOF>". Si usó fgets para leerlo, str contendría "\t abcdef\n\0". Si usó fscanf, str podría contener "abcdef\0" (donde \0 indica el terminador 0).