¿Hay alguna aplicación práctica para el formato% n en la familia printf / scanf?

votos
17
int x;
printf(hello %n World\n, &x);
printf(%d\n, x);
Publicado el 09/12/2008 a las 18:45
fuente por usuario
En otros idiomas...                            


8 respuestas

votos
15

No es tan útil printf(), pero puede ser muy útil sscanf(), especialmente si está analizando una cadena en múltiples iteraciones. fscanf()y scanf()avanza automáticamente sus punteros internos por la cantidad de entrada leída, pero sscanf()no lo hace. Por ejemplo:

char stringToParse[256];
...
char *curPosInString = stringToParse;  // start parsing at the beginning
int bytesRead;
while(needsParsing())
{
    sscanf(curPosInString, "(format string)%n", ..., &bytesRead);  // check the return value here
    curPosInString += bytesRead;  // Advance read pointer
    ...
}
Respondida el 09/12/2008 a las 19:02
fuente por usuario

votos
5

Se puede usar para realizar acciones malvadas .

Respondida el 09/12/2008 a las 19:08
fuente por usuario

votos
4

Depende de lo que quieras decir por práctica. Siempre hay otras formas de lograrlo (imprimir en un buffer de cadena con s [n] printf y calcular la longitud, por ejemplo).

sin embargo

int len;
char *thing = "label of unknown length";
char *value = "value value value"
char *value2="second line of value";
printf ("%s other stuff: %n", thing, &len);
printf ("%s\n%*s, value, len, value2);

debería producir

label of unknown length other stuff: value value value
                                     second line of value

(Aunque no probado, no estoy cerca de un compilador de C)

Lo cual es casi práctico como una forma de alinear las cosas, pero no me gustaría verlo en código. Hay mejores formas de hacerlo.

Respondida el 09/12/2008 a las 19:02
fuente por usuario

votos
3

Es bastante esotérico. Si necesita reemplazar un marcador de posición en la cadena generada más tarde, es posible que desee recordar un índice en el medio de la cadena, para que no tenga que guardar el parámetro printf original o analizar la cadena.

Respondida el 09/12/2008 a las 18:53
fuente por usuario

votos
1
#include <stdio.h>
int main(int argc, char* argv[])
{
    int col10 = (10 - 1);
    int col25 = (25 - 1);

    int pos1 = 0;
    int pos2 = 0;

    printf("    5    10   15   20   25   30\n");

    printf("%s%n%*s%n%*s\n",                     "fried", 
                            &pos1, col10 - pos1, "green",   
                            &pos2, col25 - pos2, "tomatos");


    printf("    ^    ^    ^    ^    ^    ^\n");

    printf("%d %d\n", pos1, pos2);
    printf("%d %d\n", col10 - pos1, col25 - pos2);

    return 0;
}

Me estoy perdiendo algo aquí seguro. Tomatos está demasiado lejos a la derecha.

Respondida el 09/12/2008 a las 20:19
fuente por usuario

votos
1

Posiblemente podría usarse como una manera rápida de obtener las longitudes de varias subcadenas.

Respondida el 09/12/2008 a las 18:57
fuente por usuario

votos
0

Puedes llamar

int _get_printf_count_output();

para ver si el soporte% n es habilitar, o utilizar

int _set_printf_count_output( int enable );

habilitar o deshabilitar el soporte del formato% n.

de MSDN VS2008

Respondida el 27/04/2010 a las 14:02
fuente por usuario

votos
0

Aquí hay algo del código CRT VS2005:

/* if %n is disabled, we skip an arg and print 'n' */
if ( !_get_printf_count_output() )
{
   _VALIDATE_RETURN(("'n' format specifier disabled", 0), EINVAL, -1);
   break;
}

que saca esto:

texto alternativo http://www.shiny.co.il/shooshx/printfn.png

para la siguiente línea:

    printf ("%s other stuff: %n", thing, &len);

Supongo que esto es principalmente para evitar de lo que @eJames está hablando

Respondida el 09/12/2008 a las 19:46
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more