Stringa molto, molto lunga

Ho cercato a lungo senza trovare le risposte che cercavo, conto quindi nella benevolenza di chi legge per darmi una mano.
Da neofita di C, mi trovo in serie difficolta' a gestire una stringa molto lunga, anche un migliaio di caratteri.
Senza scendere in inutili dettagli del progetto, ho bisogno di scorrere questa stringa carattere per carattere, uno alla volta applicando varie funzioni della classe String() come charAt() o toLowerCase() .
Il massimo che sono riuscito a fare e' stato creare un vettore di char con 5 o 6 elementi che poi trasformo in stringhe con la funzione String() con un numero limitato di caratteri, per un totale di circa un centinaio.
Grazie a chiunque sappia darmi un aiuto
Max

Per me non è molto chiaro.
Al massimo hai trasformato un vettore di 5/6 caratteri in una stringa di 100? In che senso?
dichiari char vet[1000]; e hai un vettore di 1000 elementi.

Inutile l'oggetto String, esistono funzioni molto più leggere per lavorare con i vettori di caratteri.

  • strlen(v) ti dice quanti caratteri ci sono nel vettore (cerca il fine stringa, '\0')
  • sizeof(v) ti dice il numero di celle (ricorda vet[10] le celle vanno da 0-9 e se contiene una frase/stringa ultimo char='\0' )
  • memset(v,quanti,valore) per azzerare tutte le celle es. memset(v,sizeof(v),'\0');
  • strncpy() per copiare n caratteri da vettore a vettore es. strncpy(dest,sorg,10); 10 char da sorg a dest
  • strcmp() per confronto fra 2 vettori di caratteri (strncmp() per limitare il numero di caratteri)
  • isdigit() per sapere se una cella è una cifra, isalpha() se è una lettera
  • passi in rassegna ogni cella con un semplice ciclo for e le parentisi quadre:
for(int i=0;i<1000;i++)
{ if(v[i]=='X')
  { // trovato X nel vettore v in cella numero i
  }
}
  • conversione lower/upper case cella per cella con isupper()/islower() ti dicono se è già in ucase o lcase, poi basta aggiungere o togliere 32
    ('A' ovvero 65+32= 97 ovvero 'a') oppure usi toupper()/tolower() ma solo 1 cella alla volta.

Che Arduino devi usare? Sai che la Uno ha solo 2K di memoria per i dati (2048 byte)? La mega ha 8K.

const char *stringaLunga = "asklkdoedl,mc dèlòd";

