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


274

Bagaimana Anda keluar dari tanda% saat menggunakan printfdi C?

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

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: %%


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]


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.


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


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


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


4

Seperti ini:

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

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%.




2

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


2

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

Contoh:

printf("You gave me 12.3 %% of profit");

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 *% "

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.