How to write a loop to read a file to an array of structs in C?

3

Hello. I have a question about how to read numbers from a given file in c to put inside the loop

The .txt file will have the following data:

3
Joao Maria 
branco p
Marcio Guess
vermelho p
Maria Jose
branco p
2
Joao Losna
Vermelho G
Donald Trump
Branco P
0

You would have to read the number 3, put inside the loop repeat, read name color / size save in variables.

Read the next number which is the 2 put inside the loop repeat, read the data.

Until the number is 0 as in the example.

Part of the code in c:

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

typedef struct
{
    char *nome[100];
    char cor[100];
    char tam[100];
} Camisetas;

int comparaNome(const void *a, const void *b) {
    const Camisetas *elemA = a;
    const Camisetas *elemB = b;
    int valor;
    if (elemA->cor[0] > elemB->cor[0])
        valor = 1;
    else if (elemA->cor[0] < elemB->cor[0])
        valor = -1;
    else if (elemA->tam[0] < elemB->tam[0])
        valor = 1;
    else if (elemA->tam[0] > elemB->tam[0])
        valor = -1;
    else if (elemA->nome[0] > elemB->nome[0])
        valor = 1;
    else if (elemA->nome[0] < elemB->nome[0])
        valor = -1;
    else
        valor = 0;
    return valor;
}

int main() {
    size_t len = 100; // valor arbitrário
    Camisetas pessoas[100];
    char c, *linha = malloc(len), *nome = malloc(len), *cor = malloc(len), *tam = malloc(len);
    int casos[100], i, j, k, C, aux, aux2;
    char url[] = "doc.txt";
    FILE *arq = fopen(url, "r");
    arq == NULL ? printf("Erro, nao foi possivel abrir o arquivo\n") : printf("Sucesso ao abrir o arquivo\n");

    //pegar os casos
    for (j = 0; j < 2 && !feof(arq); j++) {
        fscanf(arq, "%c", &C);
        casos[j] = atoi(&C);
        if (casos[j] != 0) {
            aux2 = casos[j];
        }
        aux = C * 2;
    }

    while (casos) {
        for (i = 0; i < aux && !feof(arq); i++) {
            getline(&pessoas[i].nome, &len, arq);//ou usar fscanf
            (fscanf(arq, "%s %s\n", &pessoas[i].cor, &pessoas[i].tam) != EOF);
        }

        qsort(pessoas, aux2, sizeof(Camisetas), comparaNome);
        for (k = 0; k < aux2; k++) {
            printf("%s %s %s", pessoas[k].cor, pessoas[k].tam, *pessoas[k].nome);
        }
    }

    return 0;
}
    
asked by anonymous 16.11.2016 / 14:35

1 answer

2

I chose to redo because I could not keep up with your algorithm very well. Some things did not make much sense.

With your knowledge, I believe that reading the code will be self-explanatory. Only the 'main' function already answers your question - the rest is just for testing.

- The code has been changed to add the structure ordering function -

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

#define TAM_NOME 50
#define TAM_COR 20
#define MAXPORMALLOC 100//aumento do vetor por vez

typedef struct
{
    char* nome;
    char* cor;
    char* tamanho;
}td_Pessoa;

typedef struct
{
    td_Pessoa* pessoa;
    int pos;
    int loop;//controla o uso desnecessario do malloc
}td_Lista;

td_Lista* CriaLista();
td_Pessoa* CriaPessoa();
void IniciaLista(td_Lista*);
void AumentaTamanhoLista(td_Lista*);
void AdicionaPesoa(td_Lista*, td_Pessoa*);

void OrdenarPorCor(td_Lista* lista, char* cor);//FUNCAO NOVA
void TrocaPessoa(td_Pessoa* pessoa1, td_Pessoa* pessoa2); //FUNCAO NOVA

