RISOLTO Compilatore non da errori ma non funziona

Pubblicità
Stato
Discussione chiusa ad ulteriori risposte.

Francesco C.

Utente Attivo
Messaggi
264
Reazioni
40
Punteggio
42
Salve a tutti, sono uno studente del 4o anno di Liceo Scientifico Tecnologico.
Il linguaggio di programmazione è C.
Ho creato con Dev C++ un programma con il quale posso calcolare la media e vedere l'orario.
Quando voglio vedere l'orario no problem però quando mi chiede se voglio fare altre operazioni va in autopilota selezioando No e mi chiude il programma
Quando voglio vedere la media, non mi mostra la funzione che ho creato
Che c'è di sbagliato?
Ecco il codice:

C:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void menu_operativo (int autenticazione);
void orario (int scegli, int autenticazione);
int calcola_media(int scegli, int autenticazione);
void menu_post_operazione(int scegli, int autenticazione);

int main(int argc, char *argv[])
{
    int autenticazione=0;
        
        printf("Inserire il codice utente: ");
        scanf("%d", &autenticazione);
            if(autenticazione == 123456)
            {
                menu_operativo(autenticazione);
            }
        else
            printf("Pin errato!");
            
    return 0;
}
void menu_operativo (int autenticazione)
{
    int scegli=0;
    float media=0;
    char ss;
    printf(" \n\n Bungiorno utente %d. \n Scelga l'operazione da effettuare: \n 1. Visione Orario \n 2. Calcola media \n 3. Arresta il sistema \n Scegli: ", autenticazione);
    scanf("%d", &scegli);
    
        switch(scegli)
        {
            case 1:
                printf("\n\n");
                orario(scegli, autenticazione);
            break;
            
            case 2:
                printf("\n\n");
                media = calcola_media(scegli, autenticazione);
                printf("La tua media e' =  %f ed e' ", media);
                    if(media<6)
                    {
                        printf("Insufficiente \n");
                    }
                    else printf("Sufficiente \n");
                    
            printf("Si vogliono fare altre operazioni? \n S = Si \n N = No");
            scanf("%c", &ss);
            
            switch(ss)
            {
                case 'S':
                    menu_post_operazione(scegli, autenticazione);
                break;
                
                case 'N':
                    printf("Chiusura programma. Grazie per l'utilizzo \n");
                break;
                
                default:
                    printf("Chiusura programma. Grazie per l'utilizzo \n");
                break;
                
            }
            break;
            
            case 3:
                printf("Chiusura programma in corso. Grazie per l'utilizzo\n\n");
            break;
            
            default:
                printf("Chiusura programma in corso. Grazie per l'utilizzo\n\n");
            break;
            
        }
}
void orario (int scegli, int autenticazione)
{
        int giorno=0;
        char nn;
        printf("Selezionare il giorno della settimana desiderato \n 1. Lunedi' \n 2. Martedi' \n 3. Mercoledi' \n 4. Giovedi' \n 5. Venerdi' \n 6. Sabato \n 7. Domenica \n");
        scanf("%d", &giorno);
        
        switch(giorno)
            {
                case 1:
                    printf("Orario del giorno Lunedi' \n\n");
                    
                    printf(" 1a ora \n ");
                    printf("2a ora \n ");
                    printf("3a ora  \n ");
                    printf("4a ora  \n ");
                    printf("5a ora  \n ");
                    printf("6a ora");
                    
                break;
                
                case 2:
                    printf("Orario del giorno Martedi' \n\n");
                    
                printf(" 1a ora \n ");
                    printf("2a ora \n ");
                    printf("3a ora  \n ");
                    printf("4a ora  \n ");
                    printf("5a ora  \n ");
                    printf("6a ora");
                    
                break;
                
                case 3:
                    printf("Orario del giorno Mercoledi' \n\n");
                    
                    printf(" 1a ora \n ");
                    printf("2a ora \n ");
                    printf("3a ora  \n ");
                    printf("4a ora  \n ");
                    printf("5a ora  \n ");
                    printf("6a ora");
                    
                break;
                
                case 4:
                    printf("Orario del giorno Giovedi' \n\n");
                    
                    printf(" 1a ora \n ");
                    printf("2a ora \n ");
                    printf("3a ora  \n ");
                    printf("4a ora  \n ");
                    printf("5a ora  \n ");
                    printf("6a ora");
                
                break;
                
                case 5:
                    printf("Orario del giorno Venerdi' \n\n");
                    
                    printf(" 1a ora \n ");
                    printf("2a ora \n ");
                    printf("3a ora  \n ");
                    printf("4a ora  \n ");
                    printf("5a ora  \n ");
                    printf("6a ora");
                    
                break;
                
                case 6:
                    printf("Orario del giorno Sabato \n");
                    printf("Non e' un giorno lavorativo \n");
                    
                break;
                
                case 7:
                    printf("Orario del giorno Domenica \n");
                    printf("Non e' un giorno lavorativo \n");
                    
                break;
                
                default:
                    printf("La scelta effettuata non e' corretta \n");
                break;
            }
            printf("\n\n");
            
        printf("Si vogliono fare altre operazioni? \n S = Si \n N = No");
            scanf("%c", &nn);
            
            switch(nn)
            {
                case 'S':
                    menu_post_operazione(scegli, autenticazione);
                break;
                
                case 'N':
                    printf("Chiusura programma. Grazie per l'utilizzo \n");
                break;
                
                default:
                    printf("Chiusura programma. Grazie per l'utilizzo \n");
                break;
            }
}
int calcola_media(int scegli, int autenticazione)
{
    float somma, media;
    int nvoti;
    float voti[nvoti];
    int i;
        
        printf(" Vuoi calcolare la media per quanti voti? \n Numero di voti =  ");
        scanf("%d", &nvoti);
            
            for(i=0; i<nvoti; i++)
            {
                printf("Inserisci il voto %d =  ", i+1);
                scanf("%f", &voti[i]);
                somma = somma + voti[i];
                printf("Somma = %f", somma);
            }
        media = somma / nvoti;

    return media;
}
void menu_post_operazione (int scegli, int autenticazione)
{
    int scegl;
    char ss;
    float media;
    printf("\n Scelga l'operazione da effettuare: \n 1. Visione Orario \n 2. Calcola media \n 3. Arresta il sistema \n Scegli: ");
    scanf("%d", &scegl);
        
    switch(scegl)
        {
            case 1:
                printf("\n\n");
                orario(scegli, autenticazione);
            break;
            
            case 2:
                printf("\n\n");
                calcola_media(scegli, autenticazione);
                printf("La tua media e' =  %f ed e' ", media);
                    if(media<6)
                    {
                        printf("Insufficiente \n");
                    }
                    else printf("Sufficiente \n");
                    
            printf("Si vogliono fare altre operazioni? \n S = Si \n N = No");
            scanf("%c", &ss);
            
            switch(ss)
            {
                case 'S':
                    menu_post_operazione(scegli, autenticazione);
                break;
                
                case 'N':
                    printf("Chiusura programma. Grazie per l'utilizzo \n");
                break;
                
                default:
                    printf("Chiusura programma. Grazie per l'utilizzo \n");
                break;
            }
    }
}
 
