scanf,sscanf利用format跳過干擾的空格

scanf,sscanf利用format跳過干擾的空格

用了一點時間作讀取配置部分的代碼,但願一次記錄上讀取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 }
相關文章
相關標籤/搜索