背景:欲从FTP服务器下载一文件,须知其大小,使用SIZE命令无效(该命令在RFC959中未出现,即非标准命令)。经测试发现RETR命令返回的信息中包含了文件大小,即字节数,现需要将其从字符串中解析出来。

PS:本人是写代码的,并非使用工具的。

信息如:"150 Opening BINARY mode data connection for latelee.dat (29068 bytes)\r\n\0"

后面写出“\r\n\0”没其它意思,只表明该命令以\r\n结尾,为一正常字符串(以'\0'结束)。

方法1:逐一解析该字符串,遇到左括号作一标志,遇到右括号作一标志,中间者即为我们所需要字符串,再从中解析出数字。示意代码(示意而已,非实际用中)如下:

for (int i = 0; foo[i] != '\0'; i++)
    {
        if (foo[i] == '(')
        {
            do {
            buf[j++] = foo[i++];

} while (foo[i] != ')');
            buf[j++] = '\0';
        }
    }

方法2:使用字符串操作函数,示意代码如下:

char buf1[32];
    char *p1, *p2;
    p1 = strchr(foo, '(') + 1;
    p2 = strchr(foo, ')') -1;
    strncpy(buf1, p1, p2-p1);
    buf1[p2 - p1] = '\0';

方法3:使用sscanf函数,这个函数很早就留意到了,只是没使用它的高级用法。所谓高级者,大部分时间不使用,一旦使用到,便觉得神奇,正如某人低调刻苦研究,不为人所知,突然搞出一重大成果,便一举成名。

关于sscanf函数,网上有资料,不过绝大部分都基本同一版本演绎,以“sscanf用法”为关键字google即可找到多篇相同文章。此处结合前面提出的问题说一下我对它的理解(其实没有理解,只使用它解决问题而已)。

示意代码如下:

char foo[] = "150 Opening BINARY mode data connection for latelee.dat (29068 bytes)";
    char buf[32];
    int size = 0;

sscanf(foo, "%*[^(](%s[^)]", buf);
    sscanf(foo, "%*[^(](%d[^)]", &size);
其中buf为一数组,size为整型(不是整形)类型。结果都能输出29068,前者是一个字符串,后面的是整型数据。buf实际数据为"29068\0",以'\0'结束,可放心使用。

