sscanf的行为是不同的

时间:2017-04-20 05:59:32

标签: c scanf

#include <stdio.h>

int main()
{
   char * msg = "Internal power 10. power sufficient. total count 10";
   char * temp = "Internal power %d. power %s. total count %d";
   int v1, v2, ret;
   char str1[64];
   ret = sscanf(msg, temp, &v1, str1, &v2);

   printf("%d\n", ret);
   printf("%d %s %d ", v1, str1 , v2);

   return 0;
}

我想了解为什么sscanf失败以及为什么它无法检索最后一个变量?

2 个答案:

答案 0 :(得分:7)

%s读取空白 - 定界字符串;也就是说,它在点到点时消耗sufficient.,格式的其余部分". total count %d"与剩余的" total count 10"不匹配。

由于您希望.跟随该字词,因此您最好使用%63[^.],即的最多63个字符包含一个点。或者%63[a-z]最多63个ASCII小写字母 - 明确指定宽度也可以确保缓冲区溢出不会发生:

char * temp = "Internal power %d. power %63[^.]. total count %d";

P.S。总是检查*scanf的返回值 - 它告诉我们匹配了多少个说明符(在这种情况下它应该是3);但是,现在返回2意味着第二次转换后匹配失败。

答案 1 :(得分:3)

问题是scanf格式字符串的这一部分:"power %s."

问题是因为scanf格式字符串不是真正的正则表达式或以其他方式进行精确匹配。当您使用"%s"格式时,scanf(及其兄弟姐妹)将读取所有内容,直到下一个空格。

这意味着使用"%s"字符串会导致sscanf来电显示"sufficient." ,包括点。然后,呼叫将尝试匹配已经读入字符串的点,并且由于它不再可用,呼叫将失败。

您可以按照Jonathan Leffler in his comment的建议使用套装。我还建议你阅读,例如this scanf (and family) reference了解更多详情。