RISOLTO Programma gestione diario

Stato
Discussione chiusa ad ulteriori risposte.

Andretti60

Utente Èlite
6,440
5,091
Non capisco cosa tu voglia dire.
Sto parlando di condizioni di errore.
Inoltre da nessuna parte del tuo programma dici all’utente che la pwd sia un numero. In genere non lo è, è una stringa di caratteri con certe condizioni. Ripeto, come esercizio va bene che usi un numero come pwd, ma
  1. Lo devi dire all’utente
  2. Devi assicurarti che il numero venga letto, convertito e memorizzato correttamente
Non sto lavorando solo con interi?
 
  • Mi piace
Reazioni: Vito-

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Lasciamo poi perdere che la password debba essere criptata (questo è un esercizio, si può iniziare senza).
Si, più che criptata forse andrebbe fatto l'hash e mantenuto quello.
Ma entrambi i metodi non sarebbero sicuri, in quanto aggirarlo - se fosse un software reale - rimarrebbe comunque semplicissimo.

Non sto lavorando solo con interi?
Non conta questo, conta se è possibile che l'utente che userà il tuo programma commetta errori. E di solito se ha 1 probabilità su 1000 di commettere un errore o di far emergere un caso a cui non avevi pensato... stai pur certo che lo farà, e sarà probabilmente al primo tentativo.
Devi sempre testare i valori restituiti dalle funzioni, tanto su una scanf quanto su un fopen o malloc o altro ancora.

La funzione di cambiopassword ad esempio la modificherei. Passi lo switch, anche se probabilmente userei un if/elseif/else. Dovresti restituire un messaggio in caso si prema 2, per avvertire che l'operazione è stata annullata (o una frase simile).
Invece di usare una funzione che restituisce un void, restituire un boolean: true se la password è stata cambiata, o false in caso contrario.

Non lascerei nemmeno i messaggi dentro a quella funzione, ma la utilizzerei unicamente per elaborare la scelta fatta e ottenere il risultato (true/false).
In C puoi usare l'include file stdbool.h per avere TRUE/FALSE, altrimenti anche senza questo include usi i valori 0 e 1 (false e true).

