Jaki jest użytek ze specyfikatora formatu %n W C?
Jakie jest zastosowanie specyfikacji formatu %n
W C? Czy ktoś może wyjaśnić przykładem?
10 answers
Nic nie zostało wydrukowane. Argument musi być wskaźnikiem do podpisanej liczby int, gdzie przechowywana jest liczba znaków zapisanych do tej pory.
#include <stdio.h>
int main()
{
int val;
printf("blah %n blah\n", &val);
printf("val = %d\n", val);
return 0;
}
Poprzedni kod drukuje:
blah blah
val = 5
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-21 17:29:35
Większość z tych odpowiedzi wyjaśnia, co %n
czy (czyli nic nie wydrukować i zapisać liczbę znaków wydrukowanych do tej pory do zmiennej int
), ale do tej pory nikt tak naprawdę nie podał przykładu tego, co używa. Oto jeden:
int n;
printf("%s: %nFoo\n", "hello", &n);
printf("%*sBar\n", n, "");
Wydrukuje:
hello: Foo
Bar
Z Foo i Bar wyrównane. (Jest to trywialne, aby to zrobić bez użycia %n
dla tego konkretnego przykładu, i ogólnie zawsze można rozbić ten pierwszy printf
wywołanie:
int n = printf("%s: ", "hello");
printf("Foo\n");
printf("%*sBar\n", n, "");
Czy nieco dodana wygoda jest warta użycia czegoś ezoterycznego jak %n
(i ewentualnie wprowadzenia błędów) jest otwarta do dyskusji.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-12 22:06:51
Nie widziałem zbyt wielu praktycznych zastosowań specyfikatora %n
, ale pamiętam, że był on używany w oldschoolowych lukach printf z atakiem strun formatu jakiś czas temu.
Coś, co poszło tak
void authorizeUser( char * username, char * password){
...code here setting authorized to false...
printf(username);
if ( authorized ) {
giveControl(username);
}
}
Gdzie złośliwy użytkownik mógł skorzystać z parametru username przekazywanego do printf jako ciąg formatujący i użyć kombinacji %d
, %c
lub w / e, aby przejść przez stos wywołań, a następnie zmodyfikować zmienną / align = "left" /
Tak, to Ezoteryczne zastosowanie, ale zawsze warto wiedzieć, gdy piszesz demona, aby uniknąć luk w zabezpieczeniach? : D
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-21 11:45:24
Z tutaj widzimy, że przechowuje liczbę wydrukowanych do tej pory znaków.
n
argument jest wskaźnikiem do liczby całkowitej, do której zapisywana jest liczba bajtów zapisanych na wyjściu dotychczas przez to wywołanie do jednej z funkcjifprintf()
. Żaden argument nie jest konwertowany.
Przykładowe użycie to:
int n_chars = 0;
printf("Hello, World%n", &n_chars);
n_chars
wtedy będzie miała wartość 12
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-26 23:03:35
Argument związany z %n będzie traktowany jako int* i wypełniony liczbą wszystkich znaków wydrukowanych w tym momencie w printf.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 22:15:13
Jak na razie wszystkie odpowiedzi są na to, że %n
robi, ale nie po co ktokolwiek miałby tego chcieć. Uważam, że jest to nieco przydatne z sprintf
/snprintf
, Kiedy może być konieczne późniejsze rozbicie lub zmodyfikowanie wynikowego ciągu, ponieważ przechowywana wartość jest indeksem tablicy do wynikowego ciągu. Ta aplikacja jest o wiele bardziej przydatna, jednak z sscanf
, zwłaszcza, że funkcje z rodziny scanf
nie zwracają liczby przetworzonych znaków, ale liczby pól.
Inny naprawdę lame use to uzyskanie pseudo-log10 za darmo w tym samym czasie podczas drukowania numeru w ramach innej operacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-04 12:16:04
Pewnego dnia znalazłem się w sytuacji, w której ładnie rozwiążę mój problem. W przeciwieństwie do mojej wcześniejszej odpowiedzi , w tym przypadku, nie mogę wymyślić dobrej alternatywy.
Mam kontrolkę GUI, która wyświetla określony tekst. Ta kontrolka może wyświetlać część tekstu pogrubioną (lub kursywą, lub podkreśloną, itd.), i mogę określić, która część, określając indeksy znaków początkowych i końcowych.
W moim przypadku generuję tekst do kontrolki za pomocą snprintf
i Chciałbym, aby jedna z podstawień była pogrubiona. Znalezienie indeksów początkowych i końcowych do tej podstawienia jest nietrywialne, ponieważ:
Łańcuch zawiera wiele podstawień, a jedną z podstawień jest dowolny, określony przez użytkownika tekst. Oznacza to, że wyszukiwanie tekstowe substytucji, na której mi zależy, jest potencjalnie niejednoznaczne.
Łańcuch formatu może być zlokalizowany i może używać rozszerzenia POSIX
$
dla formatu pozycyjnego / align = "left" / Dlatego wyszukiwanie oryginalnego ciągu formatu dla samych specyfikatorów formatu jest nietrywialne.Aspekt lokalizacji oznacza również, że nie mogę łatwo podzielić ciągu formatowania na wiele wywołań do
snprintf
.
Dlatego najprostszym sposobem znalezienia indeksów wokół konkretnej substytucji byłoby wykonanie:
char buf[256];
int start;
int end;
snprintf(buf, sizeof buf,
"blah blah %s %f yada yada %n%s%n yakety yak",
someUserSpecifiedString,
someFloat,
&start, boldString, &end);
control->set_text(buf);
control->set_bold(start, end);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26
Nic nie drukuje. Jest on używany, aby dowiedzieć się, ile znaków zostało wydrukowanych, zanim %n
pojawiło się w łańcuchu formatowania, i wypisać je do podanego int:
#include <stdio.h>
int main(int argc, char* argv[])
{
int resultOfNSpecifier = 0;
_set_printf_count_output(1); /* Required in visual studio */
printf("Some format string%n\n", &resultOfNSpecifier);
printf("Count of chars before the %%n: %d\n", resultOfNSpecifier);
return 0;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-21 11:48:35
Zapisze wartość liczby znaków wydrukowanych do tej pory w tej funkcji printf()
.
Przykład:
int a;
printf("Hello World %n \n", &a);
printf("Characters printed so far = %d",a);
Wyjście tego programu będzie
Hello World
Characters printed so far = 12
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-21 11:49:40
%N to C99, nie działa z VC++.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-04 22:33:25