Salve a tutti! Devo svolgere un progetto in C e devo utilizzare i file csv. Sono riuscita a fare tutte le funzioni principali di aggiunta, modifica e cancellazione. In questo progetto devo simulare una piattaforma in cui gli utenti possano iscriversi, modificare i loro dati e cancellarsi. Ho notato però che se effettuo il login oppure inserisco un nuovo utente facendolo registrare, le funzioni di modifica e cancellazione non funzionano più e mi viene stampato come errore sullo schermo "File non eliminato: permission denied" e sinceramente non capisco per quale motivo. Credevo fosse un problema di quelle due funzioni, eppure ho notato che se modifico o cancello un utente senza fare login o iscrizione, entrambe fungono, quindi denoto che il problema si presenti sia nel login che nell'iscrizione, ma non riesco proprio a capire che cosa ci sia di errato nelle funzioni. Potreste darmi una mano a capirlo? Mi sto scervellando da tanto e ancora non sono riuscita a scoprire il motivo per cui non funzionino
Questa è la funzione di login
void login()
{
FILE* fu;
int found = 0;
fu = fopen("utenti.csv", "r+");
char buff[BUFFER_SIZE];
if ((fu = (fopen("utenti.csv", "r+"))) == NULL)
{
printf("Errore nell'apertura del file.\n");
return;
}
space = getchar(); //elimina il '\n' per svuotare lo stream di input
printf("Inserisci il tuo username:\n");
fgets(user, sizeof(user), stdin);
elimina_invio(user); //elimina il '\n' per permettere un confronto e scrivere i valori sul file tutti su una riga
while(fgets(buff, sizeof(buff), fu) != 0)
{
separa_utente(buff, &us); //funzione che prende in input la riga letta da file e immette tutti i valori nella struct utenti
if(strcasecmp(user, us.username) == 0)
{
found = 1;
printf("Inserisci la password:\n");
fgets(password, sizeof(password), stdin);
elimina_invio(password);
if(strcasecmp(password, us.password) != 0)
{
printf("Password errata.\n");
return;
}
else{
system("cls");
fclose(fu);
menu_utente(); //menu principale per gli utenti collegati
}
}
}
if(!found)
{
printf("Nessun utente con questo username.\n");
}
fclose(fu);
return;
}
La struct utenti è formata in questo modo:
typedef struct
{
int giorno;
int mese;
int anno;
} data;
typedef struct
{
char username[30];
char password [30];
char nome[30];
char cognome[30];
data nascita;
data iscrizione;
} utente;
Invece la funzione
separa_utente
ha il seguente codice
void separa_utente(char* str, utente* u)
{
char* token;
token = strtok(str, ",");
strcpy(u->username, token);
token = strtok(NULL, ",");
strcpy(u->password, token);
token = strtok(NULL, ",");
strcpy(u->nome, token);
token = strtok(NULL, ",");
strcpy(u->cognome, token);
token = strtok(NULL, ",");
u->nascita.giorno = atoi(token);
token = strtok(NULL, ",");
u->nascita.mese = atoi(token);
token = strtok(NULL, ",");
u->nascita.anno = atoi(token);
token = strtok(NULL, ",");
u->iscrizione.giorno = atoi(token);
token = strtok(NULL, ",");
u->iscrizione.mese = atoi(token);
token = strtok(NULL, ",");
u->iscrizione.anno = atoi(token);
return;
}
La funzione di modifica è strutturata invece in questo modo:
void modifica_utente (char* user)
{
int scelta;
utente u;
FILE* temp;
FILE* fu;
temp = fopen("temp.csv", "w+"); ///< file temporaneo in cui salvare i dati precedenti e la struct modificata
fu = fopen("utenti.csv", "r+");
if(!temp)
{
printf("Errore nell'apertura del file\n");
return;
}
if(!fu)
{
printf("Errore nell'apertura del file\n");
return;
}
int found = 0; ///<variabile booleana che determina se l'utente e' stato trovato
/**
* Sono presenti due stringhe dato che una viene utilizzata per ricavare i dati e l'altra per
* riportare la stringa letta da file nel file temporaneo nel caso in cui lo username da modificare
* non corrisponda con la stringa immessa in input
*/
char buff[BUFFER_SIZE];
char string[BUFFER_SIZE];
while(fgets(buff, sizeof(buff), fu))
{
strcpy(string, buff);
separa_utente(buff, &u);
if(strcasecmp(user, u.username) == 0)
{
printf("Che cosa vuoi modificare?\n");
printf("1. Password\n");
printf("2. Nome\n");
printf("3. Cognome\n");
printf("4. Data di nascita\n");
scanf("%d", &scelta);
space = getchar();
switch(scelta)
{
case 1:
printf("Inserisci la nuova password:\n");
fgets(u.password, sizeof(u.password), stdin);
elimina_invio(u.password);
salva_utente(&u, temp);
attendi();
break;
case 2:
printf("Inserisci il nuovo nome:\n");
fgets(u.nome, sizeof(u.nome), stdin);
elimina_invio(u.nome);
salva_utente(&u, temp);
attendi();
break;
case 3:
printf("Inserisci il nuovo cognome:\n");
fgets(u.cognome, sizeof(u.cognome), stdin);
elimina_invio(u.cognome);
salva_utente(&u, temp);
attendi();
break;
case 4:
printf("Inserisci la nuova data di nascita (formato gg-mm-aaaa):\n");
scanf("%d-%d-%d", &u.nascita.giorno, &u.nascita.mese, &u.nascita.anno);
space = getchar();
salva_utente(&u, temp);
attendi();
break;
default:
printf("Numero errato.\nInserire valore corretto:\n");
scanf("%d", &scelta);
attendi();
break;
}
found = 1;
}
else
{
fputs(string, temp);
}
}
if(!found)
{
printf("Nessuna corrispondenza\n");
}
fclose(fu);
fclose(temp);
int tried = remove("utenti.csv");
if(tried != 0)
{
perror("File non eliminato\n"); ///< Verifica se il file e' stato rimosso correttamente
}
rename("temp.csv", "utenti.csv");
return;
}
Per ora vi posto solo queste funzioni perché vorrei evitare di rendere il post troppo lungo e pesante da leggere, ma se ce ne fosse bisogno potrei postare anche il codice di iscrizione e di cancellazione dell'utente. Credevo che il problema derivasse dal fatto che non sempre chiudessi i file perché comunque ho creato molte funzioni, ma non mi sembra di aver tralasciato nulla.