Há aplicações práticas para o% n formato em família printf / scanf?

votos
17
int x;
printf(hello %n World\n, &x);
printf(%d\n, x);
Publicado 09/12/2008 em 18:45
fonte usuário
Em outras línguas...                            


8 respostas

votos
15

Não é tão útil para printf(), mas pode ser muito útil para sscanf(), especialmente se você estiver analisando uma string em várias iterações. fscanf()e scanf()avançar automaticamente os ponteiros internos pela quantidade de leitura de entrada, mas sscanf()não o faz. Por exemplo:

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
    ...
}
Respondeu 09/12/2008 em 19:02
fonte usuário

votos
5

Ele pode ser usado para executar atos malignos .

Respondeu 09/12/2008 em 19:08
fonte usuário

votos
4

Depende do que você quer dizer com prática. Há sempre outras maneiras de realizar isto (imprimir em um tampão de cadeia, com s [n] printf e calcular o comprimento, por exemplo).

Contudo

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);

deve produzir

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

(Embora não testado, não estou perto de um compilador C)

Que é apenas cerca de prática como uma forma de alinhar as coisas, mas eu não gostaria de vê-lo em código. Existem melhores formas de fazê-lo.

Respondeu 09/12/2008 em 19:02
fonte usuário

votos
3

É bastante esotérico. Se você precisa substituir um espaço reservado na cadeia gerada depois que você pode querer se lembrar de um índice para o meio da corda, de modo que você não tem que quer salvar o parâmetro printf original ou analisar a cadeia.

Respondeu 09/12/2008 em 18:53
fonte usuário

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;
}

Eu estou faltando alguma coisa aqui com certeza. Tomates é muito longe para a direita.

Respondeu 09/12/2008 em 20:19
fonte usuário

votos
1

Ele poderia ser usado como uma maneira rápida de obter os comprimentos de várias substrings.

Respondeu 09/12/2008 em 18:57
fonte usuário

votos
0

você pode ligar

int _get_printf_count_output();

para ver se o suporte% n é permitir, ou usar

int _set_printf_count_output( int enable );

Para ativar ou desativar o suporte do formato% n.

do MSDN VS2008

Respondeu 27/04/2010 em 14:02
fonte usuário

votos
0

Aqui está uma coisa a partir do código VS2005 CRT:

/* 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 traz o seguinte:

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

para a seguinte linha:

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

Eu estou supondo que isto é principalmente para evitar o que @eJames está falando

Respondeu 09/12/2008 em 19:46
fonte usuário

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