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


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

用了一點時間做讀取配置部分的代碼,希望一次記錄上讀取N個數據,

希望讀取的格式就是一個IP地址加上端口號,希望把IP地址讀取到4個短整數里面,端口號讀取到另外的一個短整數。文字格式類似“192.120.1.120#8080”,但結果發現因為為了對齊,中間的空格干擾了讀取。

讀取的輸入可能是這樣“192.120.1.120   #     8080”,甚至可能是 " 192 .168 . 1 .120 # 8080 "

郁悶。google +MSDN,發現其實可以就用scanf,sscanf繞過。最后選擇的format 是"%hu . %hu . %hu . %hu # %hu",請注意中間的空格。

參考文檔:

http://www.cplusplus.com/reference/cstdio/scanf/   此文檔寫的很細致。

http://linux.die.net/man/3/sscanf

 

另外發現scanf 還具有比較簡單的正則能力。處理很多格式化內容其實還是挺方便的。(原來土鱉都是過濾掉空格的。)

下面是自己測試自己測試的例子,還走了一下彎路,先以為用正則可以搞點,結果發現正則的寫法還是不如空格過濾好用。

scanf的format字符串:

空格:也會同樣去過濾輸入字符串的空格,而且會持續過濾,直到不是空格為止。(空格也包括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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM