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 }

 

你可能感兴趣的:(format)