Квадратная скобка убегая] в Sscanf - PullRequest
6 голосов
/ 22 апреля 2011

Я хочу сканировать строки вроде

"[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 ]

11 голосов
/ 22 апреля 2011

Вы хотите

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

Обратите внимание на три последовательных символа ] - первый символ, который вы не хотите использовать в наборе %[, второй конец набора, начинающийся с %[, а третий соответствует ] символ на входе

5 голосов
/ 22 апреля 2011

Как уже упоминали другие ... Я не совсем уверен, что вы хотите сделать здесь ...

Предполагая, что значения в скобках всегда целые, вы можете просто сделать:

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

Если вы действительно настаиваете на использовании регулярных выражений и хотите, чтобы между скобками были переданы какие-то общие элементы, вам нужно:

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

второе регулярное выражение должно соответствовать всемсимволы, кроме ] в конце.Я полагаю, что вы пытались уйти от ] раньше, но это не обязательно, и компилятор выдает ошибку, потому что он не знает, как обработать этот выход.

Есть 3 ] в предложении захвата для a2, потому что первый говорит: «не включать этот символ в набор совпадений символов», второй закрывает набор совпадений символов, а третий соответствует ] в [25, 28] => 34 input.

Если я полностью неправильно понял ваш вопрос, просто уточните, и я могу пересмотреть.

2 голосов
/ 22 апреля 2011

Похоже, ваш вопрос в основном сводится к тому, «как включить символ ] в набор scanf».Это возможно, и вам не нужно избегать этого.Специально для этой цели спецификация языка гласит, что, когда символ ] следует сразу за открывающим символом [ или сразу после открывающего символа ^, ] считается частью набора сканирования, а не закрывающимскобка.Итак, в вашем случае спецификатор формата должен выглядеть как "[%[^,], %[^]]] => %i".Нет \ необходимо.

Я вижу, что вы почти все поняли правильно, за исключением того, что вы забыли третий ] символ после второго набора сканирования.

0 голосов
/ 22 апреля 2011

Для меня это звучит как ошибка компилятора (или библиотеки) (хотя вам нужна третья правая скобка, а не две). Согласно стандарту (C99, §7.19.6.2): ​​

Если спецификатор преобразования начинается с [] или [^], символ правой скобки находится в списке сканирования, а следующий следующий символ правой скобки - это совпадающая правая скобка, которая завершает спецификацию;

0 голосов
/ 22 апреля 2011

можете попробовать

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