How do I write a loop to read a file to a C struct array?

Asked

Viewed 1,049 times

3

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

The file . txt 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 repeat loop, read color/size name save in variables.

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

Until the number is 0 as in the example.

Part of 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;
}
  • Look at these parts: else if (elemA->cor[0] cor[0]), else if (elemA->tam[0] tam[0]) and else if (elemA->nome[0] nome[0]) - that does not compile.

  • Ignore my previous comment. Is that you had put the code inside tags <pre><code>...</code></pre>. Don’t do that. Instead of using these tags, you have four spaces. You can use the button {} from the editor after selecting all your code to do this.

  • Why in the role comparaNome you look only at the first letter?

  • Why do you use the asterisk on char *nome[100];, but not in char cor[100]; or char tam[100];?

  • hello Victor, yes the function comparedName looks only at the first letter to after alphabetizing the names. take a look at <https://www.urionlinejudge.com.br/judge/pt/problems/view/1258> and <http://www.urionlinejudge.com.br/forum/viewtopic.php?f=5&t=260> the codes are for this problem.

  • @Carloscunha can’t go around changing the question to a new one, if you have new questions, create a new one with reference to this one. Otherwise the answers may lose their validity. Remembering that here is not a forum but a site of Questions and Answers. Regards.

Show 1 more comment

1 answer

2


I chose to redo it because I couldn’t follow its algorithm very well. Some things didn’t make much sense.

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

--The code has been changed to add the structure sorting 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));
    }
}
  • 2

    Welcome to Stack Overflow in English. I suggest you translate the names used in your code into Portuguese, as the explanation of how it works is nowhere else in the answer, and we should not assume here that readers understand English.

  • Thanks for the info, I’ll change the names and edit the file.

  • Thanks for the answers, I’ll test here and put the return.

  • Hello take a look at the new code if you can help again thank you very much.

  • Why did you choose the binary tree? in case the values are already being stored in the structure "list" it is only necessary to make one ordering, I made two new functions there for ordering, give a look and let you know if it helped.

  • In the case of that binary tree he returns to me the right order. o these codes are of a challenge taken from:<https://www.urionlinejudge.com.br/judge/pt/problems/view/1258> a look there. in case there would not need to do with file but I want to do by file. await return

Show 1 more comment

Browser other questions tagged

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