Visualizzazione dei risultati da 1 a 10 su 10

Discussione: [C] scanf ?

  1. #1

    [C] scanf ?

    Se è possibile dovrei risolvere per domani, grazie.
    Questa funzione, funziona. Fa quello che deve, posso poi continuare con tutte le altre operazioni e tutto va bene. Ma, quando chiudo il programma, sia da selezione del menu che ho creato, sia direttamente la finestra, mi va in segmentazione. SOLO se ho usato questa funzione di inserimento dati.
    Se cancello lo studente inserito non da più problemi. !?
    Se da questa funzione elimino le scanf alle stringhe nome e cognome... nessun problema. Davvero non capisco.

    codice:
    void inserisciStudente(STUDENTE* studenti) {
        int i;
        char ch;
    
        system("cls");
         fflush(stdin);
         printf("INSERIMENTO NUOVO STUDENTE \n\n");
         fflush(stdin);
         printf("\nNome: ");
         scanf("%49[^\n]", studenti[n_stud].nome);
         fflush(stdin);
         printf("Cognome: ");
         scanf("%49[^\n]", studenti[n_stud].cognome);
         studenti[n_stud].matricola = ++matricola;
         printf("Matricola assegnata: 00%d\n\n", matricola);
         printf("Inserire voti\n(zero per esame non sostenuto):\n\n");
         for(i = 0; i < NUM_MAT; i++) {
              printf("\t\t%s: ", materia[i].materia);
              studenti[n_stud].voto[i] = controlloValore(VOTO_MIN, VOTO_MAX);
         }
         n_stud++;
         printf("\n\n");
         system("PAUSE");
         return;
    }

    malloc iniziale:

    codice:
    studenti = (STUDENTE*)malloc(MAX_STUD * sizeof(STUDENTE));

    cancella studente:

    codice:
    void cancellaStudente(STUDENTE* studenti) {
        int i, j, elimina;
    
        system("cls");
         fflush(stdin);
        printf("CANCELLAZIONE STUDENTE\n\n");
        if(n_stud == 0) {
              printf("Archivio studenti vuoto!\n\n");
        }
        else {
              printf("Numero di matricola dello studente da eliminare: ");
              elimina = controlloValore(MIN_MATRICOLA, MAX_MATRICOLA);
              for(i = 0; i < n_stud; i++) {
                   if(studenti[i].matricola == elimina) {
                        printf("\n\nOperazione avvenuta con successo!\n");
                        printf("Lo studente %s %s e' stato rimosso dall'archivio.\n\n", studenti[i].nome, studenti[i].cognome);
                        for(j = i; j < n_stud; j++) {
                             studenti[j] = studenti[j + 1];
                        }
                        n_stud--;
                        system("PAUSE");
                        return;
                   }
              }
              printf("\n\nIl numero di matricola inserito non e' in archivio.\n\n");
        }
         system("PAUSE");
         return;
    }

    strutture dati:

    codice:
    typedef struct STUDENTE{
        char nome[50];
        char cognome[50];
        int matricola;
        int voto[NUM_MAT];
    }STUDENTE;
    
    struct I_anno{
        char materia[50];
    } materia[NUM_MAT] = {{"Programmazione"},{"Analisi"},{"Algebra e Geometria"},{"Architetture"},{"Inglese"},{"Algoritmi"};

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Ci mostri il codice del menu ?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Questo è tutto, così è testabile.

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_STUD 200
    #define NUM_MAT 6
    #define MIN_MATRICOLA 1
    #define MAX_MATRICOLA 200
    #define VOTO_MIN 18
    #define VOTO_MAX 30
    
    int n_stud = 0;
    int matricola = 0;
    
    // DICHIARAZIONE STRUTTURA
    
    typedef struct STUDENTE{
        char nome[50];
        char cognome[50];
        int matricola;
        int voto[NUM_MAT];
    }STUDENTE;
    
    struct I_anno{
        char materia[50];
    } materia[NUM_MAT] = {{"Programmazione"},{"Analisi"},{"Algebra e Geometria"},{"Architetture"},{"Inglese"},{"Algoritmi"}};
    
    // PROTOTIPI FUNZIONE
    
    int controlloValore(int, int);
    void inserisciStudente(STUDENTE*);
    void nuoviInserimenti(STUDENTE*, int);
    void cancellaStudente(STUDENTE*);
    void cercaStudente(STUDENTE*);
    void stampaArchivio(STUDENTE*);
    void noEsame(STUDENTE*);
    void fuoriCorso(STUDENTE*);
    
    
    //INIZIO MAIN
    
    int main() {
    
        int i, end = 0;
        char ch[1];
        STUDENTE* studenti;
    
         studenti = (STUDENTE*)malloc(MAX_STUD * sizeof(STUDENTE));
         if(studenti == NULL) {
              printf("Errore di allocazione!\n\n");
              system("PAUSE");
              return;
         }
        do {
            system("cls");
            printf("SEGRETERIA STUDENTI\n\n\n");
            printf("Scegli un'operazione selezionando il codice\n(Premere 'Q' per terminare)\n\n\n");
            printf("A -> inserisci studente \nB -> fuori corso \nC -> cerca studente\n");
            printf("D -> cancella studente \nE -> archivio studenti \nF -> esame non dato\n\nSelezione: ");
              scanf("%s", ch);
              strupr(ch);
    
    
            switch(ch[0]) {
                   case 'A':
                        inserisciStudente(studenti);
                        break;
                   case 'B':
                        fuoriCorso(studenti);
                        break;
                   case 'C':
                        cercaStudente(studenti);
                        break;
                   case 'D':
                        cancellaStudente(studenti);
                        break;
                   case 'E':
                        stampaArchivio(studenti);
                        break;
                   case 'F':
                        noEsame(studenti);
                        break;
                   case 'Q':
                        end++;
                        break;
                   default:
                        fflush(stdin);
                        printf("\n\nCodice operazione non corretto.\n\n");
                        system("PAUSE");
                        break;
                   }
         }
         while(end == 0);
         free(studenti);
         return 0;
    }
    
    
    // FUNZIONE INSERIMENTO STUDENTE
    
    
    void inserisciStudente(STUDENTE* studenti) {
        int i;
        char ch;
    
    
        system("cls");
         fflush(stdin);
         printf("INSERIMENTO NUOVO STUDENTE \n\n");
         fflush(stdin);
         printf("\nNome: ");
         scanf("%49[^\n]", studenti[n_stud].nome);
         fflush(stdin);
         printf("Cognome: ");
         scanf("%49[^\n]", studenti[n_stud].cognome);
         studenti[n_stud].matricola = ++matricola;
         printf("Matricola assegnata: 00%d\n\n", matricola);
         printf("Inserire voti\n(zero per esame non sostenuto):\n\n");
         for(i = 0; i < NUM_MAT; i++) {
              printf("\t\t%s: ", materia[i].materia);
              studenti[n_stud].voto[i] = controlloValore(VOTO_MIN, VOTO_MAX);
         }
         n_stud++;
         printf("\n\n");
         system("PAUSE");
         return;
    }
    
    
    // FUNZIONE CANCELLA STUDENTE
    
    
    void cancellaStudente(STUDENTE* studenti) {
        int i, j, elimina;
    
    
        system("cls");
         fflush(stdin);
        printf("CANCELLAZIONE STUDENTE\n\n");
        if(n_stud == 0) {
              printf("Archivio studenti vuoto!\n\n");
        }
        else {
              printf("Numero di matricola dello studente da eliminare: ");
              elimina = controlloValore(MIN_MATRICOLA, MAX_MATRICOLA);
              for(i = 0; i < n_stud; i++) {
                   if(studenti[i].matricola == elimina) {
                        printf("\n\nOperazione avvenuta con successo!\n");
                        printf("Lo studente %s %s e' stato rimosso dall'archivio.\n\n", studenti[i].nome, studenti[i].cognome);
                        for(j = i; j < n_stud; j++) {
                             studenti[j] = studenti[j + 1];
                        }
                        n_stud--;
                        system("PAUSE");
                        return;
                   }
              }
              printf("\n\nIl numero di matricola inserito non e' in archivio.\n\n");
        }
         system("PAUSE");
         return;
    }
    
    
    // FUNZIONE RICERCA SINGOLO STUDENTE
    
    
    void cercaStudente(STUDENTE* studenti) {
    
    
        char ch[1], cerca_nome[50], cerca_cognome[50];
        int i, j, conta = 0, cerca_matricola;
    
    
        system("cls");
        printf("RICERCA STUDENTE \n\n");
    
    
        if(n_stud == 0) {
              printf("Archivio studenti vuoto!\n\n");
              system("PAUSE");
              return;
        }
        fflush(stdin);
        printf("Scegli il tipo di ricerca da effettuare: \n\n\nNome       -->  (N)\nCognome    -->  (C)\nMatricola  -->  (M)\n\n\nInserisci il codice:  ");
        scanf("%s", &ch[0]);
        strupr(ch);
        switch(ch[0]) {
            case 'N':
                fflush(stdin);
                printf("\n");
                   printf("Digita il nome dello studente:  ");
                scanf("%s", cerca_nome);
                for(i = 0; i < n_stud; i++) {
                    if(strcmp(studenti[i].nome, cerca_nome) == 0) {
                             conta++;
                        printf("\n\nMatricola: %d\n", studenti[i].matricola);
                             printf("\nNome: %s %s, ", studenti[i].nome, studenti[i].cognome);
                             printf("\n\n\tVoti: \n");
                             for(j = 0; j < NUM_MAT; j++) {
                                  printf("\t%s: %d\n", materia[j].materia, studenti[i].voto[j]);
                             }
                    }
                }
                if(conta == 0) {
                        printf("\n\nNome non trovato!\n\n");
                }
                break;
            case 'C':
                fflush(stdin);
                printf("\n");
                printf("Digita il cognome dello studente:  ");
                scanf("%s", cerca_cognome);
                for(i = 0; i < n_stud; i++) {
                    if(strcmp(studenti[i].cognome, cerca_cognome) == 0) {
                             conta++;
                        printf("\n\nMatricola: %d\n", studenti[i].matricola);
                             printf("\nNome: %s %s, ", studenti[i].nome, studenti[i].cognome);
                             printf("\n\n\tVoti: \n");
                             for(j = 0; j < NUM_MAT; j++) {
                                  printf("\t%s: %d\n", materia[j].materia, studenti[i].voto[j]);
                             }
                    }
                }
                if(conta == 0) {
                        printf("\n\nCognome non trovato!\n\n");
                }
                break;
            case 'M':
                fflush(stdin);
                printf("\n");
                printf("Digita la matricola dello studente:  ");
                scanf("%d", &cerca_matricola);
                for(i = 0; i < n_stud; i++) {
                    fflush(stdin);
                    if(studenti[i].matricola == cerca_matricola) {
                             conta++;
                        printf("\n\nMatricola: %d\n", studenti[i].matricola);
                             printf("\nNome: %s %s, ", studenti[i].nome, studenti[i].cognome);
                             printf("\n\n\tVoti: \n");
                             for(j = 0; j < NUM_MAT; j++) {
                                  printf("\t%s: %d\n", materia[j].materia, studenti[i].voto[j]);
                             }
                    }
                }
                if(conta == 0) {
                        printf("\n\nMatricola non trovata!\n\n");
                }
                break;
            default:
                printf("\n\nIl carattere inserito non corrisponde a nessuna delle scelte possibili.\n");
                   system("PAUSE");
                   return;
        }
        printf("\n\n");
        system("PAUSE");
         return;
    }
    
    
    // FUNZIONE STAMPA ARCHIVIO
    
    
    void stampaArchivio(STUDENTE* studenti) {
        int i, j;
    
    
        system("cls");
        fflush(stdin);
        printf("ARCHIVIO STUDENTI\n\n");
        if(n_stud == 0) {
              printf("Archivio studenti vuoto!\n\n");
              system("PAUSE");
              return;
        }
         i = 0;
         do {
              printf("\nMatricola: %d\n", studenti[i].matricola);
              printf("\nNome: %s %s, ", studenti[i].nome, studenti[i].cognome);
              printf("\n\n\tVoti: \n\n");
              for(j = 0; j < NUM_MAT; j++) {
                   printf("\t%s: %d\n", materia[j].materia, studenti[i].voto[j]);
              }
              i++;
         } while(i < n_stud);
         printf("\n\n");
        system("PAUSE");
        return;
    }
    
    
    // STUDENTI SENZA SPECIFICO ESAME
    
    
    void noEsame(STUDENTE* studenti) {
         int i, j, ID_esame, flag;
    
    
         system("cls");
         printf("STUDENTI SENZA SPECIFICO ESAME\n\n\n");
    
    
         if(n_stud == 0) {
              printf("Archivio studenti vuoto!\n\n");
              system("PAUSE");
              return;
        }
         printf("Elenco esami:\n\n");
         printf("01 -> Programmazione\n");
         printf("02 -> Analisi\n");
         printf("03 -> Algebra e Geometria\n");
         printf("04 -> Architetture\n");
         printf("05 -> Inglese\n");
         printf("06 -> Algoritmi\n\n");
    
    
         printf("Scegli codice: ");
         scanf("%d", &ID_esame);
    
    
         printf("\nChi non ha dato %s:\n\t", materia[ID_esame - 1].materia);
         flag = 0;
         for(i = 0; i < n_stud; i++) {
              for(j = 0; j < NUM_MAT; j++) {
                   if(studenti[i].voto[ID_esame - 1] == 0) {
                        flag++;
                   }
              }
              if(flag) {
                   printf("\nMatricola %d: ", studenti[i].matricola);
                   printf("%s %s", studenti[i].nome, studenti[i].cognome);
              }
         }
         if(!flag) {
              printf("\n\n\n\tNessuno, tutti bravi qua dentro.\n\n");
         }
         printf("\n\n");
         system("PAUSE");
         return;
    }
    
    
    // FUNZIONE FUORI CORSO
    
    
    void fuoriCorso(STUDENTE* studenti) {
         int i, j, flag_1, flag_2;
    
    
         system("cls");
         printf("STUDENTI FUORI CORSO\n\n\n");
         if(n_stud == 0) {
              printf("Archivio studenti vuoto!\n\n");
              system("PAUSE");
              return;
        }
         flag_2 = 0;
         for(i = 0; i < n_stud; i++) {
              flag_1 = 0;
              for(j = 0; j < NUM_MAT; j++) {
                   if(studenti[i].voto[j] == 0) {
                        flag_1++;
                        flag_2++;
                   }
              }
              if(flag_1 > 0) {
                   printf("\nMatricola: %d\n", studenti[i].matricola);
                   printf("Nome: %s %s, ", studenti[i].nome, studenti[i].cognome);
                   printf("\n\nEsami non sostenuti: \n\n");
                   for(j = 0; j < NUM_MAT; j++) {
                        if(studenti[i].voto[j] == 0)
                        printf("\t%s\n", materia[j].materia);
                   }
              }
         }
         if(flag_2 == 0) {
              printf("Nessuno studente fuoricorso.\n\n");
         }
         system("PAUSE");
         return;
    }
    
    
    // FUNZIONE CONTROLLO VALORE
    
    
    int controlloValore(int MIN, int MAX) {                 // tramite min e max posso usare la funzione senza modificarla di volta in volta
        int valore, check;
    
    
        do {
            fflush(stdin);
            check = scanf("%d", &valore);
            if(check) {                                // c restituisce valori booleani quindi chiedo se check esiste(1) cioè se è stato letto valore
                if(valore >= MIN && valore <= MAX || valore == 0) {        // se è corretto..
                    check = 1;                         // check è 1 , TRUE
                }
                else {                                  // altrimenti FALSE e resto nel ciclo
                    check = 0;
                    printf("\t\tValore non corretto.\n\t\tInserisci un valore tra %d e %d: ", MIN, MAX);
                }
            }
            else {
                check = 0;
                printf("\t\tValore non corretto.\n\t\tInserisci un valore tra %d e %d: ", MIN, MAX);
            }
        }
        while(!check);                                        // fin che check = 0
         return valore;
    }

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Il problema è in

    char ch[1];

    Per l'input con scanf della stringa devi prevedere lo spazio per il terminatore, quindi almeno 2 caratteri.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Dato che ti serve leggere un solo carattere, valuta la possibilità di evitare l'uso di una stringa, e della variabile di stato per uscire dal ciclo.
    codice:
    int main()
    {
        STUDENTE* studenti;
        studenti = (STUDENTE*)malloc(MAX_STUD * sizeof(STUDENTE));
        if(studenti == NULL)
        {
            printf("Errore di allocazione!\n\n");
            getchar();
            return -1;
        }
        
        do
        {
            system("cls");
            printf("SEGRETERIA STUDENTI\n\n\n");
            printf("Scegli un'operazione selezionando il codice\n(Premere 'Q' per terminare)\n\n\n");
            printf("A -> inserisci studente \nB -> fuori corso \nC -> cerca studente\n");
            printf("D -> cancella studente \nE -> archivio studenti \nF -> esame non dato\n\nSelezione: ");
            switch( toupper( getchar() ) )
            {
                case 'A':
                    inserisciStudente(studenti);
                break;
                case 'B':
                    fuoriCorso(studenti);
                break;
                case 'C':
                    cercaStudente(studenti);
                break;
                case 'D':
                    cancellaStudente(studenti);
                break;
                case 'E':
                    stampaArchivio(studenti);
                break;
                case 'F':
                    noEsame(studenti);
                break;
                case 'Q':
                    free(studenti);
                return 0;
            }
        }
        while(1);
    }
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  6. #6
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Il problema è in

    char ch[1];

    Per l'input con scanf della stringa devi prevedere lo spazio per il terminatore, quindi almeno 2 caratteri.
    Grazie! era quello. Inizialmente avevo messo 2 per il terminatore appunto, poi non so perché lo avevo modificato.
    Perfetto.
    Come codice è scritto decentemente?

  7. #7
    Quote Originariamente inviata da Samuele_70 Visualizza il messaggio
    Dato che ti serve leggere un solo carattere, valuta la possibilità di evitare l'uso di una stringa, e della variabile di stato per uscire dal ciclo.
    [code]
    Mi piace complicarmi la vita, volevo gestire una stringa. Non sapevo come uppare un char dato che strupr vuole una stringa... toupper, grazie, così è meglio in effetti.

  8. #8
    La toupper(), a differenza della strupr() è una soluzione portabile, infatti questa funzione è standard e la si può usare compilando su qualsiasi piattaforma.
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  9. #9
    Quindi conviene usare le funzioni toupper/lower/etc.. anche se devo leggere del testo, inserendole in dei cicli?

  10. #10
    Si, e probabilemnte è quello che fanno funzioni come la strupr
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.