while (*stringaLunga != '\0') {
      if (char oneChar == 'p')
         serial.print("trovata la p che cercavi)
      ++stringaLunga;
}

Mi spiego meglio.
Inizialmente avevo impostato una stringa in questo modo
String Testo="12345...[altri 1000 caratteri]...xxx"
Mi accorsi che il programma non riusciva a leggere nessun carattere mentre riducendo la stringa a
String Testo="1234567890" (per dire una stringa molto piu' corta)
funzionava.
Ho capito che dipendeva dalla lunghezza (non sono stato a contare dopo quanto caratteri andasse in crisi)
Ho pensato di spezzare la stringa in un vettore tipo
String Testo={"1234567890", "xxxxxxxxxx", ... , "xxxxxxxx"}
aggiungendo un ciclo che di volta in volta non leggesse l'intera stringa ma solo un pezzo per cosi' dire ma anche questo superato lo stesso numero di caratteri non funzionava.
Con char* Testo={"1234567890", "xxxxxxxxxx", ... , "xxxxxxxx"} sono riuscito ad aggiungere dei caratteri ma non riesco ad arrivare alla lunghezza che vorrei
Spero di aver chiarito meglio

Come mai devi scrivere una frase così lunga?
E' una costante? Non può essere spezzata?

Non sapevo ci fosse un limite per fare
char v[]="ttttttanti caratteriiii....... ... ";

Potresti provare cosi, ma con un vettore:

char vet[1000];

void setup()
{ strncpy(vet+0,"primi cento......",100);
  strncpy(vet+100,"secondi cento......",100);
  ...
}

Provero' quanto mi suggerisci.
Mi serve una stringa lunga perche' ho bisogno dato un testo anche lungo, di tradurlo in Morse, da qui lo scorrere carattere per carattere.
Ho trovato tanto esempi ma lavorano tutti quanto con stringhe molto corte di prova.
Stasera provo, ti sapro' dire intanto grazie

ripeto quello detto da nid69ita

Che Arduino devi usare? Sai che la Uno ha solo 2K di memoria per i dati (2048 byte)? La mega ha 8K.

Arduino non ha abbastanza RAm da memorizzare cosí tanti dati. Inoltre la gestione delle stringe non funziona bene e percui sono da evitare l'uso. Usa dei array.
Non so quanto grande puó essere l'indice dei array.

Ciao Uwe

Come ti ha detto già l'ottimo UWE, la RAM è una forte limitazione per il tuo progetto.

Sei sicuro di non poter trattare vettori più piccoli?

Ad esempio potresti memorizzare la stringa nella Flash o nella EEPROM e poi recuperarla a "pezzi" più piccoli.

In effetti e' cio' che ho fatto, ovvero ho spezzato il testo in stringhe piu' corte raccolte in un vettore.
Ho contato e a grandi linee e' attorno ai 330 caratteri complessivi che il compilatore va in crisi.
A questo punto, al di la' delle possibili limitazioni di memoria, volevo capire il modo per maneggiare stringhe molto lunghe perche' ripeto, approccio il C per la prima volta in questi giorni e non trovo nel web delucidazioni in merito.

Difficilmente si scrivono a mano stringhe costanti cosi lunghe.
Di solito si carica un testo molto lungo in vettore ma da file. Di quello di esempi ne troverai molti.

Come ti ha detto Uwe, l'oggetto String consuma molta memoria e non è efficiente. Devi usare gli array di caratteri.
http://arduino.cc/en/Reference/String

Allora, se usi la classe String ti occupa un sacco di RAM, se invece usi array di char (le stringhe altro non sono che array di char il cui ultimo carattere, della stringa, non dell'array, è il /0) hai qualche speranza. Comunque un array di 100 char occupa la stessa ram di due array da 50 char, i quali occupano la stessa memoria di 100 char separati, quindi se non ci stà non ci sta, è inutile tentare di spezzare la stringa...

Ottimo esempio dal quale avevo preso spunto e da cui partire. Anche io ho qualcosa come
char* myStrings[]={"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5","This is string 6"};

Ebbene se come da esempio la scorro (ho bisogno di farlo carattere per carattere ma il discorso non cambia)
for (int i = 0; i < 6; i++){
Serial.println(myStrings*);*

  • delay(500);*
  • }*
    funziona fintanto che oltre un certo numero di caratteri (attorno ai 330 circa) non restituisce piu' nulla e non capisco perche' se non come dite, non c'e' abbastanza memoria per contenerla...

Se non metti il codice dentro i tag appositi, le quadre vengono tagliate. Usa il pulsante # quando scrivi e il forum ti mette i due tag dentro i quali racchiudere il codice.

Comunque quello che scrivi è un vettore di stringhe, non uno stringone lungo. C'e' una discreta differenza.
Ogni elemento di myString punta a una stringa terminata da fine stringa '\0'
In memoria non è detto che i caratteri delle varie stringhe siano memorizzati una dopo l'altra.

Grazie per i tag del codice, non lo sapevo.
Scomporre il testo nel vettore e' stato un ripiegare per avere piu' caratteri possibili, il mio obiettivo sarebbe avere una sola lunga stringa.
Mi pare di capire che non cambierebbe nulla se usassi

char* myStrings[]={"<stringa molto lunga>"}

provero' appena riesco ma immagino che il problema rimanga

Scusa maxscorda, ma quella stringa è per forza una "costante" o è una cosa che varia e che Arduino può ricevere dall'esterno (es. tramite la seriale) e poi convertire in morse ???

Guglielmo

E' una costante

Esattamente, di quanti caratteri DEVE per forza essere ???

Guglielmo

puoi sempre mettere il testo in un file txt in una SD, la funzione file.read restituisce già in lettura i singoli char.
provvisoriamente te la puoi costruire anche a casa http://forum.arduino.cc/index.php/topic,8314.0.html

maxscorda:
Ottimo esempio dal quale avevo preso spunto e da cui partire. Anche io ho qualcosa come
char* myStrings[]={"This is string 1", "This is string 2", "This is string 3",
"This is string 4", "This is string 5","This is string 6"};

Ebbene se come da esempio la scorro (ho bisogno di farlo carattere per carattere ma il discorso non cambia)
for (int i = 0; i < 6; i++){
Serial.println(myStrings*);*

  • delay(500);*
  • }*
    funziona fintanto che oltre un certo numero di caratteri (attorno ai 330 circa) non restituisce piu' nulla e non capisco perche' se non come dite, non c'e' abbastanza memoria per contenerla...
    [/quote]
    Posta il codice che hai fatto in questo caso. Secondo me dovrebbe funzionare, il limite dei 330 non ha senso.
    Una unica stringa okay, ci posso essere limiti, ma vettore di stringhe, non mi risulta.