Rivedrei anche il parametro che passi alla funzione.
Inoltre appunto dovresti salvarla, ciò implica che la password dovrai leggerla da file (magari appunto salverai l'hash, e non la password... ma al momento tienilo pure così, senza complicarti la vita).

Ps. il forum ha l'automerge, ma se vuoi aggiungere altro al tuo intervento, puoi premere su Modifica. ?
 
  • Mi piace
Reazioni: Vito-

Vito-

Utente Attivo
184
14
Ok. Per il fatto della password sul file ho pensato di far finta che al primo avvio ti diano una passw che poi tu dovrai cambiare (con la funzione appostia). Infatti ho creato un file con la password che poi puo essere cambiata cambiando il contenuto del file.
Ho una domanda. Perché quando leggo la password dal file con fscanf mi dice password errata mentre con fread funziona?
P.s. Credo a questo punto di non aver capito bene la differenza tra le due

C:
#include <stdio.h>
#include <stdlib.h>
#define N 20

typedef struct  {int giorno;
                 int mese;
                 int anno;
                }datazione;

typedef struct  {int ore;
                 int minuti;
                }orario;

typedef struct  {char nome[N];
                 char descrizione[150];
                 char luogo[N];
                 orario ora;
                 datazione data;
                 char amici[N];
                 }record;

void menu();
void aggiungi_record();
void visualizza_record();
void cerca_record();
void modifica_record();
void elimina_record();
void cambia_password();

FILE *ptrPassword;

int main()
{
    menu();
    printf("\nCiao!\n");

    return(0);
}

void menu()
{
    int scelta, scelta_1, password, valPassword;

    ptrPassword = fopen("filePassword", "rb");
    if(ptrPassword)
    {
        fread(&valPassword, sizeof(int), 1, ptrPassword);
    }
    else
    {
        printf("Errore file");
    }
    fclose(ptrPassword);

    do
    {
        printf("\t\t\t\t**Benvenuti nel vostro diario personale**\n\nInserire la password per continuare (4 numeri):");
        scanf("%d", &password);

        if(password == valPassword)
        {

            system("cls");
            printf("Scegliere una delle seguenti opzioni:\n");
            printf("\n1 Aggiungi record");
            printf("\n2 Visualizza record");
            printf("\n3 Cerca record");
            printf("\n4 Modifica record");
            printf("\n5 Elimina record");
            printf("\n6 Cambia password");
            printf("\n7 Uscita\n");
            scanf("%d", &scelta);

            switch(scelta)
            {
                case 1:
                    system("cls");
                    aggiungi_record();
                    system("pause");
                    system("cls");
                    break;
                case 2:
                    system("cls");
                    visualizza_record();
                    system("pause");
                    system("cls");
                    break;
                case 3:
                    system("cls");
                    cerca_record();
                    system("pause");
                    system("cls");
                    break;
                case 4:
                    system("cls");
                    modifica_record();
                    system("pause");
                    system("cls");
                    break;
                case 5:
                    system("cls");
                    elimina_record();
                    system("pause");
                    system("cls");
                    break;
                case 6:
                    system("cls");
                    cambia_password();
                    system("pause");
                    system("cls");
                    break;
                case 7:
                    system("cls");
                    break;
                default:
                    system("cls");
                    printf("La scelta fatta non e' corretta\n\n");
            }
        }
        else
        {
            printf("\nPassword errata!!\n\n");
        }
        printf("Tornare al menu principale?\n");
        printf("\n1 Torna al menu principale");
        printf("\n2 Non tornare al menu principale\n");
        scanf("%d", &scelta_1);
        system("cls");
    }
    while(scelta_1 != 2);

}

void aggiungi_record()
{

}

void visualizza_record()
{
    printf("Ciao\n");
}

void cerca_record()
{
    printf("Ciao\n");
}

void modifica_record()
{
    printf("Ciao\n");
}

void elimina_record()
{
    printf("Ciao\n");
}

void cambia_password()
{

}
 

Andretti60

Utente Èlite
6,440
5,091
fread() legge in maniera NON formattata
fscanf() invece legge in maniera formattata.

Dipende quindi da come è scritto il file. Se la pwd la hai scritta usando fwrite() la devi leggere usando fread(). Lo stesso con fprintf() e fscanf()

Non mi piace come il programma inizia. Se il file con la pwd non è presente, significa che la pwd non è stata creata, quindi prima cosa che il tuo programma deve fare in quel caso è chiedere di generare una pwd e salvarla subito su file.
 
  • Mi piace
Reazioni: Moffetta88

Vito-

Utente Attivo
184
14
fread() legge in maniera NON formattata
fscanf() invece legge in maniera formattata.

Dipende quindi da come è scritto il file. Se la pwd la hai scritta usando fwrite() la devi leggere usando fread(). Lo stesso con fprintf() e fscanf()

Non mi piace come il programma inizia. Se il file con la pwd non è presente, significa che la pwd non è stata creata, quindi prima cosa che il tuo programma deve fare in quel caso è chiedere di generare una pwd e salvarla subito su file.
Ok grazie.
Per quanto riguarda la creazione della password ci avevo pensato anch'io, pero non so come evitare che ogni volta che apro il programma mi chiede di creare la password. Questo deve avvenire alla prima apertura.
Oppure credo un if else iniziale che chiede se é stata gia creata la password...
 

Vito-

Utente Attivo
184
14
Rileggi quello che ho scritto:

Se il file con la pwd non è presente allora…
ahh, quindi vedo se fopen non da null


Ok, non credo di riuscire a fare meglio di cosi. Ora mi mancano le altre funzioni?
C:
#include <stdio.h>
#include <stdlib.h>
#define N 20

typedef struct  {int giorno;
                 int mese;
                 int anno;
                }datazione;

typedef struct  {int ore;
                 int minuti;
                }orario;

typedef struct  {char nome[N];
                 char descrizione[150];
                 char luogo[N];
                 orario ora;
                 datazione data;
                 char amici[N];
                 }record;

void menu(int valPassword);
void aggiungi_record();
void visualizza_record();
void cerca_record();
void modifica_record();
void elimina_record();
void cambia_password(int valPassword);

FILE *ptrPassword;

int main()
{
    int valPassword=0, valPassword1=0, Scelta=0;

    ptrPassword = fopen("filePassword", "rb");
    if(ptrPassword)
    {
        fread(&valPassword, sizeof(int), 1, ptrPassword);
        menu(valPassword);
    }
    else
    {
        printf("\t\t\t\t**Benvenuti nel vostro diario personale**\n\n"
               "Per il primo avvio e' necessario creare una password di accesso\nVuoi creare una nuova password?\n1 Si\n2 No\n");
        scanf("%d", &Scelta);
        switch(Scelta)
        {
            case 1:
                system("cls");
                printf("Inserire una password che contenga 4 numeri: ");
                scanf("%d", &valPassword1);
                printf("Inserire nuovamente la password: ");
                scanf("%d", &valPassword);
                if(valPassword==valPassword1)
                {
                    ptrPassword = fopen("filePassword", "wb");
                    if(ptrPassword)
                    {
                        fwrite(&valPassword, sizeof(int), 1, ptrPassword);
                        printf("\nPassword creata correttamente.\nRiavviare il programma per salvare le modifiche.\n\n");
                    }
                    else
                    {
                        printf("Errore di file");
                    }
                fclose(ptrPassword);
                }
                else
                {
                    printf("\nLe due password non coincidono");
                }
                break;
            case 2:
                break;
            default:
                printf("La scelta effettuata non e' corretta");
        }
    }

    return(0);
}

void menu(int valPassword)
{
    int scelta, scelta_1, password;

    do
    {
        printf("\t\t\t\t**Benvenuti nel vostro diario personale**\n\nInserire la password per continuare (4 numeri):");
        scanf("%d", &password);

        if(password == valPassword)
        {

            system("cls");
            printf("Scegliere una delle seguenti opzioni:\n");
            printf("\n1 Aggiungi record");
            printf("\n2 Visualizza record");
            printf("\n3 Cerca record");
            printf("\n4 Modifica record");
            printf("\n5 Elimina record");
            printf("\n6 Cambia password");
            printf("\n7 Uscita\n");
            scanf("%d", &scelta);

            switch(scelta)
            {
                case 1:
                    system("cls");
                    aggiungi_record();
                    system("pause");
                    system("cls");
                    break;
                case 2:
                    system("cls");
                    visualizza_record();
                    system("pause");
                    system("cls");
                    break;
                case 3:
                    system("cls");
                    cerca_record();
                    system("pause");
                    system("cls");
                    break;
                case 4:
                    system("cls");
                    modifica_record();
                    system("pause");
                    system("cls");
                    break;
                case 5:
                    system("cls");
                    elimina_record();
                    system("pause");
                    system("cls");
                    break;
                case 6:
                    system("cls");
                    cambia_password(valPassword);
                    system("pause");
                    system("cls");
                    break;
                case 7:
                    system("cls");
                    break;
                default:
                    system("cls");
                    printf("La scelta fatta non e' corretta\n\n");
            }
        }
        else
        {
            printf("\nPassword errata!!\n\n");
        }
        printf("Tornare al menu principale?\nSe e' stata cambiata la password e' necessario riavviare programma per salvare le modifiche\n");
        printf("\n1 Torna al menu principale");
        printf("\n2 Non tornare al menu principale\n");
        scanf("%d", &scelta_1);
        system("cls");
    }
    while(scelta_1 != 2);

}

void aggiungi_record()
{

}

void visualizza_record()
{
    printf("Ciao\n");
}

void cerca_record()
{
    printf("Ciao\n");
}

void modifica_record()
{
    printf("Ciao\n");
}

void elimina_record()
{
    printf("Ciao\n");
}

void cambia_password(int valPassword)
{
    int scelta=0, oldPassword=0, newPassword=0, newnewPassword=0;

    printf("Sei sicuro di voler cambiare la password?\n1 Si\n2 No\n");
    scanf("%d", &scelta);
    switch(scelta)
    {
        case 1:
            system("cls");
            printf("Digitare la vecchia password: ");
            scanf("%d", &oldPassword);
            if(oldPassword==valPassword)
            {
                printf("Digitare la nuova password (4 numeri): ");
                scanf("%d", &newPassword);
                printf("Digitare nuovamente la nuova password: ");
                scanf("%d", &newnewPassword);
                if(newnewPassword==newPassword)
                {
                    ptrPassword = fopen("filePassword", "wb");
                    if(ptrPassword)
                    {
                        fwrite(&newnewPassword, sizeof(int), 1, ptrPassword);
                    }
                    else
                    {
                        printf("Errore di file");
                    }
                }
                else
                {
                    printf("Le password non sono uguali\n");
                }
            }
            else
            {
                printf("Errore\n");
            }
            break;
        case 2:
            break;
        default:
            printf("La scelta fatta non e'corretta\n");
    }
}
 
Ultima modifica:

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Gli handle ai file vanno sempre chiusi, tu stai sovrascrivendo quello della lettura invece di chiuderlo. Inoltre prima di chiuderlo, così come prima di liberare della memoria quando userai malloc, ricordati di verificare che il puntatore non sia NULL.

Per l'inserimento della pwd sarebbe meglio un ciclo comunque. Se uno digita male non è giusto che si trovi costretto ad avviare nuovamente il programma.
Andrebbero anche utilizzate funzioni aggiuntive per non scrivere tutto lo scibile nel singolo case.

Inoltre, le funzioni di creazione pwd e di modifica sono praticamente uguali. Non dovresti avere due porzioni di codici uguali. Se sono uguali, significa che puoi richiamarle all'occorrenza (una funzione).
 
  • Mi piace
Reazioni: Andretti60

Vito-

Utente Attivo
184
14
Gli handle ai file vanno sempre chiusi, tu stai sovrascrivendo quello della lettura invece di chiuderlo. Inoltre prima di chiuderlo, così come prima di liberare della memoria quando userai malloc, ricordati di verificare che il puntatore non sia NULL.
cos'é un handle?
Nel senso che dopo il primo fopen dovrei mettere un fclose?
Per l'inserimento della pwd sarebbe meglio un ciclo comunque. Se uno digita male non è giusto che si trovi costretto ad avviare nuovamente il programma.
Andrebbero anche utilizzate funzioni aggiuntive per non scrivere tutto lo scibile nel singolo case.
do while magari?
Post unito automaticamente:

Inoltre, le funzioni di creazione pwd e di modifica sono praticamente uguali. Non dovresti avere due porzioni di codici uguali. Se sono uguali, significa che puoi richiamarle all'occorrenza (una funzione).
Nel main non posso richiamare la funzione modifica password perche all'inizio manca la vecchia password da inserire
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
cos'é un handle?
Nel senso che dopo il primo fopen dovrei mettere un fclose?
Il riferimento al file che hai aperto.
Dovresti metterlo dopo la lettura che fai visto che poi non lo utilizzi più e lo vai a sovrascrivere con l'altra fopen per la scrittura.

do while magari?
Post unito automaticamente:
Si, può andar bene.
Nel main non posso richiamare la funzione modifica password perche all'inizio manca la vecchia password da inserire
Mi riferisco a queste parti di codice: https://www.diffchecker.com/XaAyWYiG
C:
                printf("Digitare la nuova password (4 numeri): ");
                scanf("%d", &newPassword);
                printf("Digitare nuovamente la nuova password: ");
                scanf("%d", &newnewPassword);
                if(newnewPassword==newPassword)
                {
                    ptrPassword = fopen("filePassword", "wb");
                    if(ptrPassword)
                    {
                        fwrite(&newnewPassword, sizeof(int), 1, ptrPassword);
                    }
                    else
                    {
                        printf("Errore di file");
                    }
                }

e

C:
               printf("Inserire una password che contenga 4 numeri: ");
                scanf("%d", &valPassword1);
                printf("Inserire nuovamente la password: ");
                scanf("%d", &valPassword);
                if(valPassword==valPassword1)
                {
                    ptrPassword = fopen("filePassword", "wb");
                    if(ptrPassword)
                    {
                        fwrite(&valPassword, sizeof(int), 1, ptrPassword);
                        printf("\nPassword creata correttamente.\nRiavviare il programma per salvare le modifiche.\n\n");
                    }
                    else
                    {
                        printf("Errore di file");
                    }
                fclose(ptrPassword);
                }

secondo me riesci a riscriverlo una volta sola questo codice.
 

Vito-

Utente Attivo
184
14
Il riferimento al file che hai aperto.
Dovresti metterlo dopo la lettura che fai visto che poi non lo utilizzi più e lo vai a sovrascrivere con l'altra fopen per la scrittura.
Cosi?
C:
int main()
{
    int valPassword=0, valPassword1=0, Scelta=0, a=0;

    ptrPassword = fopen("filePassword", "rb");
    if(ptrPassword)
    {
        fread(&valPassword, sizeof(int), 1, ptrPassword);
        fclose(ptrPassword);
        menu(valPassword);
    }
    else
Si, può andar bene.
C:
else
    {
        do
        {
            printf("\t\t\t\t**Benvenuti nel vostro diario personale**\n\n"
                   "Per il primo avvio e' necessario creare una password di accesso\nVuoi creare una nuova password?\n1 Si\n2 No\n");
            scanf("%d", &Scelta);

            switch(Scelta)
            {
                case 1:
                    system("cls");
                    printf("Inserire una password che contenga 4 numeri: ");
                    scanf("%d", &valPassword1);
                    printf("Inserire nuovamente la password: ");
                    scanf("%d", &valPassword);
                    if(valPassword==valPassword1)
                    {
                        ptrPassword = fopen("filePassword", "wb");
                        if(ptrPassword)
                        {
                            fwrite(&valPassword, sizeof(int), 1, ptrPassword);
                            printf("\nPassword creata correttamente.\nRiavviare il programma per salvare le modifiche.\n\n");
                        }
                        else
                        {
                            printf("Errore di file");
                        }
                    fclose(ptrPassword);
                    }
                    else
                    {
                        printf("\nLe due password non coincidono");
                    }
                    break;
                case 2:
                    break;
                default:
                    printf("\nLa scelta effettuata non e' corretta");
            }
            printf("\n1 Riavvia la procedura per creare una password\n2 Esci\n");
            scanf("%d", &a);
            system("cls");
        }while(a==1);

    }

Per le parti uguali dovrei scrivere un altra funzione quindi...?
é sbagliato lasciarlo cosi?
 

Andretti60

Utente Èlite
6,440
5,091
Ma no, dai.
Devi sempre richiedere la password, la prima volta per salvarla, le altre volte per fare il confronto e uscire se la pwd è sbagliata.
Inoltre devi leggere la pagina del manuale della fopen() in particolare a cosa dice sul valore di ritorno, perché esistono molte condizioni per cui il file non può essere aperto (e quindi ritorna zero). La pagina del manuale ti dice anche cosa fare se ritorna zero (hint: errno)

Scusa se mi ripeto, ma chi studia all’uni deve imparare a leggere il manuale, perché una volta al lavoro è una cosa che farai sempre (impossibile sapere tutti i dettagli)
 

Vito-

Utente Attivo
184
14
Ma no, dai.
Devi sempre richiedere la password, la prima volta per salvarla, le altre volte per fare il confronto e uscire se la pwd è sbagliata.
Inoltre devi leggere la pagina del manuale della fopen() in particolare a cosa dice sul valore di ritorno, perché esistono molte condizioni per cui il file non può essere aperto (e quindi ritorna zero). La pagina del manuale ti dice anche cosa fare se ritorna zero (hint: errno)

Scusa se mi ripeto, ma chi studia all’uni deve imparare a leggere il manuale, perché una volta al lavoro è una cosa che farai sempre (impossibile sapere tutti i dettagli)
in che senso devi sempre richiedere la password
 
Stato
Discussione chiusa ad ulteriori risposte.

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili