Estoy tratando de leer datos de un archivo que está formateado con ;. Los datos siempre serán así:

char[];int;int%;int

El char[] puede tener cualquier cantidad de espacios y el % no debe tenerse en cuenta al leer los datos.

Estoy usando fscanf() (se me permite usar solo eso) para leer los datos del archivo.
En este momento mi código para esa parte es:

fscanf(file, "%[^;]%d%d%d", f_name, &f_id, &f_score, &f_section_num) != EOF)

¿Hay una expresión regular para lo que necesito? O, ¿cómo corrijo mi fscanf?

1
Varun Ramakrishnan 7 sep. 2018 a las 23:53

3 respuestas

La mejor respuesta

Puede leer el archivo usando fscanf con esta cadena de formato:

"%[^;];%d;%d%%;%d"
  • %[^;]: lee hasta la primera ;
  • ;: ignora la ;
  • %d: lee un entero
  • ;: ignora la ;
  • %d: lee un segundo entero
  • %%: ignora la %
  • ;: ignora la ;
  • %d: lee un tercio entero

No olvide probar la cantidad de conversiones exitosas realizadas por fscanf probando fscanf(...) == 4

Entonces el código se verá así:

FILE *f = fopen(...);
char name[64];
int i, integers[3];

while (fscanf(f, "%[^;];%d;%d%%;%d", name, &integers[0], &integers[1], &integers[2]) == 4)
{
    printf("name is %s\n", name);
    for (i = 0; i < 3; ++i)
    {
        printf("i[%d] = %d\n", i, integers[i]);
    }        
}
fclose(f);
2
Mathieu 7 sep. 2018 a las 21:16

El siguiente código le permitirá leer datos separados por ; de su archivo:

char msg[100];
int  a;
char b[100];
int  c;

fscanf(fptr, "%[^;];%d;%[^;];%d", msg, &a, b, &c);
printf("%s\n %d\n %d\n %d\n", msg, a, atoi(b), c);
0
Grant Miller 8 sep. 2018 a las 00:27

Alternativamente, podría usar strtok(). Si, por ejemplo, usa una estructura para cada entrada de la siguiente manera,

typedef struct {
    char name[64];
    int id, score, section_num;
} entry_t;

Lo siguiente leería cada línea del archivo de la siguiente manera.

char line[128] = {'\0'};
char *field = NULL;
entry_t entry;

while (fgets(line, sizeof(line), fp)) {
    field = strtok(line, ";");
    if (!field || strlen(field) > sizeof(entry.name)) continue;
    strcpy(entry.name, field);
    field = strtok(NULL, ";");
    if (!field) continue;
    entry.id = atoi(field);
    field = strtok(NULL, ";%");
    if (!field) continue;
    entry.score = atoi(field);
    field = strtok(NULL, ";");
    if (!field) continue;
    entry.section_num = atoi(field);
    // Do whatever you need with the entry - e.g. print its contents
}

He eliminado algún código de repetitivo necesario por brevedad. Consulte http://codepad.org/lg6BJ0hk para ver un ejemplo completo.

Puede usar strtol() en lugar de atoi() si necesita verificar los resultados de las conversiones de enteros.

0
David Collins 7 sep. 2018 a las 21:53