sscanf 用法 - 如何验证完成的扫描与中止的扫描 [英] sscanf usage - how to verify a completed scan vs an aborted scan

查看:9
本文介绍了sscanf 用法 - 如何验证完成的扫描与中止的扫描的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的数据库提供了一个文本文件,其中包含打开和关闭 " 来分隔公式.这组公式非常有限,一旦确定就很容易实现.我尝试使用 scanf 来获取参数,我想使用分隔符 " 来提供 scanf 失败的机制.

在下面的示例中,最后一个分隔符被忽略,并且找不到分隔符的信息丢失.我如何控制 sscanf 是否能够匹配整个字符串?

#include <stdio.h>#include <string.h>无符号 printIdentity(const char * 公式){无符号 e = 0,找到 = 0;双a,b;printf("-------------
");printf("调查: %s
", 公式);if( ( ( 2 == sscanf_s( 公式, " " X * %lf %lf " ", &a, &b, sizeof( double ), sizeof( double ) ) ) ){printf("匹配: X * %lf + %lf
", a, b);++找到;}if( ( ( 1 == sscanf_s( 公式, " " X * %lf " ", &a, sizeof( double ) ) ) ){printf("比赛: X * %lf
", a);++找到;}如果(找到!= 1){e += 1;printf("错误: %u 公式类型
", 找到);}printf("-------------
");返回 e;}无符号主(无效){无符号 e = 0;e += printIdentity(" "X*3.1"");e += printIdentity(" "X*3.2-4.2"");e += printIdentity(" "X*3.3+4.3"");if( 0 != e ){ printf( "错误: %2u
", e );}else{ printf("全部通过
", e);}返回 e;}

解决方案

如何控制 sscanf 是否能够匹配整个字符串?

使用格式说明符%n获取处理结束的位置并与输入字符串的长度进行比较,其中n格式说明符定义为(从第 7.19.6.2 节 C99 标准的 fscanf 函数):

<块引用>

不消耗任何输入.对应的参数应该是一个指向要写入的有符号整数 从中读取的字符数到目前为止,通过调用 fscanf 函数得到的输入流.执行一个%n 指令不会增加在fscanf 函数的执行完成.没有参数被转换,但一个被消耗了.如果转换规范包括分配抑制字符或字段宽度,行为未定义.

例如:

#include <string.h>#include <stdlib.h>#include <stdio.h>主函数(){const char* good_input = ""20 21"";const char* bad_input = ""14 12";诠释一个[2];位置;if (sscanf(good_input, " "%d %d"%n", &a[0], &a[1], &pos) == 2 &&pos == strlen(good_input)){printf("good_input: %d %d
", a[0], a[1]);}if (sscanf(bad_input, " "%d %d"%n", &a[0], &a[1], &pos) == 2 &&pos == strlen(bad_input)){printf("bad_input: %d %d
", a[0], a[1]);}}

输出:

<上一页>好输入:20 21

http://codepad.org/6G4lLXWg 上的在线演示.

My database provides a textfile with opening and closing " to delimiter formulas. The set of formulas is very limited and will be easy to implement once identified. I try to use scanf to get the parameters and i want to use the delimiter " to provide a mechanism for scanf to fail.

In the below example the last delimiter is ignored and the information that the delimiter was not found is lost. How can i control if sscanf was able to match the whole string?

#include <stdio.h>
#include <string.h>

unsigned printIdentity(const char * formula){
    unsigned e = 0, found = 0;
    double a, b;
    printf("-------------
");
    printf("INVESTIGATING: %s
", formula);
    if( ( 2 == sscanf_s( formula, " " X * %lf %lf " ", &a, &b, sizeof( double ), sizeof( double ) ) ) ){
        printf("MATCH: X * %lf + %lf
", a, b);
        ++found;
    }
    if( ( 1 == sscanf_s( formula, " " X * %lf " ", &a, sizeof( double ) ) ) ){
        printf("MATCH: X * %lf
", a);
        ++found;
    }
    if( found != 1){
        e += 1;
        printf("ERROR: %u formula types
", found);
    }
    printf("-------------
");
    return e;
}

unsigned main( void )
{
    unsigned e = 0;

    e += printIdentity("     "X*3.1"");
    e += printIdentity("     "X*3.2-4.2"");
    e += printIdentity("     "X*3.3+4.3"");

    if( 0 != e ){ printf( "ERRORS: %2u
", e ); }
    else{ printf( "all pass
", e ); }
    return e;
}

解决方案

How can i control if sscanf was able to match the whole string?

Use the format specifier %n to obtain the position where processing ended and compare with the length of the input string, where the n format specifier is defined as (from section 7.19.6.2 The fscanf function of the C99 standard):

No input is consumed. The corresponding argument shall be a pointer to signed integer into which is to be written the number of characters read from the input stream so far by this call to the fscanf function. Execution of a %n directive does not increment the assignment count returned at the completion of execution of the fscanf function. No argument is converted, but one is consumed. If the conversion specification includes an assignmentsuppressing character or a field width, the behavior is undefined.

For example:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{
    const char* good_input = ""20 21"";
    const char* bad_input = ""14 12";
    int a[2];
    int pos;

    if (sscanf(good_input, " "%d %d"%n", &a[0], &a[1], &pos) == 2 &&
        pos == strlen(good_input))
    {
        printf("good_input: %d %d
", a[0], a[1]);
    }

    if (sscanf(bad_input, " "%d %d"%n", &a[0], &a[1], &pos) == 2 &&
        pos == strlen(bad_input))
    {
        printf("bad_input: %d %d
", a[0], a[1]);
    }
}

Output:

good_input: 20 21

Online demo at http://codepad.org/6G4lLXWg .

这篇关于sscanf 用法 - 如何验证完成的扫描与中止的扫描的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