Doubt reading file in C

1

Good morning, my question is as follows. I have a flat file called group, in which all linux users are shown. My problem is that I need to read each of the lines in the file and show the group's identifier and its name on the screen. Something like this:

Name of the group: root Group identifier: 0

My problem is that when I scan the file with fscanf, it keeps the entire file line in the first string. Does anyone know how I could go through that line separating each of the elements of the line? File lines:

root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:syslog,rafa
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:

The code:

char *valor="/etc/group";

fich=fopen(valor,"r");

if (fich)
{   
while ((fscanf(fich,"%s'%s'%d':'\n",nombre,basura3,&ident)!=0) && (fscanf(fich,"%s'%s'%d':'%s \n",nombre,basura3,&ident,basura)!=0) && (!feof(fich)))
    {
    printf("Nombre del grupo:%s \n",nombre );
    printf("Identificador del grupo: %d \n",ident);
    }
    fclose(fich);
}
else
{
printf("Error fichero.\n");
}
    
asked by Rafael Romero Medina 15.03.2017 в 12:31
source

3 answers

2

You are not using fscanf correctly:

  • You do not need to declare a variable to store garbage, %* causes the function to ignore those characters.
  • Comparing the result with 0 does not guarantee that the values have been assigned to all the variables, always compare with the number of variables that you expect to fill, in this case 2 since we have decided to discard the garbage.
  • In a desperate attempt you try to shoehorn feof , but do not paint anything in this matter:)
  • fscanf allows the use of wildcards: %[^:] (where the two points are the delimiter you are using in your example)

    Test:

    while (fscanf(fich, "%[^:]:%*[^:]:%d%*[^\n]", nombre, &ident) == 2) {
    

    If the string will always contain only one character between the :x: delimiters, you can simplify it like this:

    while (fscanf(fich, "%[^:]:%*c:%d%*[^\n]", nombre, &ident) == 2) {
    

    %*c consumes (ignores) the character x while %*[^\n] consumes the remaining characters until it reaches the line break.

        
    answered by 16.03.2017 в 12:56
    1

    You can use strtok :

    char cad[20];
    strcpy(cad,"adm:x:4:syslog,rafa");
    
    const char* nombre;
    const char* identStr;
    const char* usuarios;
    int ident;
    
    nombre = strtok(cad,":");
    strtok(NULL,":");
    identStr = strtok(NULL,":");
    usuarios = strtok(NULL,"
    char cad[20];
    strcpy(cad,"adm:x:4:syslog,rafa");
    
    const char* nombre;
    const char* identStr;
    const char* usuarios;
    int ident;
    
    nombre = strtok(cad,":");
    strtok(NULL,":");
    identStr = strtok(NULL,":");
    usuarios = strtok(NULL,"%pre%");
    
    sscanf(identStr,"%d",&ident);
    
    printf("usuario: %s\nident: %d\nusuarios: %s\n",nombre,ident,usuarios);
    
    "); sscanf(identStr,"%d",&ident); printf("usuario: %s\nident: %d\nusuarios: %s\n",nombre,ident,usuarios);

    If you then need to separate the users you can repeat the process of strtok with the pointer usuarios .

        
    answered by 15.03.2017 в 12:45
    0

    You can try this, we use malloc and fseek :

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        FILE *archivo = fopen("test.c", "r"); // declaramos el archivo a leer como (r) read
        if (archivo == NULL) {
            return 0; // si la lectura es nula, sale del script
        }
        char *final; // declaramos un valor como apuntador
        size_t n = 0; // se entiende jaja
        int c;
        fseek(archivo, 0, SEEK_END); // activamos el indicador de la posición al final
        long f_size = ftell(archivo);
        fseek(archivo, 0, SEEK_SET); // obtenemos el valor del indicador para steam
        final = malloc(f_size + 1); // en este caso es necesario usar malloc, será mejor
        while ((c = fgetc(archivo)) != EOF) {
            final[n++] = c; // metemos caracter por caracter en los bloques de memoria
        }
        final[n] = '
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        FILE *archivo = fopen("test.c", "r"); // declaramos el archivo a leer como (r) read
        if (archivo == NULL) {
            return 0; // si la lectura es nula, sale del script
        }
        char *final; // declaramos un valor como apuntador
        size_t n = 0; // se entiende jaja
        int c;
        fseek(archivo, 0, SEEK_END); // activamos el indicador de la posición al final
        long f_size = ftell(archivo);
        fseek(archivo, 0, SEEK_SET); // obtenemos el valor del indicador para steam
        final = malloc(f_size + 1); // en este caso es necesario usar malloc, será mejor
        while ((c = fgetc(archivo)) != EOF) {
            final[n++] = c; // metemos caracter por caracter en los bloques de memoria
        }
        final[n] = '%pre%'; // eliminamos el último salto de linea
        fclose(archivo); // cerramos el fichero
        printf("%s", final);
        free(final); // y liberamos el malloc
    }
    
    '; // eliminamos el último salto de linea fclose(archivo); // cerramos el fichero printf("%s", final); free(final); // y liberamos el malloc }
        
    answered by 16.03.2017 в 17:31