2010-08-08 86 views
2

我最近一直在編寫一些基本的命令行程序(我希望在夏天保持我的技能),但printfscanf已經開始困擾着我。我不是一個很棒的C程序員,並且必須進入printf/scanf,他們的不穩定性(甚至更糟,fgets之類)並不完全讓我處於一個令人欣慰的環境中(因爲這個原因,我真的很喜歡NSLog,與其舒適的默認命名空間及其自動NSStringNSObject解析)。我很失望,但是,NSLog沒有對應函數,並在最後打印了大量額外的'垃圾'(時間,函數名等,以及換行符),這會打敗我使用它的目的很多。所以我決定坐下來進行一種不同類型的編程練習,並編寫函數來替換滿足我需求的printf和scanf。Printf/scanf替換方法:一些反饋/建議需要

瞧,我想出了我自己的NSInput.h文件,其中包含兩個函數:NSPrint()NSScan()。這兩個函數在printf和scanf之後建模很多,但也處理NSString's。我知道我在這裏踩着神聖的命名空間,但我無法抗拒(IFPrintIFScan聽起來很糟糕!)。

現在,當我真的很高興,我的工作代碼(你可以找到源here),我知道,這不是有效的(出乎我的意料,不過,NSPrint是幾倍於printf更有效在Xcode 4的LLDB下,但這不在重點)。我需要一些關於如何使功能更好,更高效的建議。例如,NSScan將它收到的va_list轉換爲NSPointerArray,並使用NSScanner來掃描格式和輸入字符串,所以我知道還有很大的改進空間。

基本上,我想知道的是,是否有任何明顯的錯誤,我做了可以並應該修復?我錯過了什麼?我應該只是被稱爲寵壞了,並回到使用printfscanf?請告訴我,我在這裏尋找輸入(雙關語不打算!)...

在此先感謝!

+0

它在類似printf的函數中尋找什麼,你無法使用[NSString stringWithFormat:]? – 2010-08-08 21:42:38

+2

我注意到的一個明顯的遺漏是缺少一個測試套件。 – 2010-08-08 21:44:40

+1

@ Seamus:如果你看看源代碼,那就是我所做的。 @Greg:我以前從來沒有做過測試套件,所以我想現在應該是嘗試的好時機,對吧? 感謝您的回覆! – 2010-08-08 22:47:52

回答

3

我的想法:

  • 不要叫他們NSxxxxx,NS是保留給可可和基金會。
  • 這兩種功能都應修改爲接受FILE*,即您應該將接口建模爲fprintf()fscanf()以獲得更大的靈活性。
  • 你的printf函數可能會更好,如果你使用fputs()

例如

void NSFPrint (FILE* fp, NSString *format, ...) 
{ 
    // Create the variable argument list. 
    va_list args; 
    va_start(args, format); 

    // Using NSString, parse the argument list and convert it to a C string. 
    fputs([[[[NSString alloc] initWithFormat:format arguments:args] autorelease] UTF8String], fp); 
    va_end(args); 
} 
  • 考慮比UTF-8編碼的其他的輸入和輸出加支撐。
  • 您的scanf替代品在stdin上混合了C緩衝IO和Unix unbuffered IO。這可能是不好的。
  • 即使不需要,您的scanf替代品也可以讀取到行尾。我沒有仔細檢查,但是如果掃描格式不會佔用整行,則看起來您正在放棄輸入。這可能是不好的。
+0

感謝您的建議!我會盡快實施它們。 雖然只有一個問題。我使用C緩衝IO和Unix unbuffered IO的意思是什麼,或者至少,我怎樣才能避免這個問題? – 2010-08-09 09:21:31

+0

我已經更新了我的代碼(http://snipt.org/XmL)以反映你的建議(我已經重命名了函數IFPrint和IFScan,它們現在將文件指針作爲參數,IFPrint現在使用'fputs',並且用'fgetc'替換了'read(0,NULL,1)' - 這就是你說的緩衝/無緩衝IO的含義?)。希望我正朝着正確的方向前進。 – 2010-08-09 11:22:48

+2

是的。 read()函數調用是一個Unix系統調用,它直接從文件描述符中讀取,只使用Unix IO調用。 'fgets()'是一個C庫函數,它在'FILE *'上運行。文件指針。文件指針維護一個緩衝區,當這個緩衝區耗盡時,fgets只從物理文件讀取數據。當它讀取時,它會讀入一個大塊。這樣,執行'fgetc()'並不像你想象的那麼低效,因爲大多數時候它從內部緩衝區獲取字符。 – JeremyP 2010-08-09 13:24:29