return value type does not match function type error

I created a typedef struct "modalidades", and i want to be able to save and load it from a text file, but theres this error when returning the value from my ler() function (this is the load function). gravar() function is my saving function. Anyone can help me fix this problem? Here's what I'm trying to do, the error is on "return a":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  typedef struct
{
	char nomejogo[50];
	int cota[2];
}jogos;

typedef struct
{
	jogos jogolist[10];
	char nome[50];

}modalidades;

modalidades ler(modalidades a[5])
{
	FILE *FicheiroDoPlacard;
	FicheiroDoPlacard = fopen("ficheirodoplacard.txt", "r");
	if (FicheiroDoPlacard == NULL)
	{
		printf("Impossivel Carregar\n");
	}
	else
	{
		for (int i = 0; i < 5; i++)
		{
			fscanf(FicheiroDoPlacard, "%s\n", a[i].nome);
			for (int j = 0; j < 10; j++)
			{
				fscanf(FicheiroDoPlacard, "%s\t---\t%s---%s\n", a[i].jogolist[j].nomejogo, a[i].jogolist[j].cota[0], a[i].jogolist[j].cota[1]);
			}
		}
		fclose(FicheiroDoPlacard);
		printf("Carregado com sucesso! \n");
	}
	return a;
}

void gravar(modalidades a[5])
{
	FILE *FicheiroDoPlacard;
	FicheiroDoPlacard = fopen("ficheirodoplacard.txt", "w");
	if (FicheiroDoPlacard == NULL)
	{
		printf("Impossivel Guardar\n");
	}
	else
	{
		for (int i = 0; i < 5; i++)
		{
			fprintf(FicheiroDoPlacard, "%s\n", a[i].nome);
			for (int j = 0; j < 10; j++)
			{
				fprintf(FicheiroDoPlacard, "%s\t---\t%s---%s\n", a[i].jogolist[j].nomejogo, a[i].jogolist[j].cota[0], a[i].jogolist[j].cota[1]);
			}
		}
		fclose(FicheiroDoPlacard);
		printf("Gravado com sucesso\n");
	}
}

int main(void)
{
modalidades modalidade[5];
modalidade[5] = ler(modalidade);
//code that doesnt matter in the middle...
gravar(modalidade);
}
Line 64 is wrong.

 
modalidade[5] = ler(modalidade);

First. array subscripts start from zero, so valid subscripts of the array modalidade[5] are 0 to 4.
That line is trying to assign a value to modalidade[5] which is the 6th element, it is outside the array boundaries.

Second, the function is already reading the data into the array which is passed as a parameter.

You could make the function return type void.
1
2
3
4
5
6
void ler(modalidades a[5])
{


//    return a;   // return is not necessary
}

and line 64 becomes simply
 
    ler(modalidade);


Or perhaps you could return an integer, to show whether the function failed or succeeded. Maybe use 0 and 1 to represent failure and success.
Last edited on
With those changes the program now crashes on the function ler(modalidade);
Visual Studio doesnt detect any errors.
Does a function that gets information elsewhere really need not to return what it has read to the main program?
With those changes the program now crashes on the function ler(modalidade);
Visual Studio doesnt detect any errors.

There are mismatches in both the fprintf and fscanf parameters.
The easy one first, line 53
1
2
3
4
fprintf(FicheiroDoPlacard, "%s\t---\t%s---%s\n", 
    a[i].jogolist[j].nomejogo, 
    a[i].jogolist[j].cota[0], 
    a[i].jogolist[j].cota[1]);

The format string specifies that there are three strings, %s, %s, %s
But there is just one string, and two ints %s, %d, %d
It should be:
1
2
3
4
fprintf(FicheiroDoPlacard, "%s\t---\t%d---%d\n", 
    a[i].jogolist[j].nomejogo,    // string
    a[i].jogolist[j].cota[0],     // integer  
    a[i].jogolist[j].cota[1]);    // integer 



The fscanf function is similar, but it has an added complication. Because it will be modifying the variables in the parameter list, it needs the address of each variable. The string is already ok, because it is an array of characters, and when an array is passed to a function, it is actually the address of the array which is passed. The other two, which are simple integers, need the address of operator &
1
2
3
4
fscanf(FicheiroDoPlacard, "%s\t---\t%d---%d\n", 
    a[i].jogolist[j].nomejogo, 
    &a[i].jogolist[j].cota[0], 
    &a[i].jogolist[j].cota[1]);

Does a function that gets information elsewhere really need not to return what it has read to the main program?


As you can see from the fscanf example, when an array is passed as a function parameter, what is actually passed is a pointer containing the address of the start of the array. Thus the function is able to modify the contents of the original array via that pointer. In the case of the int parameters, we have to explicitly pass the address of the variable in order that it can be modified.

The function can of course return some additional information, such as a return code indicating whether or not the function succeeded. But that is a matter of choice, it isn't necessary.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdio.h>

typedef struct
{
    char nomejogo[50];
    int cota[2];
} jogos;

typedef struct
{
    jogos jogolist[10];
    char nome[50];

} modalidades;

void ler(modalidades a[5])
{
    FILE *FicheiroDoPlacard;
    FicheiroDoPlacard = fopen("ficheirodoplacard.txt", "r");
    if (FicheiroDoPlacard == NULL)
    {
        printf("Impossivel Carregar\n");
    }
    else
    {
        for (int i = 0; i < 5; i++)
        {
            fscanf(FicheiroDoPlacard, "%s\n", a[i].nome);
            for (int j = 0; j < 10; j++)
            {
                fscanf(FicheiroDoPlacard, "%s\t---\t%d---%d\n", a[i].jogolist[j].nomejogo, &a[i].jogolist[j].cota[0], &a[i].jogolist[j].cota[1]);
            }
        }
        fclose(FicheiroDoPlacard);
        printf("Carregado com sucesso! \n");
    }
    
}

void gravar(modalidades a[5])
{
    FILE *FicheiroDoPlacard;
    FicheiroDoPlacard = fopen("ficheirodoplacard.txt", "w");
    if (FicheiroDoPlacard == NULL)
    {
        printf("Impossivel Guardar\n");
    }
    else
    {
        for (int i = 0; i < 5; i++)
        {
            fprintf(FicheiroDoPlacard, "%s\n", a[i].nome);
            for (int j = 0; j < 10; j++)
            {
                fprintf(FicheiroDoPlacard, "%s\t---\t%d---%d\n", a[i].jogolist[j].nomejogo, a[i].jogolist[j].cota[0], a[i].jogolist[j].cota[1]);
            }
        }
        fclose(FicheiroDoPlacard);
        printf("Gravado com sucesso\n");
    }
}

int main(void)
{
    modalidades modalidade[5];
    ler(modalidade);
    // code that doesnt matter in the middle...
    gravar(modalidade);
}
Thank you very much, everything is working perfectly now and I understood your explanation ^.^
Topic archived. No new replies allowed.