我对上面的解释做了一些扩展,并提供了一些测试用例的可执行解释,以便您查看验证选项。
#include<stdio.h>
#define BUFSZ 4
void PrintLine() { printf("---------------------------\n"); }
int MyIntegerScan(const char* input, int * integer, char * outbuf, size_t outbufSize)
{
char format_str[20];
sprintf(format_str, "%s%d%s", "#%d %n%", outbufSize -1 ,"s%n%*s%n");
//"#%d %n%4s%n%*[^]%n"
// ^----------------'#' Character
// ^-------------' ' Any ammoutn of whitespace
// ^--------------%d Decimal
// ^---------%4s String Limited to 4 charcters, leave space for terminating zero
// ^---^-----^-%n how many characters were read
// ^----%*[^] match anything without storing it
int check0 = 0, check1 = 0, check2 = 0;
printf("input: '%s'\n", input);
*integer = 0;
*outbuf = 0;
int count = sscanf(input, format_str, integer, &check0, outbuf, &check1, &check2);
switch (count)
{
case 0: printf("did not find number and string\n"); break;
case 1: printf("did not find string\n"); break;
case 2: printf("found both\n"); break;
default: printf("unexpected error during scanf\n"); break;
}
if (check1 < check2)
printf("unmatched rest: '%s'\n", input + check1);
if (check1 == check2 && count == 2)
printf("length exactly as expected\n");
if (check1 == check2 && count != 2)
printf("did not fully match\n");
if ((check1 - check0) < (outbufSize - 1) && count >= 2)
printf("length shorter than expected\n");
printf("matched: '%d' '%s'\n", *integer, outbuf);
PrintLine();
return 0;
}
int main()
{
char out[BUFSZ];
int k;
//I want to have only "sizeof(out)" string 'out' to be scanned in the below code.
PrintLine();
MyIntegerScan("#123 abc", &k, out, BUFSZ); //Happy Path
MyIntegerScan("#123 abc", &k, out, BUFSZ); //A lot of whitespace
MyIntegerScan("#123 a", &k, out, BUFSZ); //Input Very Short
MyIntegerScan("#123 a noise", &k, out, BUFSZ); //Input Very Short Followed by noise
MyIntegerScan("#123 abcdefg", &k, out, BUFSZ); //Input Too Long
MyIntegerScan("#123", &k, out, BUFSZ); //Missing Text
MyIntegerScan("# asdf", &k, out, BUFSZ); //Missing Number
return 0;
}