Discussion:
estrategia para leer ficheros de properties
(demasiado antiguo para responder)
Q de quilo
2004-10-08 08:58:27 UTC
Permalink
Buenas,
a ver si a alguien se le ocurre la opcion mas correcta de hacer lo
siguiente: leer un fichero de propiedades algo asi como:
-----------------------------
nombre=un nombre cualquiera
loglevel=3
debug=yes

-----------------------------

Si desde un programa C quisieramos leerlo y parsear cada propiedad, que
funciones o que manera de leer el fichero seria la mejor?

En principio se me ocurre leer linea por linea y hacer split con strtok.
Pero quiza no sea la mejor opcion, unido al problema de la deteccion de
final-de-fichero.
Estuve pobrando fscanf("%s=%s") con unos resultados algo desastrosos.
Existe alguna funcion predefinada tipo getopt para estos casos?

Un saludo
Zephryn Xirdal
2004-10-08 12:00:41 UTC
Permalink
Si es bajo Windows tienes todo un grupo de funciones nativas para hacerlo...
si no, la mejor opción es ir leyendo línea a línea y descomponiendola en
pares de tokens, titulo,valor. Una vez que hayas parseado el fichero
completo, haces un scan de lo que quieras... creo que es así como lo hace el
API de windows. La función estándar del C para hacer eso es strtok
--
Las ideas son como las pulgas, saltan de unos a otros, pero no pican a
todos.
-- George Bernard Shaw. (1856-1950) Dramaturgo irlandés.
---Powered by zxFortune http://sourceforge.net/projects/zxfortune
Post by Q de quilo
Buenas,
a ver si a alguien se le ocurre la opcion mas correcta de hacer lo
-----------------------------
nombre=un nombre cualquiera
loglevel=3
debug=yes
-----------------------------
Si desde un programa C quisieramos leerlo y parsear cada propiedad, que
funciones o que manera de leer el fichero seria la mejor?
En principio se me ocurre leer linea por linea y hacer split con strtok.
Pero quiza no sea la mejor opcion, unido al problema de la deteccion de
final-de-fichero.
Estuve pobrando fscanf("%s=%s") con unos resultados algo desastrosos.
Existe alguna funcion predefinada tipo getopt para estos casos?
Un saludo
Zephryn Xirdal
2004-10-08 13:16:59 UTC
Permalink
La función estándar del C para hacer eso es strtok
Quiero decir: "la función estándar del C para ir parseando una cadena es
strtok."
--
Un sutil pensamiento erróneo puede dar lugar a una indagación fructífera que
revela verdades de gran valor.
-- Isaac Asimov. (1920-1992) Escritor y científico estadounidense.
---Powered by zxFortune http://sourceforge.net/projects/zxfortune
Post by Zephryn Xirdal
Si es bajo Windows tienes todo un grupo de funciones nativas para
hacerlo... si no, la mejor opción es ir leyendo línea a línea y
descomponiendola en pares de tokens, titulo,valor. Una vez que hayas
parseado el fichero completo, haces un scan de lo que quieras... creo que
es así como lo hace el API de windows. La función estándar del C para
hacer eso es strtok
--
Las ideas son como las pulgas, saltan de unos a otros, pero no pican a
todos.
-- George Bernard Shaw. (1856-1950) Dramaturgo irlandés.
---Powered by zxFortune http://sourceforge.net/projects/zxfortune
Post by Q de quilo
Buenas,
a ver si a alguien se le ocurre la opcion mas correcta de hacer lo
-----------------------------
nombre=un nombre cualquiera
loglevel=3
debug=yes
-----------------------------
Si desde un programa C quisieramos leerlo y parsear cada propiedad, que
funciones o que manera de leer el fichero seria la mejor?
En principio se me ocurre leer linea por linea y hacer split con strtok.
Pero quiza no sea la mejor opcion, unido al problema de la deteccion de
final-de-fichero.
Estuve pobrando fscanf("%s=%s") con unos resultados algo desastrosos.
Existe alguna funcion predefinada tipo getopt para estos casos?
Un saludo
Martin J. Sanchez
2004-10-09 12:43:40 UTC
Permalink
Post by Q de quilo
Buenas,
a ver si a alguien se le ocurre la opcion mas correcta de hacer lo
-----------------------------
nombre=un nombre cualquiera
loglevel=3
debug=yes
-----------------------------
Si desde un programa C quisieramos leerlo y parsear cada propiedad, que
funciones o que manera de leer el fichero seria la mejor?
En principio se me ocurre leer linea por linea y hacer split con strtok.
Pero quiza no sea la mejor opcion, unido al problema de la deteccion de
final-de-fichero.
Estuve pobrando fscanf("%s=%s") con unos resultados algo desastrosos.
Existe alguna funcion predefinada tipo getopt para estos casos?
Un saludo
Algo parecido es lo que hacen las funciones de windows:
GetPrivateProfileInt()
GetPrivateProfileString()
WritePrivateProfileString()

