File reading problems

2

Last week I did a question about reading a "giant" string . Thanks to the help of the staff here I was able to implement the function.

Now, I've come up with a new problem. The file reading is not running correctly. The program is not reading until the end of the file.

You are always printing the first line and still incomplete.

The file contains 514 lines with entries in this style:

ALEX CANZIANI;PTB;PR;T;Câmara dos Deputados, Edifício Anexo;4;, gabinete nº;842;Brasília - DF - CEP 70160-900;3215-5842;3215-2842;06;11;[email protected];ALEX CANZIANI;Exmo. Senhor Deputado;Registrador de Imóveis;ALEX CANZIANI SILVEIRA
...
ALEX MANENTE;PPS;SP;T;Câmara dos Deputados, Edifício Anexo;4;, gabinete nº;245;Brasília - DF - CEP 70160-900;3215-5245;3215-2245;08;22;[email protected];ALEX MANENTE;Exmo. Senhor Deputado;Bacharel  Em Direito;ALEX SPINELLI MANENTE

Struct:

struct padrao{
    char nomeparlamentar[50];
    char partido[12];
    char UF[3];
    char estado[2];
    char endereco[50];
    char anexo[3];
    char Econt[50];
    char gabinete[5];
    char Ecompl[50];
    char telefone[12];
    char fax[12];
    char mesniver[3];
    char dianiver[3];
    char email[30];
    char nomesacento[50];
    char tratamento[50];
    char profissao[20];
    char nomecivil[70];
};
typedef struct padrao Cadastro;
Cadastro ladrao[MAX];

File reading function:

void RecebeDados(Cadastro ladrao){
    FILE *fp = fopen("ListadeDeputados1.txt", "r");
    if(fp==NULL){
        printf("Arquivo nao encontrado.");
        exit(1);
    }
    int i=0;
    char str[1000];
    fscanf(fp, " %[^\n]s", str);

    char* palavras[18];
    char *palavra = strtok(str, ";");

    while (palavra != NULL)
    {
        palavras[i++] = palavra;
        palavra = strtok(NULL, ";");
        printf("%s\n", palavra);
    }
    strcpy(ladrao.nomeparlamentar,&palavra[0]);
    strcpy(ladrao.partido,&palavra[1]);
    strcpy(ladrao.UF,&palavra[2]);
    strcpy(ladrao.estado,&palavra[3]);
    strcpy(ladrao.endereco,&palavra[4]);
    strcpy(ladrao.anexo,&palavra[5]);
    strcpy(ladrao.Econt,&palavra[6]);
    strcpy(ladrao.gabinete,&palavra[7]);
    strcpy(ladrao.Ecompl,&palavra[8]);
    strcpy(ladrao.telefone,&palavra[9]);
    strcpy(ladrao.fax,&palavra[10]);
    strcpy(ladrao.mesniver,&palavra[11]);
    strcpy(ladrao.dianiver,&palavra[12]);
    strcpy(ladrao.email,&palavra[13]);
    strcpy(ladrao.nomesacento,&palavra[14]);
    strcpy(ladrao.tratamento,&palavra[15]);
    strcpy(ladrao.profissao,&palavra[16]);
    strcpy(ladrao.nomecivil,&palavra[17]);
    return;
}
    
asked by anonymous 18.09.2017 / 02:14

2 answers

0

As far as I can tell, your RecebeDados function is responsible for reading a line from your file and returning the Cadastro structure filled with the name of the ladrao variable.

So, there are two errors that you are making:

  • Opening the file in this function. You have to open the file before and pass the handle to this function
  • As you are changing the variable ladrao , it has to be passed via pointer and not by value, as you are doing.

So your program should be something like:

void RecebeDados(FILE *fp, Cadastro *ladrao){
     assert(fp != NULL);
     assert(ladrao != NULL);

     int i=0;

     ... /* continua igual ao seu programa até a linha abaixo */

     strcpy(ladrao->nomeparlamentar,&palavra[0]); /* note a notação de ponteiro aqui */
     ...

where assert helps when debugging your program

To use this function, you open the file and call it again and again until you read all the lines

PS. Do not forget to make the error checks, just as if you arrived at the end of the file, when you are reading it

    
18.09.2017 / 02:50
0

Following is an implementation of a program that can read and process line by line from a CSV file with the format you specified:

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

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

struct cadastro_s
{
    char * nomeparlamentar;
    char * partido;
    char * UF;
    char * estado;
    char * endereco;
    char * anexo;
    char * Econt;
    char * gabinete;
    char * Ecompl;
    char * telefone;
    char * fax;
    char * mesniver;
    char * dianiver;
    char * email;
    char * nomesacento;
    char * tratamento;
    char * profissao;
    char * nomecivil;
};


typedef struct cadastro_s cadastro_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 );
}


cadastro_t * parse_cadastro( char * linha )
{
    char ** pp = NULL;
    cadastro_t * cad = NULL;

    pp = strsplit( linha, ";" );

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

    cad->nomeparlamentar = strdup(pp[0]);
    cad->partido = strdup(pp[1]);
    cad->UF = strdup(pp[2]);
    cad->estado = strdup(pp[3]);
    cad->endereco = strdup(pp[4]);
    cad->anexo = strdup(pp[5]);
    cad->Econt = strdup(pp[6]);
    cad->gabinete = strdup(pp[7]);
    cad->Ecompl = strdup(pp[8]);
    cad->telefone = strdup(pp[9]);
    cad->fax = strdup(pp[10]);
    cad->mesniver = strdup(pp[11]);
    cad->dianiver = strdup(pp[12]);
    cad->email = strdup(pp[13]);
    cad->nomesacento = strdup(pp[14]);
    cad->tratamento = strdup(pp[15]);
    cad->profissao = strdup(pp[16]);
    cad->nomecivil = strdup(pp[17]);

    strsplitfree( pp );

    return cad;
}