int main()
{
    FILE *arqEntrada, *arqSaida;

    int i;

    td_Pessoa* tmpPessoa = CriaPessoa();

    td_Lista *lista = CriaLista();
    IniciaLista(lista);

    int loop;

    if(arqEntrada = fopen("file.txt", "r"))
    {
        fscanf(arqEntrada, "%d", &loop);
        fgetc(arqEntrada); //para os \n
        do
        {
            for(i = 0; i < loop; i++)
            {
                fgets(tmpPessoa->nome, TAM_NOME, arqEntrada);
                fscanf(arqEntrada, "%s %s", tmpPessoa->cor, tmpPessoa->tamanho);
                fgetc(arqEntrada);

                if(lista->pos < (lista->loop * MAXPORMALLOC))
                    AdicionaPesoa(lista, tmpPessoa);
                else
                {
                    AumentaTamanhoLista(lista);
                    AdicionaPesoa(lista, tmpPessoa);
                }
            }
            fscanf(arqEntrada, "%d", &loop);
            fgetc(arqEntrada);
        }while(loop != 0);

        OrdenarPorCor(lista, "vermelho");//ORDENACAO

        //Mostra os valores armazenados no VETOR
        for(i = 0; i < lista->pos; i++)
            printf("%s%s %s\n", lista->pessoa[i].nome, lista->pessoa[i].cor, lista->pessoa[i].tamanho);

        //Coloca no arquivo de saida os valores do VETOR
        arqSaida = fopen("fpOUT.txt", "w+");
        for(i = 0; i < lista->pos; i++)
            fprintf(arqSaida, "%s%s %s\n", lista->pessoa[i].nome, lista->pessoa[i].cor, lista->pessoa[i].tamanho);

    }else
    {
        printf("O arquivo nao existe.\n");
        return 1;
    }

    free(lista);
    return 0;
}

void OrdenarPorCor(td_Lista* lista, char* cor)//FUNCAO NOVA
{
    int i, a;

    for(i = 0; i < lista->pos; i++)
        if(!strcmp(lista->pessoa[i].cor, cor))
            for(a = 0;; a++)
                if(strcmp(lista->pessoa[a].cor, cor))
                {
                    TrocaPessoa(&lista->pessoa[i], &lista->pessoa[a]);
                    break;
                }
}

void TrocaPessoa(td_Pessoa* pessoa1, td_Pessoa* pessoa2) //FUNCAO NOVA
{
    td_Pessoa* tmpPessoa = CriaPessoa();

    strcpy(tmpPessoa->nome, pessoa1->nome);
    strcpy(tmpPessoa->cor, pessoa1->cor);
    strcpy(tmpPessoa->tamanho, pessoa1->tamanho);

    strcpy(pessoa1->nome, pessoa2->nome);
    strcpy(pessoa1->cor, pessoa2->cor);
    strcpy(pessoa1->tamanho, pessoa2->tamanho);

    strcpy(pessoa2->nome, tmpPessoa->nome);
    strcpy(pessoa2->cor, tmpPessoa->cor);
    strcpy(pessoa2->tamanho, tmpPessoa->tamanho);

    free(tmpPessoa);
}

void AdicionaPesoa(td_Lista* lista, td_Pessoa* pessoa)
{
    strcpy(lista->pessoa[lista->pos].nome, pessoa->nome);  
    strcpy(lista->pessoa[lista->pos].cor, pessoa->cor);  
    strcpy(lista->pessoa[lista->pos].tamanho, pessoa->tamanho);  

    lista->pos++;
}

//essa parte de baixo é só para evitar o uso excessivo de MALLOC e REALLOC
td_Lista* CriaLista()
{
    td_Lista* res;

    res = (td_Lista*)malloc(sizeof(td_Lista));

    return res;
}

td_Pessoa* CriaPessoa()
{
    td_Pessoa* res = (td_Pessoa*)malloc(sizeof(td_Pessoa));

    res->nome   = (char*)malloc(sizeof(char) * TAM_NOME);
    res->cor    = (char*)malloc(sizeof(char) * TAM_COR);
    res->tamanho= (char*)malloc(sizeof(char));

    return res;
}

void IniciaLista(td_Lista* lista)
{   
    int i;
    lista->loop = 1;
    lista->pos  = 0;

    lista->pessoa = (td_Pessoa*)malloc(sizeof(td_Pessoa) * lista->loop * MAXPORMALLOC);

    for(i = 0; i < MAXPORMALLOC; i++)
    {
        lista->pessoa[i].nome = (char*)malloc(sizeof(char) * TAM_NOME);
        lista->pessoa[i].cor= (char*)malloc(sizeof(char) * TAM_COR);
        lista->pessoa[i].tamanho = (char*)malloc(sizeof(char));
    }
}

void AumentaTamanhoLista(td_Lista* lista)
{
    int i = lista->loop++ * MAXPORMALLOC;
    int tamanho = lista->loop * MAXPORMALLOC;

    lista->pessoa = (td_Pessoa*)realloc(lista, sizeof(td_Pessoa) * tamanho);

    for(; i < tamanho; i++)
    {
        lista->pessoa[i].nome = (char*)malloc(sizeof(char) * TAM_NOME);
        lista->pessoa[i].cor= (char*)malloc(sizeof(char) * TAM_COR);
        lista->pessoa[i].tamanho = (char*)malloc(sizeof(char));
    }
}
    
17.11.2016 / 00:37