寫程式也好一段時間了,老實說一直有個疑問,一般而言函數宣告時,固定數量的參數傳入的函式製作並不難,一定數量內不定數量的參數傳入的函式也不難,但是像 printf 或 scanf 系列的函數,並沒有限定要傳入幾個參數,也不限定傳入參數的形式是什麼,這樣的函數要怎麼實做呢?
2006-09-09 04:59:50 · 1 個解答 · 發問者 Rody 5 in 電腦與網際網路 ➔ 程式設計
感謝 novus, 但您提到 -- 系統固定從 stack 配置 4 個 bytes.. --
這部份讓我疑惑, 如果固定 4 bytes, 那 long long 或 double 或 string 要怎麼處理? 你可以寫個簡易 sprintf 可以丟一個 double 和字串並存到 char buf[80] 裡面的小範例給我看嗎?
2006-09-09 09:23:27 · update #1
感謝, 根據您的範例, 我想確認一下, va_arg(arg, type) 這巨集是否每呼叫一次, arg 就會指向下個引數, 而且不論型別? 那如果型別出錯會怎樣? 如果引數不足又會怎樣?
2006-09-09 18:44:23 · update #2
真是太感謝了, 最後補充兩個小疑問, 第一, 這種 ... 的參數傳遞方式有可能被再次傳遞嗎? 例如我想替 string 類別增加類似 format 功能, 有可能寫個 myformat( string InString,const char *format, ...), 然後在裡面直接把除了第一個以外的引數傳入 sprintf 進行處理嗎? 第二, 你可以另外開個網址寫程式碼給別人看, 這怎麼做到的? 要申請什麼嗎?
最後, 非常感謝您的回答
2006-09-10 07:05:04 · update #3
咦~~有「C++的地下標準程式庫」這東西啊?去哪邊找呢?我就是覺得類似 printf 之類的作法比較簡易, 本來想說如果 string 不提供類似函式, 想要自己來實做了 (其實 MFC 的 CString 和 QT 的 QString 都有類似的東西, 但為了一個格式化就要被這束縛, 感覺很差啊~~)
2006-09-10 10:15:53 · update #4
1.在C語法支援函數宣告中加入"..."來代表不定參數2.在
2006-09-09 16:55:02 補充:
4 byte只是舉個例子,實際上有可能是8 byte或其他,要看環境如何實作對於超過一個單位的型態,可以在va_arg當中作一些處理。例如VC6的stdarg.h實作(可以看出是以sizeof(int)為單位):#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
2006-09-09 17:02:10 補充:
我寫了一個勉強可用sprintf
不過這裡po不下
我另外再想辦法補給你吧
2006-09-09 18:01:40 補充:
http://home.pchome.com.tw/online/snomel/args.htm
2006-09-10 01:36:34 補充:
是的,會指向下個引數
如果你願意研究一下我下午在答案裡所補充的VC6實作,應該會更清楚
gcc的實作很容易取得,雖然寫法不同,道理卻差不多
超過引數數目,就像超出陣列範圍或張君雅小妹妹的泡麵爛掉一樣,C是概不負責。
不過既然發生在stack裡面,大概猜得到是其他函數的區域變數、參數或呼叫返回位址之類的。
如果型態不對,則會將stack裡的二進位值reinterpret
例如0xFFFFFFC4
當成int為-60
當成unsigned int為4294967236
double.....因為有64位元,所以會提取兩倍int大小的記憶體,用IEEE浮點數規則解讀
2006-09-10 13:37:44 補充:
1.再傳遞當然沒有問題,你可以參考標準程式庫裡面的vsprintf
2.std::string雖然缺乏regular expression的相關功能
但C++的string stream也相當夠用了
(1)比C的格式化IO安全(型態在編譯期就確定了)
(2)更有彈性(能和其他物件任意搭配、結合STL的iterator和algorithm作出神奇的應用)
(3)效率更好(理論上...因為不像格式化IO一樣還要剖析格式字串。但似乎還沒有哪家的stream真正超越格式化IO)
(4)至少程式碼比較好看
2006-09-10 13:44:49 補充:
如果你真的非常需要std::string的formatter,可以找有著「C++的地下標準程式庫」頭銜的boost,犯不著自己動手
那只是普通的網頁空間
我的編輯軟體能夠將程式碼輸出成彩色html
2006-09-11 12:58:26 補充:
boost 的 format 程式庫
http://www.boost.org/libs/format/doc/format.html
一個勉強可用的_sprintf
void _sprintf(string &ss, const char *fmt, ...)
{
char buf[80];
va_list arg;
va_start(arg, fmt);
vsprintf(buf, fmt, arg);
va_end(arg);
ss = buf;
}
2006-10-03 17:05:57 補充:
補充
C library對於字串的安全性都不盡理想
這也是許多程式的漏洞所在
終於找到的文章:P
http://www.gotw.ca/publications/mill19.htm
2006-09-09 07:12:35 · answer #1 · answered by novus 6 · 0⤊ 0⤋