Il problema dell'orario lo risolvi facilmente. E' dovuto al fatto che la funzione scanf lascia il carattere di "nuova riga" (new line) nel buffer. Quindi quando vai a riutilizzare la lettura del carattere, viene in realtà letto il carattere presente nel buffer: new line, e quindi il programma termina.
Lo risolvi in questo modo: scanf(" %c", &nn);, aggiungendo uno spazio davanti allo specificatore di formato.

Nell'altra funzione hai un errore abbastanza grave, trattandosi di un errore di segmentazione. Il problema è il modo in cui inizializzi l'array, non puoi fare questo:

C:
    int nvoti;
    float voti[nvoti];

perchè la variabile "nvoti" non ha un valore definito, e per altro sarà sicuramente molto grande, quindi non vi è spazio sufficiente sullo stack (ecco perchè crasha tutto).
Dovresti inizializzare l'array in questo modo:

C:
   scanf("%d", &nvoti);
   float voti[nvoti];

quindi dopo la lettura di nvoti.

Domanda: ma a scuola non vi insegnano ad usare un debugger, o non accennano nemmeno al loro utilizzo? Questi problemi li troveresti subito (e quando avrai un pò più di esperienza sarà sufficiente guardare il codice per trovare questi problemi ?).

Un'ultima cosa: stai attento perchè la tua funzione della media torna un int, ma tu passi un float. Il valore verrà quindi troncato, perdi la precisione.
 
Tra l’altro l’espressione float voti[nvoti]; in C ti darà subito errore di compilazione, in quanto in C quella è la dichiarazione di un array statico e quindi la dimensione deve essere una costante nota durante la compilazione, per allocare un array dinamico in C occorre usare malloc() e successivamente free(). Ti va bene che usi un compilatore c++
In quel contesto è comunque inutile creare un array, in quanto ti basta leggere un valore a aggiungerlo alla somma, visto che i singoli valori non li usi più.

Piuttosto un grosso errore (colossale, ma tipico di chi inizia) è l’uso di una variabile non inizializzata (somma) che causa risultati imprevedibili. In questo caso somma va inizializzata a zero. Tra l’altro è un errore che dovrebbe essere riportato da qualsiasi compilatore “moderno”.

PS scusate se non ho formattato decentemente, sto usando un iPhone.
 
Tra l’altro l’espressione float voti[nvoti]; in C ti darà subito errore di compilazione, in quanto in C quella è la dichiarazione di un array statico e quindi la dimensione deve essere una costante nota durante la compilazione, per allocare un array dinamico in C occorre usare malloc() e successivamente free(). Ti va bene che usi un compilatore c++
In quel contesto è comunque inutile creare un array, in quanto ti basta leggere un valore a aggiungerlo alla somma, visto che i singoli valori non li usi più.

