ti metto, ti cerco, ti trovo, ma non riesco a toglierti......... mannaggia

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();
        }
    }
}

e se scrivi 0 (zero) come numero (autorizzazione) dell'utente?

posso provare male non fa, grazie

Risolto grazie
ero proprio inganniere, scusatemi
aprivo il file in lettura, aperto in scrittura, tutto OK
scusatemi, grazie

aggiunta del 10/02/2021

ecco la versione rimaneggiata sulla base delle esigenza di un utente qui del forum

void listautenti()
{
   int 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(F("Listo gli utenti contenuti in: "));
      Serial.println(FILEUTENTI);
      int l = 10;

      for (int i = 1; i < 5; i++)
      {
         if (riga < l)
         {
            Serial.print('0');
         }

         l = l * 10;
      }

      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
            riga++;
            l = 10;
            Serial.println();

            for (int i = 0; i < 4; i++)
            {
               if (riga < l)
               {
                  Serial.print('0');
               }

               l = l * 10;
            }

            Serial.print(riga);
            Serial.print(": ");
            continue;
         }

         Serial.print(cx);
      }

      dataFile.close();
   }
}


unsigned long int utente(int 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;
      int 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;
   }
}

int autorizzato(unsigned long int utente)
{
   int 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);
      int 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;
   }
}


bool autorizza(unsigned long int utente)
{
   if (!autorizzato(utente))   // aggiunge al file utenti il numero dell'utente
   {
      if (!SD.exists(FILEUTENTI))
      {
         Serial.print(F("File inesistente: "));
         Serial.println(FILEUTENTI);
         return 0;
      }
      else
      {
         File dataFile = SD.open(FILEUTENTI, FILE_WRITE);
         dataFile.println(utente);
         dataFile.close();
         return 1;
      }
   }
   else
   {
      return 1;
   }
}

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
   int target = autorizzato(utente);

   if (!target)
   {
      // utente non autorizzato, non serve rimuoverlo
      return 0;
   }
   else
   {
      if (!SD.exists(FILEUTENTI))
      {
         Serial.print(F("File inesistente: "));
         Serial.println(FILEUTENTI);
         return 0;
      }
      else
      {
         File dataFile = SD.open(FILEUTENTI, O_RDWR);
         // read write, non serve su nodemcu
         int riga = 1;
         dataFile.seek(0); // torniamo all'inizio

         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++;
               continue;
            }

            if (riga == target)
            {
               // siamo nella riga giusta
               if (cx >= '0' && cx <= '9')
               {
                  //siamo nel carattere giusto
                  // devo tornare indietro di un passo
                  dataFile.seek(dataFile.position() - 1);
                  //sovrascrivo
                  dataFile.write('-');
                  dataFile.flush();
                  dataFile.seek(dataFile.position() + 1);
                  // cancella un carattere si e uno no
                  // per poter comunque capire cosa c'era scritto
               }
            }
         }

         dataFile.close();
      }
   }
}

così ho superato il limite di 255 utenti, ora usa un int e non credo che nessuno seriamente vorrà superare queste dimensioni con un Arduino

e ho messo a posto un po’ l’estetica di stampa

piuttosto, chi volesse usarla per fare autenticazione magari per un telegrambot

OPS, mi sono lasciato scappare che la avevo sviluppata per il mio maggiordomo su telegram…)

peccato, rovinata la sorpresa

comunque, ecco perché ero e sono sicuro che funziona(va)
perché il mio maggiordomo su telegram, funziona(va), e quindi se qualcosa non va il problema non è in queste funzioni

dicevo, se voleste usarlo per autenticazione dei messaggi ricevuti da un bot, sappiate che unsigned long int non è sufficiente

per telegram serve unsigned long long int

non per niente se cercate trovate anche un mio post dove mostro come stampare un unsigned long long…

Cioè un uint64?

Per la gestione utenti e la cancellazione si poteva usare forse una lista concatenata.

Si, uint64
Forse basta signed long long
Ma tantovale…

Lista concatenata…

Non male, ma dovendo comunque passare da una SD…

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.