scanf格式忽略不相关的字符

Joh*_*nes 4 c scanf string-formatting

我写了一个简短的示例代码来说明我的问题

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

unsigned parseAndCompareDouble(const char* inSTR, const char* inF, const char * expect, const char * outF){
    unsigned e = 0;
    char buffer[2000];
    double a = 0;
    if( 1 != sscanf_s( inSTR, inF, &a, sizeof(double) ) ) e += 1;
    if( (int) strlen(expect) != sprintf_s(buffer, 2000, outF, a) ) e += 1;
    if( 0 != strcmp(expect, buffer) ) e += 1;
    return e;
}

unsigned main( void )
{
    unsigned e = 0;
    const char * universalFormat = "X/%lf";

    e += parseAndCompareDouble("X/100", universalFormat, "X/100", "X/%3.0lf");
    e += parseAndCompareDouble("     X/100\r\n", universalFormat, "X/100", "X/%3.0lf");
    e += parseAndCompareDouble("     X/99\r\n", universalFormat, "X/99", "X/%2.0lf");
    e += parseAndCompareDouble("     X / 99 ", universalFormat, "X/99", "X/%2.0lf");
    e += parseAndCompareDouble("X/99", universalFormat, "X/99", "X/%2.0lf");
    e += parseAndCompareDouble("     \"X/100\"\r\n", universalFormat, "X/100", "X/%3.0lf");  

    if( 0 != e ){ printf( "%2u errors occured\n", e ); }
    else{ printf( "all pass\n", e ); }
    return e;
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个universalFormat让我的示例夹具通过测试.我试图摆弄,%*s但我只是没有得到它.我错过了一些概念.

有人可以提供universalFormat适合这个例子的解释并解释如何到达那里.

jxh*_*jxh 6

您可以使用以下格式:

const char * universalFormat = "%*[^/]/%lf";
Run Code Online (Sandbox Code Playgroud)

%*[^/]告诉scanf忽略的一切,是不是/.我假设你的sscanf_s功能会理解它,虽然我无法自己验证.这是工作程序(略有修改).


Daniel Fischer提请我注意,这些sscanf_ssprintf_s功能在C标准2011(C11)的附录K中定义.我提出了一个关于它与一致性的关系的问题.


知道"X /"字符串中的字符对我来说很重要.

看起来你正试图用来sscanf解析自由形式的输入,这实际上不是它的强项.如果您愿意更改解析代码,可以使用格式字符串的修改版本来完成此任务:

const char * universalFormat = "%[^/]/%lf";
Run Code Online (Sandbox Code Playgroud)

现在,您的解析代码需要更新以读取与说明符对应的字符串%[^/],然后您可以对其进行一些简单的扫描以确保它符合您的要求.

char xbuffer[2000];
const char *xp;
/*...*/
if( 2 != sscanf_s( inSTR, inF, xbuffer, sizeof(xbuffer), &a, sizeof(a) ) ) e += 1;
if( (xp = strrchr(xbuffer, 'X')) == 0 || strcspn(xp, "X \t") != 0 ) e += 1;
Run Code Online (Sandbox Code Playgroud)

  • 这些似乎是标准附件K中的(可选)功能.(例如glibc没有实现它们[还是?],所以它们不是很便携.)如果它们是,它们理解与`_s`-less版本相同的格式. (2认同)