2011-04-21 13 views
6

Quiero escanear líneas comoEscapar de corchetes] en sscanf

"[25, 28] => 34" 

escribí un pequeño programa para probarlo:

#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; 
} 

compilar esto da

warning: unknown escape sequence '\]' 

y la salida

a1 = 25 
a2 = 28 
i = -1073746244 

Si lo cambio a

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

consigo ninguna queja del compilador, pero aún

a1 = 25 
a2 = 28 
i = -1073746244 

Sé que el problema está en el segundo marcador porque

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

da

a1 = 25 
a2 = 28 
i = 34 

Pero quiero usar una condición de terminación para el segundo token. ¿Cómo puedo hacer eso?

Respuesta

10

¿Quieres

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

Nota ] los tres caracteres consecutivos - el primero es el carácter que no desea hacer coincidir en el conjunto %[, el segundo extremos del conjunto a partir de la %[ y la tercera coincide con el carácter ] en la entrada

-2

Se puede tratar

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

-1 no funciona - '% s' coincide con todo hasta el siguiente espacio en blanco, por lo que absorberá el siguiente carácter de puntuación (', 'o'] ') y la coincidencia posterior fallará. –

+0

Dios mío, estoy un poco rezagado ... 8) muy bien votado. – ColWhi

4

Como otros han mencionado ... No estoy seguro de lo que quiere hacer aquí ...

Suponiendo que las cosas entre los paréntesis son siempre números enteros , usted podría hacer:

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

Si usted es realmente insistente sobre el uso de expresiones regulares y con ganas de un poco de materia genérica aprobada en entre los soportes, lo que estás buscando es:

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

la segunda expresión regular debe coincidir con todos los caracteres excepto el ] al final. Creo que antes intentabas escapar del ], pero esto no es necesario y el compilador arroja un error porque no sabe cómo manejar ese escape.

hay 3 ] en la cláusula de captura para a2 porque la primera ya es decir, "no incluye este carácter del conjunto de caracteres partido", el segundo está cerrando fuera del set partido de carácter, y la tercera coincide con el ] en la entrada [25, 28] => 34.

Si he entendido mal tu pregunta, solo aclara y puedo revisar.

0

Me parece un error de compilador (o, de hecho, de biblioteca) (aunque necesitas un tercer corchete a la derecha, no solo dos). De acuerdo con la norma (C99, §7.19.6.2):

Si el especificador de conversión comienza con [] o [^], el carácter soporte derecho está en la lista de exploración y el siguiente carácter siguiente soporte derecho es el soporte derecho a juego que termina la especificación;

2

que parezca su pregunta básicamente se reduce a "cómo incluir el carácter ] en un scanset scanf ". Es posible y no necesitas escapar de él. Específicamente para ese propósito, la especificación del lenguaje indica que cuando el carácter ] sigue inmediatamente al carácter de apertura [ o sigue inmediatamente al carácter de apertura ^, ese ] se considera parte del scanset, no un corchete de cierre. Entonces, en su caso, se supone que el especificador de formato debe verse como "[%[^,], %[^]]] => %i". No es necesario \.

Veo que casi lo hizo bien, excepto que olvidó el tercer carácter ] después del segundo escaneo.