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

StackOverflow https://stackoverflow.com/questions/353614

  •  20-08-2019
  •  | 
  •  

Pregunta

int x;
printf("hello %n World\n", &x);
printf("%d\n", x);
¿Fue útil?

Solución

No es tan útil para printf(), pero puede ser muy útil para sscanf(), especialmente si usted está de analizar una cadena en varias iteraciones. fscanf() y scanf() automáticamente avanzar en sus punteros internos por la cantidad de entrada de leer, pero sscanf() no.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
    ...
}

Otros consejos

Se puede usar para realizar malas acciones .

Depende de lo que entiendas por práctico. Siempre hay otras formas de lograrlo (imprima en un búfer de cadena con s [n] printf y calcule 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 se ha 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.

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.

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

#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. Los tomates están demasiado lejos a la derecha.

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 muestra 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 lo que @eJames está hablando

puedes llamar

int _get_printf_count_output();

para ver si el soporte% n está habilitado, o use

int _set_printf_count_output( int enable );

para habilitar o deshabilitar la compatibilidad con el formato% n.

de MSDN VS2008

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top