Bagaimana cara menghindari% (persen) masuk pada printf C?

274

Bagaimana Anda keluar dari tanda% saat menggunakan printfdi C?

printf("hello\%"); /* not like this */
Chris_45
sumber

Jawaban:

421

Anda dapat menghindarinya dengan memposting ganda '%' seperti ini: %%

Menggunakan contoh Anda:

printf("hello%%");

Meloloskan tanda '%' hanya untuk printf. Jika kamu melakukan:

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

Itu akan mencetak: This is a's value: %%

Pablo Santa Cruz
sumber
8
"printf (" hello %% ");" benar. Tapi saya pikir itu bukan pelarian. gunakan printf ("hello \ 045");
Lai Jiangshan
1
@Pablo Santa Cruz: metode ini untuk "melarikan diri" %khusus untuk printf, benar?
Lazer
10
Ini adalah kasus khusus dari aturan yang sangat umum dalam melarikan diri sistem yang untuk mendapatkan simbol escape literal Anda menggunakan <escape simbol> <escape simbol>.
dmckee --- ex-moderator kitten
12
Lai Jiangshan, ini tidak akan berhasil. \045adalah kompilasi waktu melarikan diri yang merupakan bagian dari bahasa dan akan berubah menjadi %ketika dikompilasi. printfadalah fungsi run-time, sehingga berhubungan dengan byte dari string Anda, bukan dengan kode sumber C, dan ia memiliki urutan pelarian sendiri yang merupakan bagian dari fungsi . Singkatnya, printfadalah "bahasa di dalam bahasa", dan printf("This is a's value: %s\n", a);memberikan hasil yang sama dengan printf("This is a's value: \045\0163\012", a);.
Triang3l
5
Juga, Anda dapat melakukan ini: printf("hello%c", '%');. Namun, %%lebih baik karena tidak menggunakan argumen lain.
Triang3l
36

Seperti yang orang lain katakan, %% akan lolos dari%.

Namun, perhatikan bahwa Anda tidak boleh melakukan ini:

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

Setiap kali Anda harus mencetak sebuah string, selalu, selalu, selalu cetak dengan menggunakan

printf("%s", c)

untuk mencegah embedded% dari menyebabkan masalah [pelanggaran memori, segfault, dll]

Mikeage
sumber
Peringatan ini umumnya sesuai namun mungkin ada situasi di mana Anda ingin melakukan "ini" - selama Anda tahu bahwa string yang Anda berikan akan ditafsirkan sebagai format string.
PP.
2
Saya datang dengan solusi alternatif sekali - salin buffer ke buffer lain dan kemudian pergi melipatgandakan tanda%. Saya akhirnya menemukan ide ini dan mengganti fungsi 20-30 baris dengan satu baris. Jangan khawatir, saya benar-benar memukuli kepala saya sendiri, seperti yang saya layak dapatkan.
Graeme Perrow
Benar, tetapi jangan lupa bahwa 99% dari waktu ketika Anda mendapatkan string format, Anda mendapatkan argumen sebagai va_list, jadi Anda perlu menggunakan vprintf. Jadi, aku teknis benar;)
Mikeage
2
Jauh lebih mudah untuk melakukan put (c). If
William Pursell
1
menempatkan menambahkan baris baru. Itu sering merupakan perilaku yang tidak diinginkan.
Mikeage
33

Jika tidak ada format dalam string, Anda dapat menggunakan puts(atau fputs):

puts("hello%");

jika ada format dalam string:

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

Seperti disebutkan dalam komentar, putstambahkan a \nke output dan fputstidak.

Sinan Ünür
sumber
4
Layak disebutkan fputs () juga, karena langsung membalas fprintf ().
Tim Post
1
put juga menambahkan baris baru [bahkan jika Anda sudah memilikinya]. Jika Anda menginginkannya, bagus. Jika tidak ...
Mikeage
@ Sinan Ünür: terima kasih telah mengingatkan saya tentang puts. Saya tidak pernah berpikir putsuntuk mencetak string dan langsung melompat ke sana printf. Tidak lagi.
Lazer
10

Dengan sendirinya ...

printf("hello%%"); /* like this */
martin clayton
sumber
7

Nitpick:
Anda tidak benar-benar lepas dari %string yang menentukan format untuk keluarga fungsi printf()(dan scanf()).

The %, dalam keluarga fungsi printf()(dan scanf()), memulai spesifikasi konversi. Salah satu aturan untuk spesifikasi konversi menyatakan bahwa %sebagai specifier konversi (segera setelah %yang memulai spesifikasi konversi) menyebabkan '%'karakter ditulis tanpa argumen yang dikonversi.

String benar-benar memiliki 2 '%'karakter di dalamnya (sebagai lawan dari karakter melarikan diri: "a\bc"adalah string dengan 3 karakter bukan nol; "a%%b"adalah string dengan 4 karakter bukan nol).

pmg
sumber
2
secara teknis, masih "melarikan diri"; karakter yang spesial membutuhkan cara untuk "melarikan diri" dari makna khusus mereka dan kembali ke "sifat karakter" mereka
ShinTakezou
6

gunakan %% ganda

jldupont
sumber
4

Seperti ini:

printf("hello%%");
//-----------^^ inside printf, use two percent signs together
Salman A
sumber
3

Garis miring terbalik di C digunakan untuk melarikan diri karakter dalam string. String tidak akan mengenali% sebagai karakter khusus, dan oleh karena itu tidak ada jalan keluar yang diperlukan. Printf adalah masalah lain: gunakan %% untuk mencetak satu%.

Ralph M. Rickenbach
sumber
3

Kamu bisa memakai %%:

printf("100%%");

Hasilnya adalah:

100%

Donald Bebek
sumber
3

Anda menggunakan penentu format yang salah yang harus Anda gunakan %%untuk mencetak %. Kode Anda harus:

printf("hello%%");  

Baca lebih lanjut semua penentu format yang digunakan dalam C .

Pankaj Prakash
sumber
2

Yup, gunakan printf ("hello %%"); dan sudah selesai.

Kevin
sumber
2

Anda cukup menggunakan % dua kali, yaitu"%%"

Contoh:

printf("You gave me 12.3 %% of profit");
Md Shahriar
sumber
1

Dobel '%' juga berfungsi di ".Format (...). Contoh (dengan iDrawApertureMask == 87, fCornerRadMask == 0,05): csCurrentLine.Format("\%ADD%2d%C,%6.4f*\%",iDrawApertureMask,fCornerRadMask) ; memberikan nilai yang diinginkan dan diharapkan dari (isi string dalam) csCurrentLine;"% ADD87C, 0,0500 *% "

dindea
sumber