Gibt es praktische Anwendungen für das Format% n in printf / scanf Familie?

stimmen
17
int x;
printf(hello %n World\n, &x);
printf(%d\n, x);
Veröffentlicht am 09/12/2008 um 18:45
quelle vom benutzer
In anderen Sprachen...                            


8 antworten

stimmen
15

Es ist nicht so nützlich für printf(), aber es kann sehr nützlich sein sscanf(), vor allem , wenn Sie eine Zeichenfolge in mehreren Iterationen sind Parsen. fscanf()und scanf()automatisch ihre internen Zeiger durch die Menge der Eingangslese vorrücken, aber sscanf()nicht. Beispielsweise:

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
    ...
}
Beantwortet am 09/12/2008 um 19:02
quelle vom benutzer

stimmen
5

Es kann zur Durchführung verwendet werden bösen Taten .

Beantwortet am 09/12/2008 um 19:08
quelle vom benutzer

stimmen
4

Hängt davon, was Sie von praktisch bedeuten. Es gibt immer andere Möglichkeiten, es zu erreichen (Druck in einen String-Puffer mit s [n] printf und berechnen die Länge, zum Beispiel).

jedoch

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

sollte produzieren

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

(Obwohl nicht getestet, ich bin nicht in der Nähe eines C-Compiler)

Das ist nur über praktisch wie eine Art, die Dinge ausrichten, aber ich möchte nicht, dass es in den Code sehen. Es gibt bessere Möglichkeiten, es zu tun.

Beantwortet am 09/12/2008 um 19:02
quelle vom benutzer

stimmen
3

Es ist ziemlich esoterisch. Wenn Sie einen Platzhalter in der generierten Zeichenfolge ersetzen müssen später mögen Sie vielleicht einen Index in die Mitte der Zeichenfolge erinnern, so dass Sie nicht haben, entweder die ursprünglichen printf Parameter zu speichern oder die Zeichenfolge zu analysieren.

Beantwortet am 09/12/2008 um 18:53
quelle vom benutzer

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

Ich vermisse hier etwas sicher. Tomatos ist zu weit nach rechts.

Beantwortet am 09/12/2008 um 20:19
quelle vom benutzer

stimmen
1

Es könnte möglicherweise als eine schnelle Art und Weise verwendet werden, um die Längen der verschiedenen Teil zu bekommen.

Beantwortet am 09/12/2008 um 18:57
quelle vom benutzer

stimmen
0

Du kannst anrufen

int _get_printf_count_output();

zu sehen, ob% n-Unterstützung ist aktivieren, oder verwenden

int _set_printf_count_output( int enable );

Aktivieren oder Unterstützung des% n-Formats zu deaktivieren.

von MSDN VS2008

Beantwortet am 27/04/2010 um 14:02
quelle vom benutzer

stimmen
0

Hier ist etwas, von dem VS2005 CRT-Code:

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

was bringt diese:

Alt-Text http://www.shiny.co.il/shooshx/printfn.png

für die folgende Zeile ein:

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

Ich vermute, dies ist vor allem, zu vermeiden, was @eJames spricht

Beantwortet am 09/12/2008 um 19:46
quelle vom benutzer

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