Как избежать знака% (процентов) в printf C?

Ответы:

421

Вы можете избежать этого, отправив двойной символ '%', например так: %%

Используя ваш пример:

printf("hello%%");

Экранирующий знак «%» предназначен только для printf. Если вы делаете:

char a[5];
strcpy(a, "%%");
printf("This is a's value: %s\n", a);

Он напечатает: This is a's value: %%

Пабло Санта Круз
источник
8
"Е (" привет %% ");" верно. Но это не бегство, я думаю. используйте printf ("привет \ 045");
Лай Цзяншань
1
@Pablo Santa Cruz: этот метод «побега» %специфичен printf, правильно?
Lazer
10
Это особый случай очень распространенного правила в экранирующих системах, что для получения буквального escape-символа вы используете <escape-символ> <escape-символ>.
dmckee --- котенок экс-модератора
12
Лай Цзяншань, это не сработает. \045это escape-время компиляции, которое является частью языка и превратится в %при компиляции. printfэто функция времени выполнения, поэтому она имеет дело с байтами вашей строки, а не с исходным кодом на языке Си, и имеет свои собственные escape-последовательности, которые являются частью функции . Короче говоря, printfэто «язык внутри языка» и printf("This is a's value: %s\n", a);дает тот же результат, что и printf("This is a's value: \045\0163\012", a);.
Triang3l
5
Кроме того , вы можете сделать это: printf("hello%c", '%');. Однако %%лучше, потому что он не использует другой аргумент.
Triang3l
36

Как уже говорили другие, %% избежит%.

Обратите внимание, однако, что вы никогда не должны делать это:

char c[100];
char *c2;
...
printf(c); /* OR */
printf(c2);

Всякий раз, когда вам нужно напечатать строку, всегда, всегда, всегда печатайте ее, используя

printf("%s", c)

чтобы предотвратить встраивание%% в проблемы [нарушения памяти, segfault и т. д.]

Mikeage
источник
Предупреждение обычно уместно, однако могут быть ситуации, в которых вы хотите сделать «это» - если вы знаете, что предоставленная вами строка будет интерпретироваться как строка формата.
пп.
2
Однажды я придумал альтернативное решение - скопировать буфер в другой буфер, а затем пройти через него, удваивая знаки%. В конце концов я натолкнулся на эту идею и заменил функцию из 20-30 строк одной строкой. Не волнуйтесь, я сильно ударил себя по голове, как я и заслуживал.
Грэм Перроу
Да, но не забывайте, что в 99% случаев, когда вы получаете строку формата, вы получаете аргументы в виде va_list, поэтому вам нужно использовать vprintf. Таким образом, я технически прав;)
Mikeage
2
Гораздо проще делать путы (с). Если
Уильям Перселл
1
ставит, добавляет новую строку. Это часто нежелательное поведение.
Mikeage
33

Если в строке нет форматов, вы можете использовать puts(или fputs):

puts("hello%");

если в строке есть формат:

printf("%.2f%%", 53.2);

Как отмечено в комментариях, putsдобавляет \nк выводу и fputsне делает.

Синан Юнюр
источник
4
Стоит также упомянуть fputs (), так как он напрямую отвечает на fprintf ().
Тим Пост
1
Put также добавляет новую строку [даже если она у вас уже есть]. Если ты этого хочешь, отлично. В противном случае ...
Mikeage
@Sinan ünür: спасибо, что напомнили мне о puts. Я никогда не думал о putsпечати строк и прыгнул прямо к printf. Уже нет.
Lazer
10

С собой ...

printf("hello%%"); /* like this */
Мартин Клейтон
источник
7

Nitpick:
Вы на самом деле не экранируете %строку, которая определяет формат для семейства функций printf()scanf()).

%, В printf()scanf()) семейства функций, начинает спецификацию преобразования. Одно из правил для спецификации преобразования гласит, что %в качестве спецификатора преобразования (сразу после того, %который запустил спецификацию преобразования) вызывается запись '%'символа без преобразования аргумента.

Строка действительно имеет 2 '%'символа внутри (в отличие от экранирующих символов: "a\bc"строка с 3 ненулевыми символами; "a%%b"строка с 4 ненулевыми символами).

PMG
источник
2
технически, это все еще "убегает"; персонажам, которые являются особенными, нужен способ «избежать» своего особого значения и вернуться к своей «природе характера»
ShinTakezou
4

Как это:

printf("hello%%");
//-----------^^ inside printf, use two percent signs together
Салман А
источник
3

Обратная косая черта в C используется для экранирования символов в строках. Строки не будут распознавать% как специальный символ, и, следовательно, нет необходимости в экранировании. Другое дело в printf: используйте %%, чтобы напечатать один%.

Ральф М. Рикенбах
источник
3

Ты можешь использовать %%:

printf("100%%");

Результат:

100%

Дональд Дак
источник
2

Да, используйте printf ("привет %%"); и это сделано.

Kevin
источник
2

Вы можете просто использовать %дважды, то есть"%%"

Пример:

printf("You gave me 12.3 %% of profit");
Д-р Шахриар
источник
1

Двойной «%» работает также в «.Format (…). Пример (с iDrawApertureMask == 87, fCornerRadMask == 0,05): csCurrentLine.Format("\%ADD%2d%C,%6.4f*\%",iDrawApertureMask,fCornerRadMask) ; дает желаемое и ожидаемое значение (содержимое строки в) csCurrentLine;»% ADD87C, 0,0500 *% "

dindea
источник