用了一點時間作讀取配置部分的代碼,但願一次記錄上讀取N個數據,linux
但願讀取的格式就是一個IP地址加上端口號,但願把IP地址讀取到4個短整數裏面,端口號讀取到另外的一個短整數。文字格式相似「192.120.1.120#8080」,但結果發現由於爲了對齊,中間的空格干擾了讀取。ios
讀取的輸入多是這樣「192.120.1.120 # 8080」,甚至多是 " 192 .168 . 1 .120 # 8080 "測試
鬱悶。google +MSDN,發現其實能夠就用scanf,sscanf繞過。最後選擇的format 是"%hu . %hu . %hu . %hu # %hu",請注意中間的空格。google
參考文檔:spa
http://www.cplusplus.com/reference/cstdio/scanf/ 此文檔寫的很細緻。
.net
http://linux.die.net/man/3/sscanfcode
另外發現scanf 還具備比較簡單的正則能力。處理不少格式化內容其實仍是挺方便的。(原來土鱉都是過濾掉空格的。)orm
下面是本身測試本身測試的例子,還走了一下彎路,先覺得用正則能夠搞點,結果發現正則的寫法仍是不如空格過濾好用。blog
scanf的format字符串:ip
空格:也會一樣去過濾輸入字符串的空格,並且會持續過濾,直到不是空格爲止。(空格也包括tab,回車等)
其餘字符,(不包括%):會一樣在輸入字符裏面跳過想用的字符。
%:控制輸入一個字段,根據後面的長度,控制符讀取數據內容。好比%d等。
%*:會跳過一個輸入字段,好比sscanf("123 456","%*d %d",&data); data讀取會是456;
%[0-9]:貪婪的讀取0-9的字符,做爲一個string讀取
%[^0-9]:貪婪的讀取非0-9的字符,做爲一個string讀取
1 #include <iostream> 2 #include <stdio.h> 3 4 using namespace std; 5 6 int main() 7 { 8 int ret = 0; 9 short ip_addr[4]; 10 unsigned short port; 11 12 cout <<"============================================="<<std::endl; 13 port = ip_addr[0] = ip_addr[1] = ip_addr[2] = ip_addr[3] = 0; 14 ret = sscanf("192.168.1.120#8080", 15 "%hu.%hu.%hu.%hu#%hu", 16 &ip_addr[0], 17 &ip_addr[1], 18 &ip_addr[2], 19 &ip_addr[3], 20 &port 21 ); 22 //ret 5, IP 192 168 1 120Port 8080 讀取正確 23 cout <<"ret " <<ret << 24 " IP "<<ip_addr[0] <<" "<<ip_addr[1] <<" "<<ip_addr[2] <<" "<<ip_addr[3] <<" Port "<< port << endl; 25 26 27 port = ip_addr[0] = ip_addr[1] = ip_addr[2] = ip_addr[3] = 0; 28 29 ret = sscanf(" 192 .168 . 1 .120 # 8080", 30 "%hu.%hu.%hu.%hu#%hu", 31 &ip_addr[0], 32 &ip_addr[1], 33 &ip_addr[2], 34 &ip_addr[3], 35 &port 36 ); 37 //ret 1, IP 192 0 0 0Port 0 讀取錯誤 38 cout <<"ret " <<ret << 39 " IP "<<ip_addr[0] <<" "<<ip_addr[1] <<" "<<ip_addr[2] <<" "<<ip_addr[3] <<" Port "<< port << endl; 40 41 42 cout <<"============================================="<<std::endl; 43 44 port = ip_addr[0] = ip_addr[1] = ip_addr[2] = ip_addr[3] = 0; 45 ret = sscanf("192.168.1.120#8080", 46 "%hu%*[^.].%hu%*[^.].%hu%*[^.].%hu%*[^#]#%hu", 47 &ip_addr[0], 48 &ip_addr[1], 49 &ip_addr[2], 50 &ip_addr[3], 51 &port 52 ); 53 //ret 1 IP 192 0 0 0Port 0 讀取錯誤,由於%*[^.] 是要匹配一個任何一個非.的字符。但192後面就是. 54 cout <<"ret " <<ret << 55 " IP "<<ip_addr[0] <<" "<<ip_addr[1] <<" "<<ip_addr[2] <<" "<<ip_addr[3] <<" Port "<< port << endl; 56 57 58 port = ip_addr[0] = ip_addr[1] = ip_addr[2] = ip_addr[3] = 0; 59 ret = sscanf(" 192 .168 . 1 .120 # 8080", 60 "%hu%*[^.].%hu%*[^.].%hu%*[^.].%hu%*[^#]#%hu", 61 &ip_addr[0], 62 &ip_addr[1], 63 &ip_addr[2], 64 &ip_addr[3], 65 &port 66 ); 67 //ret 5, IP 192 168 1 120Port 8080 讀取正確 68 cout <<"ret " <<ret << 69 " IP "<<ip_addr[0] <<" "<<ip_addr[1] <<" "<<ip_addr[2] <<" "<<ip_addr[3] <<" Port "<< port << endl; 70 71 cout <<"============================================="<<std::endl; 72 73 port = ip_addr[0] = ip_addr[1] = ip_addr[2] = ip_addr[3] = 0; 74 ret = sscanf("192.168.1.120#8080", 75 "%hu . %hu . %hu . %hu # %hu", 76 &ip_addr[0], 77 &ip_addr[1], 78 &ip_addr[2], 79 &ip_addr[3], 80 &port 81 ); 82 //ret 5, IP 192 168 1 120Port 8080 讀取正確 83 cout <<"ret " <<ret << 84 " IP "<<ip_addr[0] <<" "<<ip_addr[1] <<" "<<ip_addr[2] <<" "<<ip_addr[3] <<" Port "<< port << endl; 85 86 87 port = ip_addr[0] = ip_addr[1] = ip_addr[2] = ip_addr[3] = 0; 88 ret = sscanf(" 192 .168 . 1 .120 # 8080", 89 "%hu . %hu . %hu . %hu # %hu", 90 &ip_addr[0], 91 &ip_addr[1], 92 &ip_addr[2], 93 &ip_addr[3], 94 &port 95 ); 96 //ret 5, IP 192 168 1 120Port 8080 讀取正確,format中的空格的匹配輸入字符串的任意空格,很好用 97 cout <<"ret " <<ret << 98 " IP "<<ip_addr[0] <<" "<<ip_addr[1] <<" "<<ip_addr[2] <<" "<<ip_addr[3] <<" Port "<< port << endl; 99 100 return 0; 101 }