Piuttosto un grosso errore (colossale, ma tipico di chi inizia) è l’uso di una variabile non inizializzata (somma) che causa risultati imprevedibili. In questo caso somma va inizializzata a zero. Tra l’altro è un errore che dovrebbe essere riportato da qualsiasi compilatore “moderno”.

PS scusate se non ho formattato decentemente, sto usando un iPhone.

Mi ero perso la variabile "somma" non inizializzata.

Comunque solo una correzione riguardo all'inizializzazione dell'array dopo aver letto da tastiera, ovvero:
C:
scanf("%d", &n);
int array[n];

questo in C99 è valido, si tratta di VLA (variable length array), quindi non ci sono errori in compilazione.


Nel codice ci sono comunque altre cose che si potrebbero migliorare; ma le lascio per dopo, prima attendiamo una tua risposta. @Francesco C.
 
Tra l’altro l’espressione float voti[nvoti]; in C ti darà subito errore di compilazione, in quanto in C quella è la dichiarazione di un array statico e quindi la dimensione deve essere una costante nota durante la compilazione, per allocare un array dinamico in C occorre usare malloc() e successivamente free(). Ti va bene che usi un compilatore c++
In quel contesto è comunque inutile creare un array, in quanto ti basta leggere un valore a aggiungerlo alla somma, visto che i singoli valori non li usi più.

Piuttosto un grosso errore (colossale, ma tipico di chi inizia) è l’uso di una variabile non inizializzata (somma) che causa risultati imprevedibili. In questo caso somma va inizializzata a zero. Tra l’altro è un errore che dovrebbe essere riportato da qualsiasi compilatore “moderno”.

PS scusate se non ho formattato decentemente, sto usando un iPhone.
Ciao, visto che ci sono anche voti decimali, tipo 7 e mezzo, se lo inserisco in un array di tipo intero crasha tutto, ci ho provato.
Però nessun debugger o compilatore mi ha dato problemi di varibabili, andavano senza problemi...

Non me ne ero proprio accorto dell'inizializzazione di somma, lo farò subito, comunque anche in questo caso non mi da nessun errore, al massimo mi esce un valore completamente random. Grazie!
--- i due messaggi sono stati uniti ---
ma a scuola non vi insegnano ad usare un debugger, o non accennano nemmeno al loro utilizzo? Questi problemi li troveresti subito (e quando avrai un pò più di esperienza sarà sufficiente guardare il codice per trovare questi problemi ?).
Ciao guarda, a scuola utilizzo questo mentre a casa utilizzo Dev C++. Però utilizziamo solo la funzione di compilatore, non di debugger.

In quel contesto è comunque inutile creare un array, in quanto ti basta leggere un valore a aggiungerlo alla somma, visto che i singoli valori non li usi più.
So che sarebbe inutile e che con un for userei una variabile per sommare tutti i voti però volendomi esercitare un po' su tutto ho preferito usare gli array.
 
Ciao a tutti, ho modificato il codice come consigliato e va benissimo! Adesso una cosa:
alcuni utenti mi hanno detto "alcuni compilatori moderni dovrebbero segnalare il problema" per una variabile non inizializzata. Ci sono dei compilatori tipo Dev C++ che mi permette di compilare in C, ovviamente che si scarica e abbia la funzione di compilatore?

Ovviamente, avendo fatto molti programmi con Dev, vorrei la possibilità di aprire i codici di Dev ancge su un nuovo compilatore.

Grazie a chi risponderà!
 
In ambiente Windows hai almeno due scelte. Innanzitutto cosa importante: i compilatori prendono codice in C e creano il tuo eseguibile.
Poi ci sono gli editor di test o gli IDE, che sono strumenti molto più potenti, e ti segnalano di tutto e di più.

In Windows puoi usare Visual Studio come IDE, che ha come compilatore MSVC, o scaricare MinGw come compilatore. Questi li devi scaricare a parte, poi l'editor sta a te.
Visual studio puoi usarlo anche per compilare con Mingw.

Ci sono un sacco di alternative. L'ottimo clion a pagamento, piuttosto di Atom o Visual Studio Code.
 
In ambiente Windows hai almeno due scelte. Innanzitutto cosa importante: i compilatori prendono codice in C e creano il tuo eseguibile.
Poi ci sono gli editor di test o gli IDE, che sono strumenti molto più potenti, e ti segnalano di tutto e di più.

In Windows puoi usare Visual Studio come IDE, che ha come compilatore MSVC, o scaricare MinGw come compilatore. Questi li devi scaricare a parte, poi l'editor sta a te.
Visual studio puoi usarlo anche per compilare con Mingw.

Ci sono un sacco di alternative. L'ottimo clion a pagamento, piuttosto di Atom o Visual Studio Code.
Perfetto grazie!
--- i due messaggi sono stati uniti ---
Grazie a tutti per i vari consigli!
Buona Serata
 
C'è anche il classico editor di testo e GCC per compilare. Se hai Windows 10 puoi installare la bash di Linux.
Ovviamente qui devi compilare tu a mano e non hai il tastino di run :)

Comunque visual studio code è ottimo
 
Stato
Discussione chiusa ad ulteriori risposte.
Pubblicità
Pubblicità
Indietro
Top