c中的sscanf函数用法

时间:2012-09-13 03:55:33

标签: c scanf

我正在尝试使用xxxxxx(xxxxx)解析sscanf格式字符串,如下所示:

sscanf(command, "%s(%s)", part1, part2)

但似乎sscanf不支持此格式,因此part1实际上包含整个字符串。

任何人都有这方面的经验请分享......

谢谢

3 个答案:

答案 0 :(得分:7)

将代码转换为程序:

#include <stdio.h>

int main(void)
{
    char part1[32];
    char part2[32];
    char command[32] = "xxxxx(yyyy)";
    int n;

    if ((n = sscanf(command, "%s(%s)", part1, part2)) != 2)
        printf("Problem! n = %d\n", n);
    else
        printf("Part1 = <<%s>>; Part2 = <<%s>>\n", part1, part2);
    return 0;
}

运行时会生成“Problem! n = 1”。

这是因为第一个%s转换说明符会跳过前导空格,然后扫描“非空白”字符,直到下一个空格字符(或者,在本例中为字符串结尾)。 / p>

您需要使用(否定的)字符类或 scansets 来获得所需的结果:

#include <stdio.h>

int main(void)
{
    char part1[32];
    char part2[32];
    char command[32] = "xxxxx(yyyy)";
    int n;

    if ((n = sscanf(command, "%31[^(](%31[^)])", part1, part2)) != 2)
        printf("Problem! n = %d\n", n);
    else
        printf("Part1 = <<%s>>; Part2 = <<%s>>\n", part1, part2);
    return 0;
}

这会产生:

Part1 = <<xxxxx>>; Part2 = <<yyyy>>

注意31的格式;它们可以防止溢出。


  

我想知道%31是如何运作的。它是否以%s的形式工作并防止溢出或仅防止溢出?

使用给定的数据,这两行是等效的,并且足够安全:

    if ((n = sscanf(command, "%31[^(](%31[^)])", part1, part2)) != 2)
    if ((n = sscanf(command, "%[^(](%[^)])", part1, part2)) != 2)

%[...]表示法是转换规范; %31[...]也是如此。

C标准说:

  

每个转换规范都由字符%引入。   在%之后,以下顺序出现:

     
      
  • 可选的赋值抑制字符*。
  •   
  • 大于零的可选十进制整数,指定最大字段宽度   (字符)。
  •   
  • 可选的长度修饰符,用于指定接收对象的大小。
  •   
  • 转换说明符字符,指定要应用的转换类型。
  •   

31是(可选)最大字段宽度的示例。 [...]部分是 scanset ,它可能被视为s转换说明符的特例。 %s转化说明符大致相当于%[^ \t\n]

31比字符串的长度少一个;最后的空值不计入该长度。由于part1part2均为32 char的数组,因此%31[^(]%31[^)]转换说明符可防止缓冲区溢出。如果第一个字符串在(之前超过31个字符,则由于文字左括号不匹配,因此返回值为1。同样,第二个字符串将限制为31个字符,但您无法轻易判断)是否在正确的位置。

答案 1 :(得分:2)

如果您确切知道“命令”的各个部分有多长,那么最简单的选项是:

sscanf(command, "%6s(%5s)", part1, part2);

这假定'part1'总是6个字符长,'part2'总是5个字符长(如代码示例中所示)。

答案 2 :(得分:1)

请改为尝试:

#include <stdio.h>

int main(void)
{
  char str1[20];
  char str2[20];
  sscanf("Hello(World!)", "%[^(](%[^)])", str1, str2);
  printf("str1=\"%s\", str2=\"%s\"\n", str1, str2);
  return 0;
}

输出(ideone):

str1="Hello", str2="World!"