在sscanf中逃离方括号]

时间:2011-04-21 22:34:42

标签: c parsing escaping scanf format-specifiers

我想扫描像

这样的行
"[25, 28] => 34"

我写了一个小程序来测试它:

#include <cstdlib>
#include <iostream>

int main() {
        char* line = "[25, 28] => 34";
        char a1[100],  a2[100];
        int i;
        sscanf(line, "[%[^,], %[^\]] => %i", a1, a2, &i);
        std::cout << "a1 = " << a1 <<"\na2 = " << a2 << "\ni = "<<i <<"\n";
        return 0;
}

编译这个给出了

warning: unknown escape sequence '\]'

和输出

a1 = 25
a2 = 28
i = -1073746244

如果我将其更改为

sscanf(line, "[%[^,], %[^]] => %i", a1, a2, &i);

我没有编译器投诉,但仍然

a1 = 25
a2 = 28
i = -1073746244

我知道问题出在第二个令牌中,因为

sscanf(line, "[%[^,], %[0123456789]] => %i", a1, a2, &i);

给出

a1 = 25
a2 = 28
i = 34

但是我想为第二个令牌使用终止条件。我该怎么做?

5 个答案:

答案 0 :(得分:11)

你想要

sscanf(line, "[%[^,], %[^]]] => %i", a1, a2, &i);

注意连续三个]个字符 - 第一个是您不希望在%[集中匹配的字符,第二个字符以%[开头的结尾第三个匹配输入中的]字符

答案 1 :(得分:5)

正如其他人所说......我不确定你想在这做什么......

假设括号之间的东西总是整数,你可以这样做:

int a, b, c;
sscanf(line, "[%d, %d] => %d", &a,&b,&c);

如果您真的坚持使用正则表达式并希望在括号之间传递一些通用的东西,那么您需要的是:

sscanf(line, "[%[^,], %[^]]] => %d", a1, a2, &i);

第二个正则表达式应匹配除]之外的所有字符。我相信你之前试图逃避],但这不是必需的,编译器会抛出一个错误,因为它不知道如何处理这个转义。

]的捕获子句中有3个a2,因为第一个是“不在字符匹配集中包含此字符”,第二个是关闭字符匹配集,第三个与]输入中的[25, 28] => 34匹配。

如果我完全误解了你的问题,请澄清,我可以修改。

答案 2 :(得分:2)

看起来您的问题基本上归结为“如何将]字符包含到scanf扫描集中”。这是可能的,你不需要逃避它。特别是为此目的,语言规范指出当]字符紧跟开始[字符或紧跟开头^字符后,]被认为是扫描组的一部分,而不是结束括号。因此,在您的情况下,格式说明符应该看起来像"[%[^,], %[^]]] => %i"。不需要\

我发现你几乎把它弄好了,除了你忘记了第二个扫描集之后的第三个]字符。

答案 3 :(得分:0)

听起来像编译器(或实际上是库)的错误(虽然你确实需要第三个右括号,而不仅仅是两个)。根据标准(C99,§7.19.6.2):

  

如果转换说明符以[]或[^]开头,则右括号字符位于扫描列表中,下一个右括号字符是结束规范的匹配右括号;

答案 4 :(得分:-2)

你可以尝试

吗?
sscanf(line, "[%s, %s] => %d", a1, a2, &i);