Read elements from a file

Asked

Viewed 122 times

4

Hi, I have a big problem! I have to read two very large numbers of a file and save each position in a list. I’m using fgetc to pick up each element, the two numbers are separated by a blank space, however after I read the first and start the while to pick the second it picks up from the beginning of the line. Would anyone have any idea how to solve this problem?

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


typedef struct celula{
    int num;
    struct celula *prox;
} celula;

typedef struct pilha{
    celula c;
    celula *topo, *fundo;
    int tamanho;
}pilha;

void fpvazia (pilha *p){
    p->topo = (celula*) malloc (sizeof(celula));
    p->fundo = p->topo;
    p->topo->prox = NULL;
    p->tamanho = 0;
}

int vazia(pilha p){
    return (p.topo == p.fundo);
}

void insere (pilha *p, int x){
    celula *aux;
    aux = (celula*) malloc (sizeof(celula));
    p->topo->num = x;
    aux->prox = p->topo;
    p->topo = aux;
    p->tamanho++;
}

void retira (pilha *p, int *x){
    celula *aux;
    if(vazia(*p)){
        printf("Erro! Lista vazia!\n");
        return;
    }
    aux = p->topo;
    (*x) = aux->prox->num;
    free(aux);
    p->tamanho--;
}

int tamanho(pilha p){
    return (p.tamanho);
}

void imprime(pilha p){
    celula *aux;
    aux = (celula*)malloc (sizeof(celula));
    aux = p.topo->prox;

    while(aux!=NULL){
        printf("%d", aux->num );
        aux = aux->prox;
    }
}


int main (){
    pilha p, q;
    FILE *input;
    input = fopen("exemplo.txt", "r");
    if (input == NULL){
        printf("Erro ao abrir o arquivo\n");
        return 0;
    }
    char c;
    int n;

    fpvazia(&p);
    fpvazia(&q);
    //while (!feof(input)){
        //while (!feof(input)){
        c = fgetc(input);
        while (c!=' '){
        //  if (c == ' ')
        //  break;
        //printf("%c\n", c);
        n = c - 48;
        printf("%d\n", n );
        //printf("%d\n\n", n );
        insere(&p, n);
        c = fgetc(input);
    }

        //while (!feof(input)){
        //c = fgetc(input);
        c= fgetc(input);
        while (c!='\n'){
        //  if (c == ' ')
        //  break;
        //printf("%c\n", c );
        n = c - 48;
        insere(&q, n);
        c = fgetc(input);
        }


    imprime(q);
    //imprime(q);
    printf("\n%d\n", tamanho(q));
    //printf("%d\n", tamanho(p));
    //retira(&l, l.primeiro->prox, &z);
    //printf("%d\n",z );

return 0;
}
  • Post a sample of the file with the data. So it makes it much easier.

  • Example of Input 712476924792051427232 742179675108682905639616864728692565

  • in the example the numbers are small and would give salvation with a long long int, but in the statement he says that they can be giant numbers

1 answer

1

To read and store large integers, I suggest using character vectors char[], this way you have the flexibility to work with numbers with n number of digits.

Follow the necessary modifications to your code to make it do what you need:

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


#define DIGITOS_MAX    (300)

typedef struct celula{
    char num[DIGITOS_MAX + 1];
    struct celula *prox;
} celula;

typedef struct pilha{
    celula c;
    celula *topo, *fundo;
    int tamanho;
}pilha;

void fpvazia (pilha *p){
    p->topo = (celula*) malloc (sizeof(celula));
    p->fundo = p->topo;
    p->topo->prox = NULL;
    p->tamanho = 0;
}

int vazia(pilha p){
    return (p.topo == p.fundo);
}

void insere (pilha *p, const char * x ){
    celula *aux;
    aux = (celula*) malloc (sizeof(celula));
    strncpy( p->topo->num, x, DIGITOS_MAX );
    aux->prox = p->topo;
    p->topo = aux;
    p->tamanho++;
}

void retira (pilha *p, char ** x ){
    celula *aux;
    if(vazia(*p)){
        printf("Erro! Lista vazia!\n");
        return;
    }
    aux = p->topo;
    *x = aux->prox->num;
    free(aux);
    p->tamanho--;
}

int tamanho(pilha p){
    return (p.tamanho);
}

void imprime(pilha p){
    celula *aux;
    int i;
    aux = (celula*)malloc (sizeof(celula));
    aux = p.topo->prox;

    i=0;
    while(aux!=NULL){
        printf("pos = %d / n = %s\n", i++, aux->num );
        aux = aux->prox;
    }
}

int numvalido( const char * x ){
    const char * p = x;
    while(*p){
        if( !isdigit(*p) && (*p!='-') && (*p!='+') )
            return 0;
        p++;
    }

    return 1;
}

int main (){
    pilha p, q;
    FILE *input;
    input = fopen("exemplo.txt", "r");
    if (input == NULL){
        printf("Erro ao abrir o arquivo\n");
        return 0;
    }

    fpvazia(&p);
    fpvazia(&q);

    while(1){
        int ret;
        char a[DIGITOS_MAX+1];
        char b[DIGITOS_MAX+1];

        ret = fscanf( input, "%s %s\n", a, b );

        if( ret != 2 )
            break;

        if( !numvalido(a) || !numvalido(b) )
            continue;

        insere( &p, a );
        insere( &q, b );
    }

    printf("\nConteudo da pilha p:\n");
    imprime(p); 

    printf("\nConteudo da pilha q:\n");
    imprime(q);

    return 0;
}

Compiling (on Linux):

$ gcc -Wall numeros.c -o numeros

Input file:

$ cat exemplo.txt
712476924792051427232 742179675108682905639616864728692565
1234567890 1234567890
fooobarnotanumber 1234567890
aeiou xyzsklre
-1234567890 -1234567890
12345678901234567890 12345678901234567890
123456789012345678901234567890 123456789012345678901234567890
+1234567890123456789012345678901234567890 1234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890
0 0
-123 +123

Exit:

$ ./numeros

Conteudo da pilha p:
pos = 0 / n = -123
pos = 1 / n = 0
pos = 2 / n = 12345678901234567890123456789012345678901234567890
pos = 3 / n = +1234567890123456789012345678901234567890
pos = 4 / n = 123456789012345678901234567890
pos = 5 / n = 12345678901234567890
pos = 6 / n = -1234567890
pos = 7 / n = 1234567890
pos = 8 / n = 712476924792051427232

Conteudo da pilha q:
pos = 0 / n = +123
pos = 1 / n = 0
pos = 2 / n = -12345678901234567890123456789012345678901234567890
pos = 3 / n = 1234567890123456789012345678901234567890
pos = 4 / n = 123456789012345678901234567890
pos = 5 / n = 12345678901234567890
pos = 6 / n = -1234567890
pos = 7 / n = 1234567890
pos = 8 / n = 742179675108682905639616864728692565

I hope I’ve helped!

Browser other questions tagged

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