Oppure

Loading
19/12/11 19:14
TheKaneB
per dovere di cronaca, in C le funzioni possono ritornare anche intere struct, non per forza puntatori ad esse. In tal caso il compilatore infila un memcpy a tradimento, risolvendo tra l'altro il problema di allocazione della memoria per una singola struct (che introduce overhead e frammentazione dell'heap).

Questa era una limitazione Pre-ANSI ISO C89, mi sorprende che qualcuno se ne ricordi ancora O_o''

Io avevo 3 anni quando hanno sistemato questo problema :rofl:
Ultima modifica effettuata da TheKaneB 19/12/11 19:17
aaa
19/12/11 19:42
Driverfury
Postato originariamente da nessuno:

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


Ho modificato i puntatori a char nella struttura "contact":

// Struttura: Contatto
struct contact
{
    char name[30];
    char surname[30];
    char number[15];
    char address[100];
};


Ma l'errore è sempre lo stesso: "Si è verificato un errore in Rubrica.exe. L'applicazione verrà chiusa.". Perchè?

Vi posto l'intero sorgente:

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

#define FILE_NAME "rubrica.txt"

#define DEBUG 1

// 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[30];
    char surname[30];
    char number[15];
    char address[100];
};

// Prototipi di funzioni
void showMenu();
void controlMenu();
int addContact(char *fileName);
int showContacts(char *fileName);
void returnContacts(char *fileName, struct contact *c);
int returnNContacts(char *fileName);

int main(int argc, char *argv[])
{
    
    // Compie all'infinito questo ciclo
    do
    {
        
        showMenu();
        controlMenu();
        
    } while(1);
    
    // Se il programma è in fase di debug allora usa la funzione di sistema "PAUSE"
    #if DEBUG == 1
        system("PAUSE");
    #endif
    
    return 0;
}

// Procedura che stampa a schermo il menù
void showMenu()
{
    printf("--- MENU' PRINCIPALE ---\n");
    printf("\n1. Aggiungi contatto");
    printf("\n2. Guarda rubrica");
    printf("\n3. Cerca contatto");
    printf("\n9. Esci\n");
}

// Procedura che richiama una funzione a seconda della decisione presa nel menù
void controlMenu()
{
    int choise;
    printf("\nScegli un'opzione dal menu' => ");
    scanf("%d", &choise); // Prendo in input la scelta dell'utente
    
    // Richiamo le funzioni in base alla scelta
    switch (choise)
    {
        case 1:
            addContact(FILE_NAME);
            break;
        case 2:
            showContacts(FILE_NAME);
            break;
        case 3:
            break;
        case 9:
            exit(1);
        default:
            controlMenu(); // Se la scelta non è valido richiamo ricorsivamente questa funzione
    }
}

// Funzione per aggiungere un nuovo contatto nella rubrica (ritorna 1 se la funzione va a buon fine)
int addContact(char *fileName)
{
    FILE *fp; // Puntatore a file
    struct contact c; // Variabile di tipo struttura "contact"
    char *temp_c; // Variabile d'appoggio
    
    if(!(fp=fopen(fileName, "a"))) // Se non riesce ad aprire il file in modalità di scrittura
    {
        printf("\nErrore durante l'apertura del file \"%s\" in modalita' append.\n", fileName);
        return 0;
    }
    
    printf("Inserire il nome: ");
    gets(c.name); // Prendo in input il nome del contatto
    gets(temp_c);
    
    printf("Inserire il cognome: ");
    gets(c.surname); // Prendo in input il cognome del contatto
    gets(temp_c);
    
    printf("Inserire il numero di telefono: ");
    gets(c.number); // Prendo in input il numero di telefono del contatto
    gets(temp_c);
    
    printf("Inserire l'indirizzo: ");
    gets(c.address); // Prendo in input l'indirizzo
    gets(temp_c);
    
    if(fprintf(fp, "%s %s %s %s\n", c.name, c.surname, c.number, c.address)>0) /* Se riesce a scrivere su file
    più di 0 Byte */
    {
        printf("\nContatto inserito con successo!\n");
    } else {
        fclose(fp); // Chiudo il file
        printf("\nErrore durante l'inserimento del contatto!\n");
        return 0;
    }
    
    fclose(fp); // Chiudo il file
    return 1; // Se tutto va a buon fine ritorna 1
}

// Funzione per stampare a schermo tutti i contatti della rubrica (ritorna 1 se la funzione va a buon fine)
int showContacts(char *fileName)
{
    FILE *fp; // Puntatore a file
    struct contact c[MAX_CON]; // Variabile di tipo struttura "contact"
    int nOfContacts;
    int i=0; // Contatore
    
    returnContacts(fileName, c);
    
    nOfContacts = returnNContacts(fileName);
    
    for (i=0; i < nOfContacts; i++)
    {
        if (i==0) // Se questo è il primo contatto stampa le descrizioni delle informazioni dei contatti
        {
            printf("\nCognome\t\tNome\t\tNumero\t\tIndirizzo\n");
        }
        
        // Stampo a schermo il contatto attuale
        printf("\n%s\t\t%s\t\t%s\t\t%s", c[i].surname, c[i].name, c[i].number, c[i].address);
    }
    
    
    fclose(fp); // Chiudo il file
    return 1; // Se tutto va a buon fine ritorna 1
}

// 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
}

// Funzione che ritorna il numero dei contatti nella rubrica
int returnNContacts(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 0;
    }
    
    while(fscanf(fp, "%*s %*s %*s %*s\n")>0) /* Fin quando
    riesce a leggere da file più di 0 Byte */
    {
        i++;
    }
    
    fclose(fp); // Chiudo il file
    return i; // Ritorna il numero di contatti letti
}


Sia quando scelgo l'opzione 1 che la 2 (ovvero sia che scrivo o che leggo da file) mi esce sempre lo stesso errore. Aiutatemi per favore.
Ultima modifica effettuata da Driverfury 19/12/11 19:43
aaa
19/12/11 23:54
Anche per

tempc

vale lo stesso discorso. E' un puntatore a char ma non puoi usarlo senza allocare lo spazio per la gets.

Hai difficoltà a lavorare con i puntatori ...

20/12/11 13:31
Driverfury
Postato originariamente da nessuno:

Anche per

tempc

vale lo stesso discorso. E' un puntatore a char ma non puoi usarlo senza allocare lo spazio per la gets.

Hai difficoltà a lavorare con i puntatori ...



Sì, è vero, ho ancora difficoltà a lavorare con i puntatori... abbiate pazienza. Comunque nella funzione showContacts() con uso nessun puntatore a carattere.
Mi spiegate cosa c'è che non va nella funzione addContacts() e showContacts()?
Ultima modifica effettuata da Driverfury 20/12/11 13:32
aaa
20/12/11 14:23
Beh, in addContact c'è il problema di tempc !

L'hai corretto?

Mostra il codice corretto ...
21/12/11 16:14
Driverfury
Ok per addContact() è quello l'errore... ma in showContacts(), cosa c'è che non va?
aaa
21/12/11 17:38
Perché utilizzi un altro puntatore FILE, perché chiudi un file non aperto?

Perché richiami due funzioni simili come

returnContacts

returnNContacts

Dovresti usarne una sola che faccia tutto.

E devi fare il debugging dell'applicazione ...