2009-09-13 30 views
9

Soy un novato en busca de una manera rápida y fácil de analizar un archivo de texto en C o C++ (wxWidgets)archivo de configuración Analizar en C/C++

El archivo se verá algo como esto (una categoría principal con "subobjetos") que aparecerá en un cuadro de lista

[CategoryA] 

[SubCat] 

    Str1 = Test 

    Str2 = Description 

[SubCat] [End] 

[SubCat] 

    Str1 = Othertest 
... 

[CategoryA] [End] 

¿Alguna sugerencia?

+0

Si escribe su propio formato que probablemente tiene que escribir su propio analizador. Ver http://stackoverflow.com/questions/1669/learning-to-write-a-compiler – dmckee

Respuesta

14

Parece que quiere analizar un archivo que está muy cerca de un archivo ini.

Hay al menos algunas bibliotecas de analizadores INI: minIni, iniParser, libini, por ejemplo.

0

¿Qué tal si tratamos de hacer un archivo XML simple? Hay muchas bibliotecas que pueden ayudarlo a leerlo, y la ventaja adicional es que muchos otros programas/idiomas también pueden leerlo.

+0

He encontrado que la sobrecarga no es necesariamente el análisis sintáctico, sino el enlace de los archivos xml a los datos que no vale la pena el esfuerzo de los archivos de configuración simple . Si tienes algo que crea los enlaces, es una cuestión diferente. –

1

Parece más sencillo implementar su propio analizador que tratar de adaptar uno existente con el que no está familiarizado.

Su estructura parece, por su ejemplo, estar basada en línea. Esto hace que analizarlo sea más fácil.

Por lo general, tiene sentido cargar su archivo en un árbol y luego caminar alrededor de él según sea necesario.

1

En Windows solamente, GetPrivateProfileSection hace esto. Está obsoleto a favor del registro, pero aún está aquí y todavía funciona.

13

Debería ser bastante fácil escribir su propio analizador si utiliza secuencias. Se puede leer un archivo usando una std::ifstream:

std::ifstream ifs("filename.ext"); 
if(!ifs.good()) throw my_exceptions("cannot open file"); 
read_file(ifs); 

Puesto que parece línea orientado, usted entonces lea primero las líneas y, a continuación, procesar éstas:

void read_file(std::istream& is) 
{ 
    for(;;) { 
    std::string line; 
    std::getline(is, line); 
    if(!is) break; 
    std::istringstream iss(line); 
    // read from iss 
    } 
    if(!is.eof()) throw my_exceptions("error reading file"); 
} 

Para el análisis real, se pudo 1) primero eche un vistazo al primer personaje. Si es un [, póngalo en la corriente y use std::getline(is,identifier,']') para leer lo que esté dentro de '[' y ']'. Si no es un [, use std::getline(is, key, '=') para leer el lado izquierdo de un par de clave-valor, y luego std::getline(is, value) para leer el lado derecho.

Nota: La entrada del flujo, desafortunadamente, no suele ser muy rápida. (Esto no tiene por qué ser así, pero en la práctica suele ser así.) Sin embargo, es realmente fácil de hacer y es bastante fácil hacerlo bien, una vez que conoces unos pocos patrones para trabajar con sus peculiaridades (como if(strm.good()) no es lo mismo que if(strm) y no es lo opuesto a if(strm.bad()) y algunas otras cosas a las que tendrá que acostumbrarse). Para algo tan crítico para el rendimiento (har har!) Como leer un archivo ini del disco, debería ser lo suficientemente rápido en 999,999 de 1,000,000 de casos.

+2

Tres años más tarde, pero una respuesta muy informativa. Soy bastante nuevo en las transmisiones de archivos y me proporcionó toda la información que necesitaría para hacer un analizador básico sin bibliotecas adicionales (sobre todo, me gusta el argumento getline completo para obtener una cadena entre caracteres específicos). Ojalá pudiera dar más de un +1. –

9

Es posible que desee intentar Boost.Program_Options. Sin embargo, tiene un formato ligeramente diferente. Más cerca de los archivos INI. Las subcategorías se hacen así:

[CategoryA] 
Option = Data 

[CategoryB.Subcategory1] 
Option = Data 

[CategoryB.Subcategory2] 
Option = Data 

También tiene algunas otras características por lo que es realmente muy útil IMO.

0

Si está utilizando wxWidgets, consideraría wxFileConfig. No estoy usando wxWidgets, pero la clase parece admitir categorías con subcategorías.

3

Pruebe el Configurador. Es una biblioteca C++ fácil de usar y flexible para el análisis de archivos de configuración (desde el INI más simple hasta archivos complejos con anidamiento arbitrario y comprobación semántica). Encabezado solo y multiplataforma. Utiliza las bibliotecas Boost C++.

Ver: http://opensource.dshevchenko.biz/configurator