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读取

 #include <iostream>
#include <stdio.h> using namespace std; int main()
{
int ret = ;
short ip_addr[];
unsigned short port; cout <<"============================================="<<std::endl;
port = ip_addr[] = ip_addr[] = ip_addr[] = ip_addr[] = ;
ret = sscanf("192.168.1.120#8080",
"%hu.%hu.%hu.%hu#%hu",
&ip_addr[],
&ip_addr[],
&ip_addr[],
&ip_addr[],
&port
);
//ret 5, IP 192 168 1 120Port 8080 读取正确
cout <<"ret " <<ret <<
" IP "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" Port "<< port << endl; port = ip_addr[] = ip_addr[] = ip_addr[] = ip_addr[] = ; ret = sscanf(" 192 .168 . 1 .120 # 8080",
"%hu.%hu.%hu.%hu#%hu",
&ip_addr[],
&ip_addr[],
&ip_addr[],
&ip_addr[],
&port
);
//ret 1, IP 192 0 0 0Port 0 读取错误
cout <<"ret " <<ret <<
" IP "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" Port "<< port << endl; cout <<"============================================="<<std::endl; port = ip_addr[] = ip_addr[] = ip_addr[] = ip_addr[] = ;
ret = sscanf("192.168.1.120#8080",
"%hu%*[^.].%hu%*[^.].%hu%*[^.].%hu%*[^#]#%hu",
&ip_addr[],
&ip_addr[],
&ip_addr[],
&ip_addr[],
&port
);
//ret 1 IP 192 0 0 0Port 0 读取错误,因为%*[^.] 是要匹配一个任何一个非.的字符。但192后面就是.
cout <<"ret " <<ret <<
" IP "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" Port "<< port << endl; port = ip_addr[] = ip_addr[] = ip_addr[] = ip_addr[] = ;
ret = sscanf(" 192 .168 . 1 .120 # 8080",
"%hu%*[^.].%hu%*[^.].%hu%*[^.].%hu%*[^#]#%hu",
&ip_addr[],
&ip_addr[],
&ip_addr[],
&ip_addr[],
&port
);
//ret 5, IP 192 168 1 120Port 8080 读取正确
cout <<"ret " <<ret <<
" IP "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" Port "<< port << endl; cout <<"============================================="<<std::endl; port = ip_addr[] = ip_addr[] = ip_addr[] = ip_addr[] = ;
ret = sscanf("192.168.1.120#8080",
"%hu . %hu . %hu . %hu # %hu",
&ip_addr[],
&ip_addr[],
&ip_addr[],
&ip_addr[],
&port
);
//ret 5, IP 192 168 1 120Port 8080 读取正确
cout <<"ret " <<ret <<
" IP "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" Port "<< port << endl; port = ip_addr[] = ip_addr[] = ip_addr[] = ip_addr[] = ;
ret = sscanf(" 192 .168 . 1 .120 # 8080",
"%hu . %hu . %hu . %hu # %hu",
&ip_addr[],
&ip_addr[],
&ip_addr[],
&ip_addr[],
&port
);
//ret 5, IP 192 168 1 120Port 8080 读取正确,format中的空格的匹配输入字符串的任意空格,很好用
cout <<"ret " <<ret <<
" IP "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" "<<ip_addr[] <<" Port "<< port << endl; return ;
}

