Problems with "strcpy" locking program

3

I'm solving an exercise where I have to fill a vector of type struct , and one of the values is char , so I made a while and was using a simple assignment with "=" but was not working , so I did with strcpy but every time I run the program it does not open and hangs.

Here is the code:

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

typedef struct aluno{
    char* name;
    float nota1, nota2, media;  
}aluno;

void resize (FILE *arq);
void fill (aluno *std, FILE * arq);
void menu (aluno* std, FILE *arq);
void consulta (aluno* std, FILE *arq);
int counter (FILE *arq);

int main(int argc, char * argv[]) { 
    FILE *arq;

    if (argc != 2) {
        printf("Erro de sintaxe: %s NOME_ARQUIVO\n", argv[0]);
        return 1;
    }   
    arq = fopen(argv[1], "r");  
    if (arq == NULL){
        printf("Erro ao abrir arquivo.\n");
    }
    else {
        resize (arq);
    }
}

void resize (FILE * arq){
    aluno* std;
    int cont = counter (arq);

    std = (aluno *) malloc(cont * sizeof(*std));    
    fill (std, arq);
}

void fill (aluno* std, FILE * arq){
    char nome[15];
    int i = 0;
    float nota1, nota2;

    fseek (arq , 0 , SEEK_SET); 
    while ((fscanf (arq, "%s %f %f", nome, &nota1, &nota2)) != EOF){
        strcpy (std[i].name, nome);
        std[i].nota1 = nota1;
        std[i].nota2 = nota2;
        std[i].media = (nota1+nota2)/2; 
        i++;
    }
    printf ("\n\n\n\nArquivo carregado!\n");    
    menu (std, arq);
}

void menu (aluno* std, FILE * arq){
    int escolha;
    do {
        printf ("\n\n -- Catalogo: -- \n\n");
        printf ("1 - Inserir dado no final \n");
        printf ("2 - Inserir dado na posicao 'N' \n");
        printf ("3 - Remover dado no final \n");
        printf ("4 - Remover dado na posicao 'N' \n");
        printf ("5 - Buscar dado\n");
        printf ("\nDigite sua escolha: ");
        scanf ("%d", &escolha);

        switch (escolha){
            case 1:
                printf ("\nEscolha: 'Inserir dado no final!'");
                break;
            case 2:
                printf ("\nEscolha: 'Inserir dado na posicao - N - !'");
                break;
            case 3:
                printf ("\nEscolha: 'Remover dado no final!'");
                break;
            case 4:
                printf ("\nEscolha: 'Inserir dado na posicao - N - !'");
                break;
            case 5:
                printf ("\nEscolha: 'Buscar dado!'");
                consulta (std, arq);
                break;
            default: 
                printf ("\nEscolha: 'Inserir dado no final'!");
                break;
        }
    } while (1);
}

void consulta (aluno* std, FILE *arq){
    int cont, i=0;
    cont = counter (arq);

    printf ("\n\n Consulta de Alunos \n\n");
    printf ("Quantidade de registros: %d\n", cont);

    while (i < cont){
        printf ("O aluno %s possui: Nota 1: %.2f, Nota 2: %.2f, Media: %.2f\n", std[i].name, std[i].nota1, std[i].nota2, std[i].media);
        i ++;
    }
}

int counter (FILE * arq){
    int contador = 0;
    char nome[15];
    float nota1, nota2;

    fseek (arq , 0 , SEEK_SET);
    while ((fscanf (arq, "%s %f %f", nome, &nota1, &nota2)) != EOF){
        contador ++;
    }   
    return contador;
}

The error in question is in the fill function.

The file is formatted as follows: nome nota nota .

    
asked by anonymous 28.08.2015 / 01:49

3 answers

5

I will not look at the whole code and may have other errors. I can not test without isolating, which would give work and this you should have done before posting. Two things need to be fixed.

First you have to allocate memory for the string and the pointer to this string is what should be stored in the structure. Note that the member type name is a pointer to char , so only a pointer can be placed there.

while ((fscanf (arq, "%s %f %f", nome, &nota1, &nota2)) != EOF){
    char * temp = malloc(15);
    strcpy (temp, nome);
    std[i].name = temp
    std[i].nota1 = nota1;
    std[i].nota2 = nota2;
    std[i].media = (nota1+nota2)/2; 
    i++;
}

I would improve this and other things that can bring problem and inefficiency, but I will not touch on anything other than the problem pointed out.

The other problem is that you have allocated memory for pointers to aluno when you probably wanted to create an area for a string of aluno .

std = malloc(cont * sizeof(aluno));
    
28.08.2015 / 02:17
4

I think it would be ideal to do

  std[i].name = strdup(nome);

Simply assign you can not, because "name" is not a simple value as an int, it is an address for an area of memory, only "char name [15]" is no longer valid as soon as you exit the fill function (). Somehow you have to allocate and copy content to a heap memory area; strdup () does both in a single call.

    
28.08.2015 / 06:54
1

Inside the aluno structure, it was declared that name is a pointer to a character. The problem is that you are trying to copy the nome of the file and put it in the name pointer, which does not accept character data. You can follow the @bigown hint or you can change your name variable within the aluno structure.

typedef struct aluno
{
    char name[30];
    float nota1, nota2, media;  
}aluno;
    
28.08.2015 / 13:51