Problems with "strcpy" locking program

Asked

Viewed 272 times

3

I’m solving an exercise where I have to fill a vector like struct, and one of the values is char, for that I made a while and was using a simple assignment with "=" but it wasn’t working, so I did it with strcpy but every time I run the program it doesn’t open and lock.

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 function fill.

The file is formatted as follows: nome nota nota.

  • 1

    Next tip: don’t post the entire code, just isolate the important code snippet for your question. It gets easier to answer and sometimes doing so gives you an idea of what might be causing the problem.

3 answers

5


I’m not gonna look at all the code, and there could be other mistakes. I have no way to test without isolating, which would be work and this you should have done before posting. Two things need to be fixed.

First you have to allocate memory to the string and the pointer to that string is that it should be stored in the structure. Note that the member type name is a pointer to char, then only one 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 may bring problem and inefficiency, but I will not touch 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 sequence of aluno.

std = malloc(cont * sizeof(aluno));

I put in the Github for future reference.

  • Actually the second allocation is ok because it caught sizeof(Std), as Std is student-type, the dereferentiation took the right struct.

  • I agree that if it were std would be okay, but he took *std.

  • Typo, I wanted to type sizeof([asterisk]Std) :)

  • So in this case you’re allocating space for pointers and not for structures. This could be done, but then you need to allocate the structures as well.

  • I don’t think so, because sizeof(*(student*)) is sizeof(student).

  • Now I understand what you mean. I’m going to touch this.

Show 1 more comment

4

I think it would be ideal to do

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

Simply assigning you cannot, because "name" is not a simple value as an int, it is an address for a memory area, only that "char name[15]" ceases to hold as soon as you leave Fill() function. Somehow you have to allocate and copy the content to a heap memory area; strdup() does both in one call.

1

Within the structure aluno was declared that name a pointer to a character. The problem is that you are trying to copy the nome file and put on pointer name, which does not accept character type data. You can follow the @Maniero suggestion or you can change its variable name within the structure aluno .

typedef struct aluno
{
    char name[30];
    float nota1, nota2, media;  
}aluno;

Browser other questions tagged

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