sscanf一小用法

来源:互联网 发布:无线网络优化设备现状 编辑:程序博客网 时间:2024/04/29 09:28

背景:欲从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字符都读到缓冲区中。

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

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 贞子从电视里爬出来怎么办 2个月的婴儿吓到怎么办 排卵日同房了没避孕怕怀孕怎么办 妻子因为我欺骗她要跟我离婚怎么办 老婆用苹果手机共享我的位置怎么办 孕妇餐后2小时血糖偏高怎么办 孕妇血糖餐后2小时数值高怎么办 股市退市的话股民的钱怎么办 美股股票退市了手里的股票怎么办 坐高铁安检时怕把包包弄坏了怎么办 很贵的包包高铁安检怎么办 如果过高铁安检东西被扣留怎么办 邻居家小孩把我家东西弄坏了怎么办 邻居早上6点放音乐扰民怎么办 隔壁楼邻居天天放音乐很吵怎么办 发现老公在卧室安了摄像头怎么办 憋的尿又没有厕所的时候怎么办 一岁宝宝拉屎总是拉出血怎么办 孩子鼻窦炎鼻子堵有白色鼻涕怎么办 家里阳台上老是有蝙蝠趴着怎么办 空调太冷在空调房里该怎么办 分手了怎么办不要挽回要重新吸引 过敏体质没打疫苗的孩子入学怎么办 遇到不认识的小姐姐问我问题怎么办 小孩孑脖子洛忱了痛怎么办 挤奶把乳腺挤肿了不出奶怎么办 遇到好兄弟在背后捅刀子怎么办 面对出轨还不想离婚的老公怎么办 法院执行局把案划错了不承认怎么办 手机nfc功能被手机壳挡住怎么办 飞信短信登录验证码达到上限怎么办 手机自带短信软件没了怎么办 老婆出轨孩子又3个不知道怎么办 骑电动车摔跤小脚趾疼有点肿怎么办 第一次太疼了有心理阴影了怎么办 天梭机械表调了时间忽然慢怎么办 支付宝信用住到酒店没房间怎么办 拳头打在硬上骨头肿了怎么办 领导决策出现了失误你该怎么办 我的直销团队走到瓶颈了怎么办 孕妇8个月便秘大便带血怎么办