Существуют ли какие-либо практические приложения для формата% п в Printf / Scanf семье?

голоса
17
int x;
printf(hello %n World\n, &x);
printf(%d\n, x);
Задан 09/12/2008 в 18:45
источник пользователем
На других языках...                            


8 ответов

голоса
15

Это не так полезно printf(), но это может быть очень полезно sscanf(), особенно если вы разбора строки в нескольких итераций. fscanf()и scanf()автоматически продвигать свои внутренние указатели на величину входного чтения, но sscanf()не делает. Например:

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
    ...
}
Ответил 09/12/2008 в 19:02
источник пользователем

голоса
5

Он может быть использован для выполнения злых дел .

Ответил 09/12/2008 в 19:08
источник пользователем

голоса
4

Зависит от того, что вы имеете в виду практичны. Есть всегда другие способы для ее выполнения (печать в строку буфера с с [п] Printf и вычислить длину, например).

Однако

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

должна производить

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

(Хотя тестировался, я не рядом с компилятором)

Что только о практической, как способ выравнивания вещи, но я не хотел бы видеть его в коде. Есть лучшие способы сделать это.

Ответил 09/12/2008 в 19:02
источник пользователем

голоса
3

Это довольно эзотерическое. Если вам необходимо заменить заполнитель в сгенерированной строке позже вы можете вспомнить индекс в середине строки, так что вам не придется либо сохранить исходный параметр PRINTF или разобрать строку.

Ответил 09/12/2008 в 18:53
источник пользователем

голоса
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;
}

Я-то здесь отсутствует наверняка. Tomatos слишком далеко вправо.

Ответил 09/12/2008 в 20:19
источник пользователем

голоса
1

Это, возможно, может быть использован как быстрый способ получить длины различных подстрок.

Ответил 09/12/2008 в 18:57
источник пользователем

голоса
0

вы можете позвонить

int _get_printf_count_output();

чтобы увидеть, если% п поддержка включить или использовать

int _set_printf_count_output( int enable );

Чтобы включить или отключить поддержку% н формате.

из MSDN VS2008

Ответил 27/04/2010 в 14:02
источник пользователем

голоса
0

Вот кое-что из кода 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;
}

который вызывает это:

альтернативный текст http://www.shiny.co.il/shooshx/printfn.png

для следующей строки:

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

Я предполагаю, что это в основном, чтобы избежать того, что @eJames говорит о

Ответил 09/12/2008 в 19:46
источник пользователем

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