Oppure

Loading
19/12/11 13:36
Driverfury
Ciao a tutti, stavo creando una rubrica in C quando andando a compilare in una funzione c'è stato l'errore: "incompatible types in return". Ecco il file sorgente:

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

// Variabili e costanti globali
const int MAX_CON = 500; // Costante che sta ad indicare il massimo numero di contatti della rubrica

// Struttura: Contatto
struct contact
{
    char *name;
    char *surname;
    char *number;
    char *address;
};

// Prototipi di funzioni
struct contact returnContacts(char *fileName);

int main()
{
    char *fname = "rubrica.txt"
    struct contact c[MAX_CON];
    c = returnContacts(fname);
}

// Funzione che ritorna una struttura di contatti o un array di contatti
struct contact returnContacts(char *fileName)
{
    FILE *fp; // Puntatore a file
    struct contact c[MAX_CON]; // Variabile di tipo struttura "contact"
    int i=0; // Contatore
    
    if(!(fp=fopen(fileName, "r"))) // Se non riesce ad aprire il file in modalità di scrittura
    {
        printf("\nErrore durante l'apertura del file \"%s\" in modalita' lettura.\n", fileName);
        return;
    }
    
    while(fscanf(fp, "%s %s %s %s\n", c[i].name, c[i].surname, c[i].number, c[i].address)>0) /* Fin quando
    riesce a leggere da file più di 0 Byte */
    {
        i++;
    }
    
    fclose(fp); // Chiudo il file


    return c; // Questo è l'errore!!!
}


L'errore c'è quando ritorno "c" dalla funzione returnContacts(). Mi potete aiutare a farmi perchè c'è l'errore?
aaa
19/12/11 13:43
HeDo

allora, a parte l'errore sintattico sulla dichiarazione della funzione che dovrebbe essere "struct contact *", c'è un gravissimo errore semantico che non farà funzionare nulla e sono sicuro che non ci sbatteresti la testa per giorni.

non si può ritornare un array statico da una funzione, il motivo è che l'area di memoria dove è allocato va fuori scopo dopo il ritorno della funzione. per risolvere il problema ci sono due strade, la prima è allocare l'array con malloc, ovvero far si che risieda nell'heap e non nello stack. il contro di questa opzione è che ti devi ricordare di chiamare free sull'array dopo che hai utilizzato i dati nel main, altrimenti ti ritroverai con un memory leak.

la seconda strada, quella che io consiglio, è passare l'array di output come parametro della funzione e riempirlo all'interno della stessa. in questo modo la funzione non si deve occupare dell'allocazione della memoria ma è gestito tutto dal main.
aaa
19/12/11 15:33
Driverfury
Innanzitutto grazie. Ho provato a modificare il codice secondo i tuoi consigli:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
// Variabili e costanti globali
const int MAX_CON = 500; // Costante che sta ad indicare il massimo numero di contatti della rubrica
 
// Struttura: Contatto
struct contact
{
    char *name;
    char *surname;
    char *number;
    char *address;
};
 
// Prototipi di funzioni
struct contact * returnContacts(char *fileName, struct contact c[MAX_CON]);
 
int main()
{
    char *fname = "rubrica.txt"
    struct contact c[MAX_CON];
    c = returnContacts(fname, c);
}

// Funzione che ritorna un array di contatti
struct contact * returnContacts(char *fileName, struct contact c[MAX_CON])
{
    FILE *fp; // Puntatore a file
    int i=0; // Contatore
    
    if(!(fp=fopen(fileName, "r"))) // Se non riesce ad aprire il file in modalità di scrittura
    {
        printf("\nErrore durante l'apertura del file \"%s\" in modalita' lettura.\n", fileName);
        return;
    }
    
    while(fscanf(fp, "%s %s %s %s\n", c[i].name, c[i].surname, c[i].number, c[i].address)>0) /* Fin quando
    riesce a leggere da file più di 0 Byte */
    {
        i++;
    }
    
    fclose(fp); // Chiudo il file
    return c; // Ritorna il contatto o l'array di contatti
}


