Devo fare il jolly dei file...

che è una "brillante" traduzione di google di una delle mie ricerce sul problema di oggi:
Uso delle wildcard sui nomifile in una SD
Sì, insomma, vorrei listare su seriale (e/o Softserial, o radio o quant'altro) i nomi dei file di una SD che corrispondono a certi wildcard (per esempio ".txt")
ora, listarli tutti non è problema, fa parte degli esempi
è listare solo quelli il cui nome soddifa una certa wildcard che fa problema
ora, una roadmap io la ho
la funzione file.name() restituisce una stringa stampabile, spero quindi che sia un char

e posso fare una cosa del tipo

char wildcard[]="*.txt"
bool soddisfa(file.name, wildcard)

è scrivere la soddisfa che mi mette patema
qualcuno di voi ha consigli?

dipende se vuoi usare solo, l’asterisco per trovare tutti i file che hanno una determinata estensione allora ricerchi nel nomeFile il punto (lo trovi con stringaInOggetto.indexOf(".") che ti da il valore della posizione del testo cercato) e poi confronti l’estensione con quella da te cercata, al contrario se vuoi ricercare anche parti di nome del file (tipo *ino.txt) o utilizzare anche “?” allora è leggermente più complesso

modifica

non so se funziona con string o solamente con String

Un modo è quello di convertire il pattern in una RegExp e quindi usare una libreria per verificare se i nomi dei file matchano la RegExp. Così su due piedi direi che è una cosa folle da fare su un microcontrollore, ma visto che esiste una libreria per le RegExp su Arduino, potrebbe anche funzionare. Sono curioso di sapere se questa libreria funziona su una Uno senza esaurire le risorse.

Se "parli" Python, puoi prendere ispirazione da questa funzione per fare la conversione da pattern a RegExp.

per ora grazie a tutti, stanotte ci ponzo un po'

Ma qualsiasi ricerca ? AB*.* AB*.TXT *.TXT etc. ??
strstr() se nell'esempio ammazzi asterisco e tieni solo ".TXT" dovrebbe funzionare.
C'e' anche il problema delle maiuscole/minuscole però

Ci ho pensato, stanotte...
all'ora, le varie cose che si basano sulle regular expression sono belle complicate, anche troppo per cercare un nome file in una SD
anche la scelta anti-intuitiva di restituire falso se SODDISFA la condizione..........
insomma, ho tirato fuori questo
per le 4 prove che ho fatto sembra andare, qualche anima pia mi da uno sguardo?

bool wildcardname(char pattern[], char nome[])
{
    /*
        restituisce true se il nome soddisfa il pattern
        cose semplici, come

        '*' qualsiasi stringa (anche nulla, ma non un nome completamente nullo)
        '?' un carattere qualsiasi
        '?*' qualsiasi stringa, non nulla
        '*.*' tutti i file (con punto di estensione)
        e via così come col buon vecchio DOS
    */
    bool ritorno = 1;
    byte p = 0; // indice nel pattern
    byte n = 0; // indice nel nome

    while (1)
    {
        // se siamo arrivati alla fine di pattern E nome
        if (pattern[p] == 0 && nome[n] == 0)
        {
            ritorno = 1;
            break;
            // esco dal ciclo e restituisco true
        }

        // se siamo arrivati alla fine del pattern O del nome
        if (pattern[p] == 0 || nome[n] == 0)
        {
            ritorno = 0;
            break;
            // esco dal ciclo e restituisco false
        }

        // carattere speciale ?
        if (pattern[p] == '?')
        {
            // se ?
            // avanti un passo
            p++;
            n++;
            continue;
        }

        //carattere speciale *
        // due casi: ultimo carattere, che a quel punto va bene tutto quello che c'è
        //oppure seguito da qualcosa, che vuol dire che deve trovare quel qualcosa

        if (pattern[p] == '*')
        {
            if (!pattern[p + 1])
            {
                // pattern finito con un *, non serve andare avanti, qualunque cosa ci sia scritta va bene
                // il caso che la stringa sia appena finita dovrebbe essere stato escluso dai test precedenti
                //non serve che vado avanti
                ritorno = 1;
                break;
            }
            else
            {
                // cerco nel nome il carattere successivo all'asterisco
                char c = 0;

                while (c = nome[n++])
                {
                    if (c == pattern[p + 1])
                    {
                        // trovato, esco dal while
                        p++; // avanti un carattere nel pattern
                        n--; // ritorno indietro di uno nel nome
                        break;
                    }
                }

                // se sono qui sono uscito dal while,
                // se nome[n] ==0 è perchè è finito il nome senza trovare il carattere
                if (!nome[n])
                {
                    return 0;
                    break;
                }
                else
                {
                    // ok, trovato il carattere successivo al *
                    // posso continuare
                    continue;
                }
            }
        }

        // per ogni carattere del pattern
        if (pattern[p] == nome[n])
        {
            // trovata coincidenza
            p++;
            n++;
            // avanti un passo
            continue;
        }
        else
        {
            //  non coincide, esco con un false
            ritorno = 0;
            break;
        }
    }

    //non  dovremmo, ma se siamo arrivati fin qui tutto ha corrisposto
    //restituisco OK (il valore impostato all'inizio)
    return ritorno;
}

fondamentalmente semplice, con casi che si auto-escludono
Se le stringhe sono finite OK
se una è finita ma l'altra no NO OK
se un carattere non corrisponde al suo "corrispondente" NO ok
se un punto di domanda, e c'è un qualsiasi carattere : avanti un passo
se un asterisco non seguito da nulla: OK
se un asterisco seguito da un carattere, cerco il carattere, se lo trovo avanti un passo, se no NO OK
se un carattere corrisponde al suo "gemello" dell'altra stringa, avanti un passo
NON sono le espressioni regolari complete, ma per quanto riguarda i file-name in un file system FAT dentro una SD in Arduino, direi che basta
naturalmente la ho provata con una funzione apposita

void prova(char pattern[], char nome[])
{
    Serial.print(nome);
    Serial.print(" ");
    Serial.print(pattern);

    if (wildcardname(pattern, nome))
    {
        Serial.println(" SI");
    }
    else
    {
        Serial.println(" NO");
    }
}

che uso nella setup (non mi serve la loop, basta provare una volta)

// di Nelson "StandardOil"
// Idea da sviluppare: wildcard nei filename


void setup(void)
{
    Serial.begin(9600);
    Serial.println("Prova wildcard");
    prova("noi.tre", "noi.tre");
    prova("noi.tr", "noi.tre");
    prova("?oi.tre", "noi.tre");
    prova("?oi.tre", "Voi.tre");
    prova("?oi.tre", "Coi.tre");
    prova("?oi.due", "noi.tre");
    prova("*", "noi.tre");
    prova("*.tre", "noi.tre");
    prova("*.*", "noi.tre");
    prova("*.lst", "aqeua.lst");
    prova("*.lst", "uno.lst");
    prova("*.lst", "alcuni.lst");
    prova("*.lst", "tre prove.lst");
    prova("*", "");
}

void loop(void)
{
}

per le poche prove che ho fatto sembra andare, voi che ne dite?

Direi che va bene.

Se vuoi una funzione più completa (ma non mi pare il caso) potresti cercare il sorgente di fnmatch, funzione POSIX di ricerca wildcard: Wildcard Matching (The GNU C Library)
Qui un sorgente c: fnmatch.c Source File

Grazie per l'interessamento
a proposito, uso abitalmente Linux, non ci penso nemmeno più che "LA Maiuscola" possa essere uguale a "la mINUSCOLA", grazie comunque per avermelo ricordato

Standardoil:
Ci ho pensato, stanotte...

Io pure, e anche la notte dopo, e quella dopo ancora... a quasi 33 gradi in casa. Questo il risultato. Si lo so, sono pazzo.

Claudio_FF:
Io pure, e anche la notte dopo, e quella dopo ancora... a quasi 33 gradi in casa. Questo il risultato. Si lo so, sono pazzo.

confermo :smiley:

sito aggiunto ai segnalibri! :wink:

No, non sei pazzo, soffri solo un po il caldo
Bel lavoro.