sscanf说明符%[]和缓冲区溢出

GPT*_*nno 1 c embedded scanf

抱歉这个"另一个"sscanf问题,但我通过实验找不到任何解决方案.

这是一个我要解析的字符串,并提取由":"分隔的2个子字符串:

char *str = "tag:R123:P1234";
Run Code Online (Sandbox Code Playgroud)

这个功能完成了这项工作:

char r_value[5];
char p_value[6];
sscanf(str, "tag:%[^:]:%s", r_value, p_value);
// now r_value = "R123" and p_value = "P1234"
Run Code Online (Sandbox Code Playgroud)

但现在我想确保我不会溢出我的接收缓冲区:

sscanf(str, "tag:%[^:]:%5s", r_value, p_value);
// this is good for p_value, if I give something bigger than 5 character long it
// will be truncated, if less than 5 character long, I get it also
Run Code Online (Sandbox Code Playgroud)

但问题是%[]格式:

sscanf(str, "tag:%4[^:]:%5s", r_value, p_value);
// this will be ok if initial r_value is 4 char or less long
// but not OK if more than 4 char long, then it will be truncated,
// but p_value will not be found...
Run Code Online (Sandbox Code Playgroud)

请注意我在嵌入式系统中; 我买不起非常大的缓冲区来提高溢出的限制......

有办法解决我的问题吗?或者我应该对每个字符进行手动循环以手动进行解析?

Iha*_*imi 5

使用此任务更容易 strtok_r

char  r_value[5];
char  p_value[6];
char *token;
char *saveptr;

token = strtok_r(str, ":", &saveptr);
if (token == NULL)
    return; /* there is no ":" in the string so handle failure properly */
token = strtok_r(NULL, ":", &saveptr);
if (token == NULL)
    return; /* no more tokens found so handle failure properly */
strncpy(r_value, token, sizeof r_value);
r_value[sizeof(r_value) - 1] = '\0';
token = strtok_r(NULL, ":", &saveptr);
if (token == NULL)
    return; /* no more tokens found so handle failure properly */
strncpy(p_value, token, sizeof p_value);
p_value[sizeof(p_value) - 1] = '\0';
Run Code Online (Sandbox Code Playgroud)

并且你防止溢出你的r_valuep_value.

唯一额外的事情是你应该复制,str因为strtok_r需要修改它

char *str = "tag:R123:P1234";
Run Code Online (Sandbox Code Playgroud)

改为

char *str = strdup("tag:R123:P1234");
Run Code Online (Sandbox Code Playgroud)

并记住free(str)最后.