2012年1月14日 星期六

scanf整理

最近寫了很多檔案處理的程式,涉及許多字串中,包含數字符號、跳行的內容,不斷的看許多scanf的相關文件,把它整理在這裡,供大家參考。

註:你還在用iostream的cin,cout嗎?我是覺得<cstdio>的scanf, printf比較好用

scanf簡單來說就是格式化輸入,使用上長這樣:
int scanf(format, argument pointer list)
int fscanf(FILE* , format, argument pointer list)
int sscanf(char *, format, argument pointer list)

這裡集中在format要怎麼寫:

基本規則:
空白字元:tab、\n,match到任意字元的空白、tab、\n、none
一般字元:一定要全部match
%後為特殊字元,需要在argument pointer list中有相對應的pointer

基本規則就這麼簡單,那看一下%的規則:
%的規則,基本上是'%' '*' 'n' 'modifier' 'type'

其實* n modifier是選擇性的,先看type的選項:
type 輸入 argument
% 輸入一個%字元

d Signed decimal Int *
i Signed/unsigned decimal,輸入以'0x'為首則以16進位讀入,以0為首則以8進位讀入
ex: scanf(“%i”,&a),輸入0x10a=16
Int *
oux 8/10/16進位讀入unsigned int
試驗結果,用unsigned也會過,但輸入-2,輸出就變成4294967294
Int *
fegE 輸入為 float Float *
s 輸入到字串,直到空白字元出現,注意後面的char*一定要有足夠的空間(先malloc),據說很多安全問題都是這種溢位造成,因此也有人要求用其他函數代替 char*
c 輸入到字元 Char*
p 輸入到pointer位置 void
n Nothing is expected,還不清楚怎麼用,一般好像也用不到

[] 這個厲害,match[]中的任意字元
配合正規表示的^,表示,match到除了[]裡的字元
例如:%[a-z]表示matcha-z中任意字元
%[^aeiou1-9]表示match到並非aeiou19字元
Char *


決定這筆資料是否要存入argument
n 數字,決定要讀入多少個char

舉例:
如果我寫:
int a;
scanf(“%d”); //runtime error, 讀入東西沒地方存,seg fault
scanf(“%d”, a); //runtime error, 是&a,這很容易忘記

正確是:
scanf(“%d”, &a);
scanf(“%*d”); //OK,讀入的數字就dump掉
scanf(“%3d”,&a); //輸入4444,a=444

搭配上面的[],scanf就變得超強大
比如說常有人問要如何換行?
其實只要scanf(“%[^\n]\n”),就是換一行。
modifier的內容:
modifier決定讀入的資料要如何儲存,以下是modifier的選項,不過除了lL以外,好像也不常用(?):
h Typed,i,o,u,x,X,指定存入short int
hh 指定存入char 中,還不清楚詳細內容
j C99 standard,存入intN_t
l Efg存入doublediouxX存入long
L Efg存入long doublediouxX存入long long
t C99 standard,存入ptrdiff_t(這蝦毀)
z C99 standard,存入size_t