[問題] 關於sprintf格式化 %%%ds的問題

看板C_and_CPP作者 (Ayuang)時間7年前 (2017/04/07 21:14), 編輯推噓9(9019)
留言28則, 8人參與, 最新討論串1/1
問題(Question): 這是在https://openhome.cc/Gossip/AlgorithmGossip/PascalTriangle.htm看到的題目 ,是關於巴斯卡三角形的運算並排列。裡面的程式碼大部分小弟都看得懂,但在sprintf 裡有一個%%%ds的格式化符號實在是不懂它的功能,以前也沒看過這樣子的打法;還請版 上高手能替小弟解答,感激不盡。 程式碼(Code): #include <stdio.h> #define HEIGHT 12 int combi(int r, int n){ int p = 1; int i; for(i = 1; i <= n; i++) { p = p * (r - i + 1) / i; } return p; } int main() { int r; for(r = 0; r < HEIGHT; r++) { char format[5]; sprintf(format, "%%%ds", (HEIGHT - r) * 3); printf(format); int n; for(n = 0; n <= r; n++) { printf("%6d", combi(r, n)); } printf("\n"); } return 0; } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 163.18.30.156 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1491570871.A.B17.html

04/07 21:16, , 1F
%%印出% %d出整數 s就是s
04/07 21:16, 1F

04/07 21:20, , 2F
跟下面那行一起看就是印出(HEIGHT-r)*3個空白
04/07 21:20, 2F

04/07 21:31, , 3F
x000032001 所以%s不給變數的話就會輸出空白嗎?
04/07 21:31, 3F

04/07 22:45, , 4F
唔嗯...我感覺印空白是 UB, 至少也要擺個 ""
04/07 22:45, 4F

04/07 22:50, , 5F
查了一下沒錯, va_arg 在沒參數時硬叫是未定義行為
04/07 22:50, 5F

04/07 22:50, , 6F
原文好像有"" …
04/07 22:50, 6F

04/07 22:50, , 7F
所以正確的寫法應該是 printf(format,"");
04/07 22:50, 7F

04/07 22:51, , 8F
不過這裡其實可以不用這麼間接的方式
04/07 22:51, 8F

04/07 22:51, , 9F
printf 系的格式字串可以在需要數字時放 * 字
04/07 22:51, 9F

04/07 22:51, , 10F
這個 * 字實際上是多少由下一個 int 決定
04/07 22:51, 10F

04/07 22:52, , 11F
所以這裡可以寫 printf("%*s",(HEIGHT-r)*3,"");
04/07 22:52, 11F

04/07 22:52, , 12F
達到一樣的效果
04/07 22:52, 12F

04/07 23:17, , 13F
LPH66 我剛剛有是過去掉print裡的" ",效果一樣
04/07 23:17, 13F

04/07 23:19, , 14F
還是很謝謝兩位為我解答,這打法真的很有意思。
04/07 23:19, 14F

04/07 23:47, , 15F
長知識了 以前都沒注意到有%*s的用法 感謝LPH66大大
04/07 23:47, 15F

04/08 05:05, , 16F
%%%%%%
04/08 05:05, 16F

04/08 23:43, , 17F
長知識
04/08 23:43, 17F

04/09 03:32, , 18F
%.*s 有一個點
04/09 03:32, 18F

04/09 11:42, , 19F
可以不用%.*s , 那個 dot 多用在浮點數,如 %*.*lf
04/09 11:42, 19F

04/09 12:18, , 20F

04/09 12:26, , 21F
有那個的點點才能 truncate 所以 〃*.*s〃 也是對的
04/09 12:26, 21F

04/09 13:20, , 22F

04/09 20:50, , 23F
可以參考這篇文章,寫得很詳細http://curryworld.ga/archi
04/09 20:50, 23F

04/09 20:51, , 24F
這招到還沒用過,謝謝。
04/09 20:51, 24F

04/09 20:51, , 25F

04/10 02:43, , 26F
嗯, 上面推文沒提 . 是因為原文寫法就不是用 . 的
04/10 02:43, 26F

04/10 02:44, , 27F
* 字可以取代數字所以 %*.*s 這個寫法可以直接定死輸出長度
04/10 02:44, 27F

04/10 02:44, , 28F
不論實際上的字串有多長; 原文只是要印空白所以不用 .
04/10 02:44, 28F
文章代碼(AID): #1Ovv2tiN (C_and_CPP)