我想在下面的代码中只扫描“sizeof(out)”字符串'out'。 'input'字符串可能不仅仅是out,因此out可能会产生溢出。格式字符串也可以使用sprintf / snprintf完成。
#include<stdio.h>
#define BUFSZ 4
int main()
{
char input[16]="#123 abcdefg";
int k;
char out[BUFSZ];
sscanf(input,"#%d %s",&k,out);
/* Something like %ns where n is the size of out in above line */
printf("%d\n",k);
printf("%s\n",out);
return 0;
}
答案 0 :(得分:2)
#include<stdio.h>
#define BUFSZ 4
#define _S(x) #x
#define S(x) _S(x)
int main(void){
char input[16]="#123 abcdefg";
int k;
char out[BUFSZ+1];
sscanf(input,"#%d %" S(BUFSZ) "s",&k,out);//field size -1 for End Of String(\0)
printf("%d\n",k);
printf("%s\n",out);
return 0;
}
答案 1 :(得分:0)
您需要创建另一个字符串,用作sscanf的格式字符串。这允许您将字符串大小(BUFSZ)插入格式字符串。
char format_str[20];
sprintf(format_str, "#%%d %%%ds", BUFSZ - 1);
sscanf(input,format_str,&k,out);
答案 2 :(得分:0)
我对上面的解释进行了一些扩展,并提供了一些可执行的解释和一些测试用例,以便您查看验证选项。
#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;
}