Go Down

Topic: [Risolto] Stranissimaorruzione dell'array di caratteri usando una "è" o una "é"! (Read 484 times) previous topic - next topic

Federico66

Come accennato prima, mi sono reso conto di un problema dell'uso del file header: se faccio una nuova versione del programma, anche senza toccare l'header, quando vado a salvare la nuova versione, che ha un nome diverso (cioè deve riscrivere il file header ...
Evidentemente l'IDE salva il file anche se non modificato! Peccato, era una soluzione semplice.


A questo punto, ripropongo la mia idea (#6) di utilizzare i segnaposto senza pensarci oltre (60post!), visto che le stringhe non sono soggette a modifica frequente.

Ti ho già fatto lo schemino (promemoria) aggiungendo anche le altre, scegli tu i segnaposto se questi pensi di usarli.
Code: [Select]

//##################################################
//#### RICORDATI I SEGNAPOSTO PER LE ACCENTATE #####
//##################################################
//  à  (224)  =>  #  (35)
//  è  (232)  =>  %  (37)
//  é  (233)  =>  $  (36)
//  ì  (236)  =>  &  (38)
//  ò  (242)  =>  ^  (94)
//  ù  (249)  =>  ~  (126)
//##################################################

  unsigned char testo[4][100] = // nMsg va da 1 a N; gli indici dei testi vanno da 0 a N-1.
  {
    "Trovate $ nostri video su www.youtube.com/mariachescioglieinodi",
    "Questo $ il testo 2",
    "Questo qui $ il testo 3",
    "#$%&^~"
  };


Dopo puoi decidere se sostituire i caratteri nel setup:
Code: [Select]

  //Sostituzione segnaposto accentate
  for (byte i = 0; i < 4; i++) {
    for (byte j = 0; j < 100; j++) {
      if (testo[i][j] == 0) {
        break;
      } else if (testo[i][j] == '#') {
        testo[i][j] = 224; //à
      } else if (testo[i][j] == '$') {
        testo[i][j] = 232; //è
      } else if (testo[i][j] == '%') {
        testo[i][j] = 233; //é
      } else if (testo[i][j] == '&') {
        testo[i][j] = 236; //ì
      } else if (testo[i][j] == '^') {
        testo[i][j] = 242; //ò
      } else if (testo[i][j] == '~') {
        testo[i][j] = 249; //ù
      }
    }
  }


o modificare la tua procedura ri-mappando le accentate con i corrispondenti segnaposto:
Code: [Select]

void printCharWithShift(unsigned char c, int shift_speed) {
  if(c<32) return;
  if(c<126) c-=32;
  if(c==232) c=95;
  if(c==233) c=96;
  //...
}



Federico
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

Federico66

Oppure l'altra soluzione, ossia cercare i byte a zero (che precedono sempre i caratteri speciali in UTF8) e "spostare" indietro i caratteri successivi per togliere lo zero.
Scusa, ma io continuo a non capire. Perchè dici che c'è sempre un byte a zero?

Ieri ho fatto questa semplice prova:
Code: [Select]

  unsigned char t[4] = "Aè";
  for (byte i=0;i<3;i++) {
    Serial.print(t[i], DEC);
    Serial.print("=>");
    Serial.println(t[i], HEX);
  }


ottenendo:
Code: [Select]

65=>41 //questa è la A, in UTF8 hex 41

195=>C3 //questi due byte sono la "è" in formato UTF8 hex C3A8, che in UTF16 diventa 00E8
168=>A8


che conferma quello che dice il reference:

Quote
The Arduino editor and the compiler (avr-gcc) use UTF-8 for special characters. When UTF-8 is used in the program code itself, the characters can occupy one up to four bytes
Grazie
Federico

"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

docdoc

Concordo con Federico66, anche se a mio avviso forse basterebbe e resterebbe più semplice l'altra soluzione ossia impostare il file in sola lettura per impedire all'IDE di riscriverlo.

Qualora all'IDE dovesse dar fastidio un file read-only, allora per me una procedurina di pulizia delle accentate di questo tipo dovrebbe funzionare, e sarebbe molto più generica senza richiedere di ricordare una tabellina di caratteri:

Code: [Select]
void filtraUnicode(char str[], int len) {
  for (int i=0; i<len; ++i) {
    byte c = str[i];
    Serial.print(c, HEX);
    Serial.print(" ");
    if ( c == 0xC3 ) {
      memcpy(str+i, str+i+1, len-i);
      c = str[i];
      if ( c >= 0xA0 ) str[i] = c + 0x40;
    }
  }
}

PS: le accentate in Unicode mi risultano in realtà composte da due byte, il primo è 0xC3 seguito dal codice del carattere accentato, ma dato che il codice ASCII esteso corrispondente è uguale al secondo byte più 0x40 si mappano TUTTE le accentate con una istruzione "str[ i ] = c + 0x40".. ;)

Scusa, ma io continuo a non capire. Perchè dici che c'è sempre un byte a zero?
EDIT: Si hai ragione, avevo interpretato male, ed ho detto una cazzata.
Infatti mi sono corretto, vedi il PS di sopra.. ;)
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