Por ejemplo, dado un fichero "config.dat" con este formato:
==========================
[Seccion1]
loglevel=1
debug=2

[Seccion2]
loglevel=1
debug=2
===========================
Para obtener el loglevel de Seccion2 harias:
int x= GetPrivateProfileInt( "Seccion2", "loglevel", -1, "config.dat");

Si no estas trabajando en windows, o te interesa crear una aplicacion
portable a otras plataformas, deberas crear tu propia version. Por
ejemplo una version compatible con la funcion GetPrivateProfileInt
podria quedar asi:


/* tamaño maximo de linea en fichero */
#define MAX_LINE_LENGTH 120

/*****************************************************************
int read_line(FILE* fp, char* bp);
fp - puntero a fichero de lectura
bp - puntero a buffer de copia
szbp - tamaño de buffer

Lee una linea de fp dejando un maximo de szbp-1 caracteres en bp
La string dejada en sp siempre termina en '\0'.

Return: 1 OK, 0 en otro caso
******************************************************************/
static int read_line(FILE *fp, char *bp, int szbp)
{
char c = '\0';
int i = 0;

if(!bp || szbp<1 )
return 0;

/* Leer una linea del fichero fuente
* eliminando \n en final de linea
*/
for( i=0; i<szbp-1 && (c = getc(fp)) != '\n'; i++ ) {
if( c == EOF ) /* EOF */
break;
bp[i] = c;
}
bp[i] = '\0';
if( c=='\n' || c==EOF )
return 1;
return 0;
}


/************************************************************************
int getPrivateProfileInt( const char* section, const char* entry,
int def, const char* file_name);
section - nombre de seccion a buscar
entry - entrada a buscar
def - Valor por defecto a devolver en caso de fallo
file_name - el nombre del fichero .ini

Return: Valor localizado para la entrada
*************************************************************************/
int getPrivateProfileInt(const char *asection, const char *aentry,
int adef, const char *afile_name)
{
char buff[MAX_LINE_LENGTH+1];
char *ep;
char section[MAX_LINE_LENGTH+1];
int i;
FILE *fp;
int val;
int len = strlen(entry);

fp = fopen(afile_name,"r");
if( !fp )
return adef;

/* Formatear el nombre de seccion */
strcpy(section, "[");
strncat(section,asection,sizeof(section)-3);
strcat(section,"]");

/* Buscar la seccion */
do {
if( !read_line(fp,buff, sizeof(buff)) ) {
fclose(fp);
return adef;
}
} while( strcmp(buff, section) );

/* Encontrar la entrada dentro de esta seccion */
do {
/* la seccion termina cuando empieza otra seccion */
if( !read_line(fp,buff,sizeof(buff)) || buff[0] == '[' ) {
fclose(fp);
return def;
}
} while( strncmp(buff,aentry,len) );
fclose(fp);

/* Encontrar la string de valor (despues del signo =)*/
ep = strrchr(buff,'=');
if( ep)
ep++;
if( !ep || !strlen(ep) ) /* hay valor asignado ? */
return adef;

/* devolver valor */
if(sscanf( ep, "%d", &val)==1)
return val;
return adef;
}

No he probado el codigo, espero que no este muy mal.

Un saludo,
Martin.

Loading...