Problems Reading C File - Comma Delimiter

Asked

Viewed 328 times

2

aid of kindness.

I have the following file line structure:

99933311133,UM NOME QUALQUER,8485885855,UM ENDERECO QUALQUER,84 9992212,S,S

The default is: string-comma-string-comma-string-comma-string-comma... That is, each field is separated by a comma.

To read, I intended to capture line by line with fgets and then assign the value to each variable using fscanf, thus:

while (fgets(linha, TAM_BUFFER, arq)) { // lê cada linha do arquivo por vez, cada linha está na variável buffer
    fscanf(arq, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]\n", cpf, nome, cnh, endereco, contato, ind_brasileiro, ind_estado_civil);

In fgets each line of the file is stored in the variable "line", as a casing.

In fscanf the variable Arq is the variable with the file opened in read mode.

This solution is nowhere near what I need because the result is catastrophic: inserir a descrição da imagem aqui

Would anyone have an idea of what to do to fix?

What I want to appear on the screen is a text like this: "CPF: 123456666, name: Fulano de Tal, CNH number: 93939393939393....".

  • How is the printing of the data?

  • Maybe be the case to read the line with fgets and use the function strtok

  • I made the impression of each field and it’s coming in the right way. So I changed the string and now it’s coming almost correctly. Thank you.

1 answer

2

You can use the function strtok() of the standard library string.h to "break" the line into fields.

The following function is able to split the string src, using the delimiter delim and return it in the form of an array of strings:

char ** strsplit( const char * src, const char * delim )
{
    char * pbuf = NULL;
    char * ptok = NULL;
    int count = 0;
    int srclen = 0;
    char ** pparr = NULL;

    srclen = strlen( src );

    pbuf = (char*) malloc( srclen + 1 );

    if( !pbuf )
        return NULL;

    strcpy( pbuf, src );

    ptok = strtok( pbuf, delim );

    while( ptok )
    {
        pparr = (char**) realloc( pparr, (count+1) * sizeof(char*) );
        *(pparr + count) = strdup(ptok);

        count++;
        ptok = strtok( NULL, delim );
    }

    pparr = (char**) realloc( pparr, (count+1) * sizeof(char*) );
    *(pparr + count) = NULL;

    free(pbuf);

    return pparr;
}

Then you can abstract the fields from your record into a data structure:

struct record_s
{
    char * cpf;
    char * nome;
    char * cnh;
    char * endereco;
    char * contato;
    char * ind_brasileiro;
    char * ind_estado_civil;
};

typedef struct record_s record_t;

Since the order of the fields of your record in file is always the same, the following implementation is able to map the field with the member of the structure, converting the read line to a populated data structure:

record_t * parse_record( char * linha )
{
    char ** pp = NULL;
    record_t * cad = NULL;

    pp = strsplit( linha, "," );

    cad = (record_t*) calloc( 1, sizeof(record_t) );

    cad->cpf = strdup(pp[0]);
    cad->nome = strdup(pp[1]);
    cad->cnh = strdup(pp[2]);
    cad->endereco = strdup(pp[3]);
    cad->contato = strdup(pp[4]);
    cad->ind_brasileiro = strdup(pp[5]);
    cad->ind_estado_civil = strdup(pp[6]);

    strsplitfree( pp );

    return cad;
}

Putting it all together:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LINE_MAX_LEN            (1024 * 2)   /* 2 KBytes */

struct record_s
{
    char * cpf;
    char * nome;
    char * cnh;
    char * endereco;
    char * contato;
    char * ind_brasileiro;
    char * ind_estado_civil;
};


typedef struct record_s record_t;


char ** strsplit( const char * src, const char * delim )
{
    char * pbuf = NULL;
    char * ptok = NULL;
    int count = 0;
    int srclen = 0;
    char ** pparr = NULL;

    srclen = strlen( src );

    pbuf = (char*) malloc( srclen + 1 );

    if( !pbuf )
        return NULL;

    strcpy( pbuf, src );

    ptok = strtok( pbuf, delim );

    while( ptok )
    {
        pparr = (char**) realloc( pparr, (count+1) * sizeof(char*) );
        *(pparr + count) = strdup(ptok);

        count++;
        ptok = strtok( NULL, delim );
    }

    pparr = (char**) realloc( pparr, (count+1) * sizeof(char*) );
    *(pparr + count) = NULL;

    free(pbuf);

    return pparr;
}


void strsplitfree( char ** strlist )
{
    int i = 0;

    while( strlist[i])
        free( strlist[i++] );

    free( strlist );
}


record_t * parse_record( char * linha )
{
    char ** pp = NULL;
    record_t * cad = NULL;

    pp = strsplit( linha, "," );

    cad = (record_t*) calloc( 1, sizeof(record_t) );

    cad->cpf = strdup(pp[0]);
    cad->nome = strdup(pp[1]);
    cad->cnh = strdup(pp[2]);
    cad->endereco = strdup(pp[3]);
    cad->contato = strdup(pp[4]);
    cad->ind_brasileiro = strdup(pp[5]);
    cad->ind_estado_civil = strdup(pp[6]);

    strsplitfree( pp );

    return cad;
}


void destroy_record( record_t * cad )
{
    free(cad->cpf);
    free(cad->nome);
    free(cad->cnh);
    free(cad->endereco);
    free(cad->contato);
    free(cad->ind_brasileiro);
    free(cad->ind_estado_civil);

    free(cad);
}


void show_record( record_t * cad )
{
    printf( "[ REGISTRO ]\n" );
    printf( "   CPF: %s\n", cad->cpf );
    printf( "   Nome: %s\n", cad->nome );
    printf( "   CNH: %s\n", cad->cnh );
    printf( "   Endereco: %s\n", cad->endereco );
    printf( "   Contato: %s\n", cad->contato );
    printf( "   Ind. Brasileiro: %s\n", cad->ind_brasileiro );
    printf( "   Estado Civil: %s\n", cad->ind_estado_civil );
    printf( "\n" );
}


int main( int argc, char * argv[] )
{
    char line[ LINE_MAX_LEN + 1 ];
    record_t * c = NULL;
    FILE * fp = NULL;

    fp = fopen( argv[1], "r" );

    while( fgets( line, LINE_MAX_LEN, fp ) )
    {
        c = parse_record( line );
        show_record( c );
        destroy_record( c );
    }

    fclose(fp);

    return 0;
}

Input.txt:

12312312300,JOSE SILVA,56548656,SAO PAULO,(11) 999991234,S,N
98798798700,MARIA SOUZA,32443234,RIO DE JANEIRO,21 978783434,S,S
88877766600,JOAO CARLOS,78645554,BRASILIA,61 945454532,N,N
99933311133,UM NOME QUALQUER,8485885855,UM ENDERECO QUALQUER,84 9992212,S,S

Testing:

$ ./teste entrada.txt
[ REGISTRO ]
   CPF: 12312312300
   Nome: JOSE SILVA
   CNH: 56548656
   Endereco: SAO PAULO
   Contato: (11) 999991234
   Ind. Brasileiro: S
   Estado Civil: N


[ REGISTRO ]
   CPF: 98798798700
   Nome: MARIA SOUZA
   CNH: 32443234
   Endereco: RIO DE JANEIRO
   Contato: 21 978783434
   Ind. Brasileiro: S
   Estado Civil: S


[ REGISTRO ]
   CPF: 88877766600
   Nome: JOAO CARLOS
   CNH: 78645554
   Endereco: BRASILIA
   Contato: 61 945454532
   Ind. Brasileiro: N
   Estado Civil: N


[ REGISTRO ]
   CPF: 99933311133
   Nome: UM NOME QUALQUER
   CNH: 8485885855
   Endereco: UM ENDERECO QUALQUER
   Contato: 84 9992212
   Ind. Brasileiro: S
   Estado Civil: S
  • I think in the first 4 words of the answer I already knew you were the author =]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.