... Purtroppo l'errore è lo stesso... potresti aiutarmi più nel dettaglio?
Ultima modifica effettuata da Driverfury 19/12/11 15:34
aaa
19/12/11 15:42
Non hai proprio seguito tutti i consigli ... la funzione NON deve restituire nulla dato che lavora con il vettore passato come parametro.

Quindi sarà di tipo

void

e non

struct contact *

la chiamerai con

returnContacts(fname, c);

e non ci sarà la riga

return c;

P.S. In merito alla tua firma, qual è la Domanda ?
19/12/11 15:44
Bonny
non poi passare il vettore con la sua dimensione come parametro di una funzione....
struct contact * returnContacts(char *fileName, struct contact c[MAX_CON]);


devi farlo cosi
struct contact * returnContacts(char *fileName, struct contact c[]);
//or
struct contact * returnContacts(char *fileName, struct contact *c);

il vettore viene passato per riferimento... ovvero viene passato il puntatore alla prima allocazione di memoria del vettore
adesso capisci perchè Hedo ti ha consigliato di passarlo come parametro?
tutte le operazioni (assegnamento ecc..) che fai sul vettore, al termine della funzione restano "persistenti" in esso segue che non serve fare il return, quindi diventa:
void returnContacts(char *fileName, struct contact c[]);

Ultima modifica effettuata da Bonny 19/12/11 15:49
aaa
19/12/11 17:43
Driverfury
Postato originariamente da nessuno:

Non hai proprio seguito tutti i consigli ... la funzione NON deve restituire nulla dato che lavora con il vettore passato come parametro.

Quindi sarà di tipo

void

e non

struct contact *

la chiamerai con

returnContacts(fname, c);

e non ci sarà la riga

return c;

P.S. In merito alla tua firma, qual è la Domanda ?


Sì, è vero avevo interpretato male quanto citato da Hedo. Grazie mille nessuno, sei sempre molto disponibile e pronto ad aiutare. :k:
Ultima modifica effettuata da Driverfury 28/08/15 23:51
aaa
19/12/11 17:56
Driverfury
Comunque ho modificato il codice come mi avete consigliato ma l'applicazione si blocca e si chiude. Premetto che il file "rubrica.txt" esiste. Ecco come ho modificato il codice:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
// Variabili e costanti globali
const int MAX_CON = 500; // Costante che sta ad indicare il massimo numero di contatti della rubrica
 
// Struttura: Contatto
struct contact
{
    char *name;
    char *surname;
    char *number;
    char *address;
};

// Prototipi di funzioni
void returnContacts(char *fileName, struct contact c[]);

int main()
{
    char *fname = "rubrica.txt"
    struct contact c[MAX_CON];
    returnContacts(fname, c);
}

// Procedura che assegna un array di contatti
void returnContacts(char *fileName, struct contact c[])
{
    FILE *fp; // Puntatore a file
    int i=0; // Contatore
    
    if(!(fp=fopen(fileName, "r"))) // Se non riesce ad aprire il file in modalità di scrittura
    {
        printf("\nErrore durante l'apertura del file \"%s\" in modalita' lettura.\n", fileName);
        return;
    }
    
    while(fscanf(fp, "%s %s %s %s\n", c[i].name, c[i].surname, c[i].number, c[i].address)>0) /* Fin quando
    riesce a leggere da file più di 0 Byte */
    {
        i++;
    }
    
    fclose(fp); // Chiudo il file
}
aaa
19/12/11 18:12
Postato originariamente da Driverfury:

Comunque ho modificato il codice come mi avete consigliato ma l'applicazione si blocca e si chiude.


Per il futuro, il fatto che un'applicazione venga corretta (e vengano eliminati gli errori di compilazione) non significa che funzioni quando venga eseguita e non ci possano essere "altri" errori (a runtime appunto).

Il problema del tuo codice è causato dal fatto che hai utilizzato, nella struttura, dei puntatori a char e li hai utilizzati direttamente "senza allocare lo spazio" per ogni stringa. Questo causa (almeno) un crash dell'applicazione (come capita a te).

P.S. Per la firma, ok ... de gustibus ...