Federico66

.. una procedurina di pulizia delle accentate di questo tipo dovrebbe funzionare, e sarebbe molto più generica senza richiedere di ricordare una tabellina di caratteri:
Questa mi piace, la metto in scarsella, può tornare utile :)
Grazie


Federico
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

C1P8

magari una cosa così:


Code: [Select]


typdef struct
{
char escape[3]; // la escape sequence
byte value;// il codice
} escapeseq;


escapeseq sostituzioni[]={{"e+",130},{"e-",138},{"u-", 158}}; //non ricordo il codice della u accentata
byte lettere=sizeof sostituzioni / sizeof sostituzioni[0];

#define Messagenumber 3
volatile char ** messaggi;
char messaggi[0][]="e grave e+ e acuta e-";
char messaggi[1][]="e acuta e- e grave e+";
// to be continued

for byte i=0;i<Messagenumber;i++){
   byte j=0;
   while(messaggi[i][j]){
      for (byte k=0; k<lettere;k++){
          if (messaggi[i][j]==sostituzioni[k].escape[0] && messaggi[i][j+1]==sostituzioni[k].escape[1]){
             messaggi[i][j]=(char)sostituzioni[k].value;
             j++;
             while(messaggi[i][j]){
             messaggi[i][j]=messaggi[i][j++];
            }
          }
       j++; 
      }   
   }
}




dove si cerca su un array di puntatori a carattere

dichiarati volatile (ne abbiamo discusso pochi giorni fa il perchè

si cicla per cercare la coppia di escape sequence
coppia che a sua volta viene da un array di sostituzioni che viene ciclato

una soluzione rapida, indolore ed universale

naturalmente esendo le escape sequence più lunghe del singolo carattere serve "tirare indietro" il resto della stringa




„Quando il sole della cultura è basso, i nani hanno l'aspetto di giganti"
Quando si tacita chi dice la verità con l'autorità invece che con l'autorevolezza il sole della cultura è gia tramontato

Datman

Grazie a tutti, ma sono andato avanti.

Il problema principale dell'header è, come ho detto, che quando salvo il programma con una nuova versione, ad esempio da 1.1_p16 a 1.1_p17, dove p sta per prova o provvisorio, tutti i file vengono riscritti nella nuova cartella! Anche l'header viene scritto, come l'IDE ritiene opportuno! >:(

Comunque, come detto, sto andando avanti e non mi faccio il problema della vocali accentate. Tanto questi sono messaggi di prova. I messaggi veri verranno messi alla fine, quando non dovrò più modificare il programma o lo farò raramente.

Grazie!
Gianluca
Hi,I'm Gianluca from Roma.I play&work with electronics since I was16(1984).
After 25yrs of maintenance on cameras&video mixers,since 2013myJob is HDTVstudios design.
Since Jan2015 IPlayWith Arduino:bit.ly/2F3LPWP
Thanks 4 a Karma if U like my answer

Go Up