sscanf似乎是以单词为单位,本来是输出"29068 bytes”然而后面的bytes并没有存储到buf中,“%*[^(]”表示过滤掉“(”前面所有字符,直到遇到“(”为止,%s与%d分别表示以字符串、整型存储,注意它们前面还有一个“(”,这个是必须的,不然会被识别为"(29068"的,后面的“[^)]”表示直到遇到右括号“)”为止——不过似乎改写成“[^ ]”更好一些,即遇到空格符号为止。

此法针对某一固定格式的字符串,个人认为使用sscanf还是挺好的,虽然没有比较过上面几种方法的效率,但个人更喜欢使用sscanf函数。

2013-05-09补记:

最近又遇到需要使用sscanf的情况,下面简单写一下。

问题:uboot在启动时需要写日志,该日志存放到EEPROM,并且带有时间信息,现在为了处理时间,需要将时间信息解析出来。

方法:使用scanf一一解析出时间及其它信息。

举例:

int year, month, day, hour, min, sec;

char p[] = "2000-01-01 01:35:02:come on!! hello world!!!";
    char tmp[128] = {0};

printf("org: %s\n", p);
    sscanf(p, "%04d-%02d-%02d %02d:%02d:%02d%[ -~]", &year, &month, &day, &hour, &min, &sec, tmp);

//strcpy(tmp, p + 19);
    printf("%04d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, min, sec);
   
    year += 1;
    day += 1;

sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d%s", year, month, day, hour, min, sec, tmp);
    printf("new: %s\n", p);

结果:

org: 2000-01-01 01:35:02:come on!! hello world!!!
2000-01-01 01:35:02
new: 2001-01-02 01:35:02:come on!! hello world!!!

说明:主要遇到的问题是如何解析时间后面的字符串,因为这个字符串有空格,所以scanf不用直接用%s。上面的方法是%[ -~],把所有的打印的ASCII字符都读到缓冲区中。

至于为什么要这样做,后面有空再写篇文章出来。

sscanf一小用法相关推荐

  1. 字符串处理函数:sscanf 的用法

    前言: 一直对于一些日期字符串中数字的提取比较头疼,现看到 sscanf 对于字符串中的内容提取较方便,学习记录如下.方便以后查询. sscanf():将 C 语言字符串中数据按 指定的格式 将数据存 ...

  2. ATS中用到的sscanf高级用法说明

    ATS使用sscanf函数主要用来解析配置文件,或者提取出要用到的数据类型的值,比较方便,大家可以使用SourceInsight来搜索sscanf用到的地方,这里补充一些sscanf的知识,方便自己更 ...

  3. [转载].sscanf的用法

    原作者不详. 名称: sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: Int sscanf( string str, string fmt, mixed var1, mix ...

  4. sscanf高级用法级正则表达式

    sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源. 函数原型: int scanf( const char *format [,argume ...

  5. C语言中 sscanf 的用法

    名称: sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型:Int sscanf( string str, string fmt, mixed var1, mixed var2 ...

  6. sscanf简单用法

    ssacnf:从一个字符串中读进与指定格式相符的数据(百度百科) 上面只是简单的用法,sscanf还能进行字符和数字的分割. #include<iostream> using namesp ...

  7. C语言函数sscanf()的用法

    转自 http://www.cnblogs.com/lyq105/archive/2009/11/28/1612677.html sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原 ...

  8. %d 跟%i 的区别以及scanf和sscanf的用法

    scanf 用%i能够获得8/16进制的值, 比如0011就是9,0x11就是17,当然如果读取到08或者09就会出错了. scanf简介 scanf函数,与printf函数一样,都被定义在stdio ...

  9. sscanf函数用法详解

    sscanf() - 从一个字符串中读进与指定格式相符的数据.  函数原型:  Int sscanf( string str, string fmt, mixed var1, mixed var2 . ...

最新文章

  1. javax.naming.NoInitialContextException: Need to specify class name in environment or system property
  2. When 多模态 meets 信息抽取
  3. Druid 数据源连接池配置
  4. 跟燕十八学习PHP-第十五天-php增删改查表数据
  5. android activity切换动画
  6. 【自定义控件】自定义属性
  7. 使用Arquillian,Docker和Selenium使Web UI测试再次变得出色(第1部分)
  8. echarts 卡_图表太丑怎么破,ECharts神器带你飞!
  9. 神经网络学习历程与总结
  10. Judy Beta 第10天
  11. python 速成学堂_Python 与数据科学入门
  12. java scriptengine e-_Java使用ScriptEngine(javax.script)
  13. linux输入过的命令行,LINUX中命令行的历史记录和编辑
  14. Cholesky分解法
  15. 嗨,你真的懂this吗? 1
  16. 6.29--6.30郭天祥老师课程中的一些错误与我的存疑
  17. Matlab坐标轴标签中文设置宋体,英文设置新罗马字体(Times New Roman)
  18. Rhino学习教程——1.4
  19. BASIS ADM 100标准课程中文版本
  20. 如何连接Access数据库

热门文章

  1. 宇通客车大型客车销量同比增长12.50%
  2. 这就是即将发布的苹果刘海屏MacBook Pro样机?
  3. 本田电动SUV Prologue拟2024年上市销售 初始年销售目标7万辆
  4. OLED屏智能手机在出货量方面仍未占据主导地位 但预计今年将接近40%
  5. 号称36个月不卡顿!网友:就是有点贵
  6. 阿里巴巴牵手上汽集团:成立汽车科技公司
  7. 华为技术有限公司申请“荣耀视频”、“荣耀钱包”等商标
  8. 安卓“新皇”来了!华为Mate 40确定10月22日发布
  9. 华为手机安卓系统可能停更,鸿蒙系统手机要来了
  10. B 站 Up主自制秃头生成器,圆你一个秃头梦?