scanf,sscanf利用format跳过干扰的空格的更多相关文章

  1. 浅析C语言中printf(),sprintf(),scanf(),sscanf()的用法和区别

    printf语法: #include <stdio.h>int printf( const char *format, ... ); printf()函数根据format(格式)给出的格式 ...

  2. scanf/sscanf %[]格式控制串的用法(转)

    scanf/sscanf %[]格式控制串的用法 scanf中一种很少见但很有用的转换字符:[...]和[ ^...]. #include<stdio.h> int main() { ch ...

  3. 利用Format函数格式化时间和日期

    在做机房收费系统的时候,因为需要使用到日期进行查询,所以在数据表中没有使用自动添加日期的功能,而是采用了自定义的格式插入.但由于事先没有对时间转换的格式进行统一,导致后面查询时出现的问题不断. 插入时 ...

  4. 利用skipList(跳表)来实现排序(待补充)

    用于排名的数据结构 一般排序为利用堆排序(二叉树)和利用skipList(跳表)的方式 redis中SortedSet利用skipList(跳表)来实现排序,复杂度为O(logn),利用空间换时间,类 ...

  5. 利用cookies跳过登陆验证码

    前言在爬取某些网页时,登陆界面时经常遇到的一个坎,而现在大多数的网站在登陆时都会要求用户填写验证码.当然,我们可以设计一套机器学习的算法去破解验证码,然而,验证码的形式多种多样,稍微变一下(有些甚至是 ...

  6. 利用java生成带有干扰线的网页验证码图片

    package imageCreate; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import j ...

  7. Android开发之EditText利用键盘跳转到下一个输入框

    以前做项目的时候,从来没考虑过这些.这段时间公司内部用的一款APP,就出现了这个问题,在登录或者注册的时候,点击键盘的回车按钮,可以跳到下一个输入框的功能,这个属性一直也没记住,今天就把自己一直没记过 ...

  8. 利用canvas绘制带干扰线的验证码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. PHP利用微信跳转的Code参数获取用户的openid

    //获取微信登录用户信息function getOpenID($appid,$appsecret,$code){   $url="https://api.weixin.qq.com/sns/ ...

随机推荐

  1. Maven是如何工作的

    Maven的依赖机制能够自动下载依赖文件,并且自动维护.更新版本. 让我们通过一个案例来了解Maven是如何工作的,假如你的系统想用log4j作为日志输出工具,让我们看一下传统做法和Maven做法: ...

  2. AsciiDoc Markup Syntax Summary

    AsciiDoc Markup Syntax Summary ============================== A summary of the most commonly used ma ...

  3. Zookeeper集群和HBase集群

    1.部署Zookeeper集群(hadoop0\hadoop1\hadoop2) 1.1.在hadoop0上解压缩Zookeeper-3.4.5.tar.gz 1.2.执行命令 cp conf/zoo ...

  4. bzoj3955

    首先,最短路不同的两辆车一定不会发生堵塞 对于最短路相同的点,我们把属于最短路径上的边拎出来建图跑最大流即可 然后我TLE了…… 因为很明显建出来图很大,而真正流的流量很小 普通的初始标号都是0的sa ...

  5. UVa 10883 (组合数 对数) Supermean

    在纸上演算一下就能看出答案是:sum{ C(n-1, i) * a[i] / 2^(n-1) | 0 ≤ i ≤ n-1 } 组合数可以通过递推计算:C(n, k) = C(n, k-1) * (n- ...

  6. LA 3890 (半平面交) Most Distant Point from the Sea

    题意: 给出一个凸n边形,求多边形内部一点使得该点到边的最小距离最大. 分析: 最小值最大可以用二分. 多边形每条边的左边是一个半平面,将这n个半平面向左移动距离x,则将这个凸多边形缩小了.如果这n个 ...

  7. Jqgrid入门-使用模态对话框编辑表格数据(三)

            Jqgrid是一个强大的表格插件,它提供了多种方式来编辑数据.这三种方式分别是: Cell Editing——只允许修改某一个单元格内容 Inline Editing——允许在jqGr ...

  8. WebApp开发框架Ionic+AngularJS+Cordova

    目前的手机APP有三类:原生APP.WebAPP.HybridApp:HybridApp结合了前两类APP各自的优点,越来越流行. Ionic Ionic是一个新的.可以使用HTML5构建混合移动应用 ...

  9. Asp.net正则获取html内容

    1.获取div内容 string str = "tt<u>ss</u><div id=\"test\"><div>< ...

  10. android中的ellipsize设置(省略号的问题)

    textview中有个内容过长加省略号的属性,即ellipsize,可以较偷懒地解决这个问题,哈哈~ 用法如下: 在xml中 android:ellipsize = "end"   ...