问题
I wrote a short example code to illustrate my problem
#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;
}
I am looking for a universalFormat
that lets my example fixture pass the test. I tried to fiddle around with %*s
but I just don't get it rigth. I am missing some concept.
Can someone provide the universalFormat
that fits this example and explain how to get there.
回答1:
You can use the following format:
const char * universalFormat = "%*[^/]/%lf";
The %*[^/]
tells scanf
to ignore everything that isn't a /
. I am assuming your sscanf_s
function will understand it, although I am unable to verify that myself. Here's the working program (slightly modified).
Daniel Fischer has brought to my attention that the sscanf_s
and sprintf_s
functions are defined in Annex K of C Standard 2011 (C11). I raised a question about its relation to conformance.
Knowing that
"X /"
is in the string is of importance for me.
It seems you are trying to use sscanf
to parse free-form input, which is not really its forte. If you are willing to change your parsing code, you can use the modified version of the format string to accomplish this:
const char * universalFormat = "%[^/]/%lf";
Now, your parsing code will need to be updated to read in the string corresponding to the %[^/]
specifier, and then you can do some simple scanning on it to make sure it meets your requirements.
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;
来源:https://stackoverflow.com/questions/16696428/scanf-format-to-ignore-irrelevant-characters