void destroy_cadastro( cadastro_t * cad )
{
    free(cad->nomeparlamentar);
    free(cad->partido);
    free(cad->UF);
    free(cad->estado);
    free(cad->endereco);
    free(cad->anexo);
    free(cad->Econt);
    free(cad->gabinete);
    free(cad->Ecompl);
    free(cad->telefone);
    free(cad->fax);
    free(cad->mesniver);
    free(cad->dianiver);
    free(cad->email);
    free(cad->nomesacento);
    free(cad->tratamento);
    free(cad->profissao);
    free(cad->nomecivil);

    free(cad);
}


void show_cadastro( cadastro_t * cad )
{
    printf( "[ CADASTRO ]\n" );
    printf( "   Nome Parlamentar: %s\n", cad->nomeparlamentar );
    printf( "   Partido: %s\n", cad->partido );
    printf( "   UF: %s\n", cad->UF );
    printf( "   Estado: %s\n", cad->estado );
    printf( "   Endereco: %s\n", cad->endereco );
    printf( "   Anexo: %s\n", cad->anexo );
    printf( "   Endereco: %s\n", cad->Econt );
    printf( "   Gabinete: %s\n", cad->gabinete );
    printf( "   Complemento: %s\n", cad->Ecompl );
    printf( "   Telefone: %s\n", cad->telefone );
    printf( "   Fax: %s\n", cad->fax );
    printf( "   Aniversario: %s/%s\n", cad->dianiver, cad->mesniver );
    printf( "   E-mail: %s\n", cad->email );
    printf( "   Nome: %s\n", cad->nomesacento );
    printf( "   Tratamento: %s\n", cad->tratamento );
    printf( "   Profissao: %s\n", cad->profissao );
    printf( "   Nome Civil: %s\n", cad->nomecivil );
    printf( "\n" );
}


int main( int argc, char * argv[] )
{
    char linha[ LINHA_MAX_TAM + 1 ];
    cadastro_t * c = NULL;
    FILE * fp = NULL;

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

    while( fgets( linha, LINHA_MAX_TAM, fp ) )
    {
        c = parse_cadastro( linha );
        show_cadastro( c );
        destroy_cadastro( c );
    }

    fclose(fp);

    return 0;
}

Test file deputados.csv :

ALEX CANZIANI;PTB;PR;T;Câmara dos Deputados, Edifício Anexo;4;, gabinete nº;842;Brasília - DF - CEP 70160-900;3215-5842;3215-2842;06;11;[email protected];ALEX CANZIANI;Exmo. Senhor Deputado;Registrador de Imóveis;ALEX CANZIANI SILVEIRA
ALEX MANENTE;PPS;SP;T;Câmara dos Deputados, Edifício Anexo;4;, gabinete nº;245;Brasília - DF - CEP 70160-900;3215-5245;3215-2245;08;22;[email protected];ALEX MANENTE;Exmo. Senhor Deputado ;Bacharel  Em Direito;ALEX SPINELLI MANENTE
BRUNNY;PR;MG;T;Câmara dos Deputados, Edifício Anexo;4;, gabinete nº;260;Brasília - DF - CEP 70160-900;3215-5260;3215-2260;08;21;[email protected];BRUNNY;Exma. Senhora Deputada;Superior Incompleto;BRUNIELE FERREIRA GOMES

Testing:

$ ./cadastro deputados.csv 
[ CADASTRO ]
    Nome Parlamentar: ALEX CANZIANI
    Partido: PTB
    UF: PR
    Estado: T
    Endereco: Câmara dos Deputados, Edifício Anexo
    Anexo: 4
    Endereco: , gabinete nº
    Gabinete: 842
    Complemento: Brasília - DF - CEP 70160-900
    Telefone: 3215-5842
    Fax: 3215-2842
    Aniversario: 11/06
    E-mail: [email protected]
    Nome: ALEX CANZIANI
    Tratamento: Exmo. Senhor Deputado
    Profissao: Registrador de Imóveis
    Nome Civil: ALEX CANZIANI SILVEIRA


[ CADASTRO ]
    Nome Parlamentar: ALEX MANENTE
    Partido: PPS
    UF: SP
    Estado: T
    Endereco: Câmara dos Deputados, Edifício Anexo
    Anexo: 4
    Endereco: , gabinete nº
    Gabinete: 245
    Complemento: Brasília - DF - CEP 70160-900
    Telefone: 3215-5245
    Fax: 3215-2245
    Aniversario: 22/08
    E-mail: [email protected]
    Nome: ALEX MANENTE
    Tratamento: Exmo. Senhor Deputado 
    Profissao: Bacharel  Em Direito
    Nome Civil: ALEX SPINELLI MANENTE


[ CADASTRO ]
    Nome Parlamentar: BRUNNY
    Partido: PR
    UF: MG
    Estado: T
    Endereco: Câmara dos Deputados, Edifício Anexo
    Anexo: 4
    Endereco: , gabinete nº
    Gabinete: 260
    Complemento: Brasília - DF - CEP 70160-900
    Telefone: 3215-5260
    Fax: 3215-2260
    Aniversario: 21/08
    E-mail: [email protected]
    Nome: BRUNNY
    Tratamento: Exma. Senhora Deputada
    Profissao: Superior Incompleto
    Nome Civil: BRUNIELE FERREIRA GOMES
    
18.09.2017 / 20:55