salve gente, stavolta scrivo per cercare la soluzione ad un problema
temo sia banale e i farà fare la figura dell'inganniere, ma tentè, io di aiuto ho bisogno
premessa, vorrei, per puro diletto, gestire una lista di utenti, fisicamente allocata in un file scritto su una SD (sto giochicchiando con la SD montata sulla nodemcu del termoremoto, ma spero (SPERO) che non cambi nulla rispetto a uno shield sd su una UNO
EDIT del febbraio 2021
Scoperto adesso che CAMBIA
Leggete tutto
/EDIT
all'ora, premessa
ho pensato ad una lista di utenti, ognuno riconosciuto da un numero (unsigned long int, ma questo è un dettaglio)
lista mantenuta su una scheda SD nome file qualcosapuntoqualcosa (uso una macro #define FILEUTENTI "utenti.txt")
ok, mi dico, creati le "primitive": lista utente, cerca utente, aggiungi utente e togli utente
saranno delle belle funzioni del tipo bool foo(unsigned lon int utente){.....}
detto fatto:
lista gli utenti
void listautenti()
{
byte riga = 1;
if (!SD.exists(FILEUTENTI))
{
Serial.print(F("File inesistente: "));
Serial.println(FILEUTENTI);
return ;
}
else
{
File dataFile = SD.open(FILEUTENTI, FILE_READ);
Serial.print(riga);
Serial.print(' ');
while (dataFile.available())
{
//fino alla fine del file
char cx = dataFile.read();
if (cx == '\r')
{
continue;
// ignoro fine riga windows
}
if (cx == '\n')
{
// fine riga linux
Serial.println();
Serial.print(++riga);
Serial.print(' ');
continue;
}
Serial.print(cx);
}
dataFile.close();
}
}
dammi l'utente ad una certa riga
unsigned long int utente(byte target)
{
//legge da un file il numero di account di un utente indicato dalla riga
// al solito la riga cominicia da uno, allo scopo di non mandare in confusione un umano
// apro il file
if (!SD.exists(FILEUTENTI))
{
Serial.print(F("File inesistente: "));
Serial.println(FILEUTENTI);
return 0;
}
else
{
unsigned long int ritorno = 0;
byte riga = 1; // si parte dalla prima riga, sarebbe la 0, ma umanamente e' 1
File dataFile = SD.open(FILEUTENTI, FILE_READ);
while (dataFile.available())
{
char cx = dataFile.read();
if (cx == '\n')
{
riga++;
continue;
// riga contata, lavoro fatto, avanti un carattere
}
if (cx == '\r')
{
continue;
// terminatore di riga di windows, ignorato
}
if (riga == target)
{
if (cx >= '0' && cx <= '9')
{
// solo cifre
ritorno = ritorno * 10 + cx - '0';
continue;
}
}
if (riga > target)
{
// abbiamo passato
break;
// fuori dal ciclo
}
}
// finito file
dataFile.close();
return ritorno;
}
}
dimmi se un certo utente è autorizzato
byte autorizzato(unsigned long int utente)
{
byte ritorno = 0;
// restituisce il numero di riga dove si trova lo account dell'utente
// 0 se non lo trova
// serve per dare una autorizzazione agli utenti (col numero si gestisce anche il livello)
// apro il file
if (!SD.exists(FILEUTENTI))
{
Serial.print(F("File inesistente: "));
Serial.println(FILEUTENTI);
return 0;
}
else
{
File dataFile = SD.open(FILEUTENTI, FILE_READ);
byte riga = 1;
unsigned long int attuale = 0;
while (dataFile.available())
{
//fino alla fine del file
char cx = dataFile.read();
if (cx == '\r')
{
continue;
// ignoro fine riga windows
}
if (cx == '\n')
{
// fine riga linux
// faccio il test se corrisponde
if (attuale == utente)
{
// corrisponde, restituisco il numero di riga ed esco
ritorno = riga;
break;
}
// se sono arrivato qui non corrisponde, avanti una riga
riga++;
attuale = 0;
continue;
}
if (cx >= '0' && cx <= '9')
{
// una cifra
attuale = attuale * 10 + cx - '0';
}
}
dataFile.close();
return ritorno;
}
}
questa restituisce un byte, perchè userei anche il numero ordinale come embrione di livello di autorizzazione
aggiungi un utente alla lista degli autorizzati
bool autorizza(unsigned long int utente)
{
if (!autorizzato(utente)) // aggiunge al file utenti il numero dell'utente
{
// in realtà accoda
File dataFile = SD.open(FILEUTENTI, FILE_WRITE);
dataFile.println(utente);
dataFile.close();
return 1;
}
else
{
}
}
OK, fin qui tutto bene
adesso pero' non so come togliere l'autorizzazione ad un utente
come faccio a rimuoverlo dalla lista, senza copiare il file saltando la riga, intendo
avevo pensato di sovrascrivere il numero con dei trattini, ma non va
bool rimuovi(unsigned long int utente)
{
// toglie dal file degli utenti la riga relativa ad un utente cancellato
// in realtà ne cancella il numero
// restituisce 0 se utente non autorizzato, non serve rimuoverlo
// 1 se utente autorizzato e rimosso
// prima cosa, sapere il numero della riga
byte target = autorizzato(utente);
if (!target)
{
Serial.print("utente ");
Serial.print(target);
Serial.println(" non autorizzato, non serve rimuoverlo ");
// utente non autorizzato, non serve rimuoverlo
return 0;
}
else
{
if (!SD.exists(FILEUTENTI))
{
Serial.print(F("File inesistente: "));
Serial.println(FILEUTENTI);
return 0;
}
else
{
Serial.print("rimuovo riga");
Serial.print(target);
Serial.print(" utente: ");
Serial.println(utente);
File dataFile = SD.open(FILEUTENTI, FILE_READ);
Serial.println("file aperto");
byte riga = 1;
dataFile.seek(0); // torniamo all'inizio
Serial.println("tornati indietro");
while (dataFile.available())
{
//fino alla fine del file
char cx = dataFile.read();
if (cx == '\r')
{
continue;
// ignoro fine riga windows
}
if (cx == '\n')
{
// fine riga linux
riga++;
Serial.println("trovatariga");
continue;
}
if (riga == target)
{
// siamo nella riga giusta
if (cx >= '0' && cx <= '9')
{
//siamo nel carattere giusto
// devo tornare indietro di un passo
Serial.println(dataFile.position());
dataFile.seek(dataFile.position() - 1);
//sovrascrivo
Serial.print("in posizione ");
dataFile.write('-');
dataFile.flush();
Serial.print("fatto ");
dataFile.seek(dataFile.position() + 1);
Serial.println(dataFile.position());
}
}
}
dataFile.close();
}
}
}