Curiosita' Char

Per controllare la fine di una stringa normalmente si va a verificare quando si arriva al terminatore, che contiene zero.
Ma ho visto che a volte il controllo si fa sia su 0 che su 128 (usando Byte, non Char)

Mi chiedevo, capisco in questo caso l'uso del Byte serve perche' Char non puo' contenere piu' di 127, ma comunque visto che parliamo di una stringa sempre lo zero mi deve arrivare, quindi normalmente io uso Char e controllo l'arrivo dello 0

Esistono casi in cui il terminatore invece di 0 e' 128 ?

Tutti a nanna
buonanotte :slight_smile:

Un Char é a 8 bit senza segno percui puó contenere valori tra 0 e 255.
Per l' uso del 128 come terminatore non so dirti niente
Ciao Uwe

Come signed char 128 vuol dire -1.
Personalmente non mi ricordo di averlo mai visto.
Dove l'hai visto questo controllo ?

x uwe: no uwe, normalmente il char e' signed, quindi fino a 127,
Anche nel mondo arduiniano se dichiari una variabile Char stai usando una variabile signed. E' il datatype Byte che e' unsigned.

x nid: l'ho visto in giro per codici, cose tipo cosi':

byte Char;
if ((Char == 0) || (Char == 128)) break;

x uwe: no uwe, normalmente il char e' signed, quindi fino a 127,
Anche nel mondo arduiniano se dichiari una variabile Char stai usando una variabile signed. E' il datatype Byte che e' unsigned.

http://arduino.cc/en/Reference/Char
Hai ragione. Errore mio.
Ciao Uwe

nid69ita:
Come signed char 128 vuol dire -1.

-1 viene usato in ambito C come valore di ritorno di funzioni e significa errore. Forse per questo?
Ciao Uwe

Le stringhe intese come char array si terminano con 0x00 ed è l'unico valore che le varie funzioni della librerie standard vanno a cercare, del resto, non per nulla ... si chiamano "null-terminated strings".

Come dice giustamente Uwe, non confondere la ricerca dei "terminatori di stringa" con altri test. Ad esempio, la Serial.read() di Arduino, in caso di nessun carattere nel buffer, ritorna appunto -1 quindi ... se tu vuoi testare se la stringa è finita (0x00) o se non ci sono più caratteri nel buffer (-1) fai IF per entrambi i valori. :wink:

Guglielmo

ok, questa e' una info in piu' che mi sfuggiva,
ma per sfruttare un eventuale riconoscimento di errore si sarebbe dovuto lasciare Char come tipo char, invece qui Char e' specificatamente un tipo byte :cold_sweat:
Forse e' semplicemente un errore di programmazione :slight_smile:

Hanno fatto di peggio ... guardati il reference della Serial.read() ...

Returns : the first byte of incoming serial data available (or -1 if no data is available) - int

... hanno definito che la funzione ritorna ... un INT ... solo per poter restituire quel -1 :astonished: :astonished: :astonished:

Guglielmo

c'e' tanta ram sull'arduino, perche' lesinare un int ? :stuck_out_tongue_closed_eyes:

Almeno il tuo esempio funziona, nel mio caso invece e' proprio un errore, perche' se mi arriva un -1, avendo dichiarato CHar come byte, vado in overflow.

Il codice corretto quindi dovrebbe essere cosi':

char Char; //dichiarata char, non byte
if ((Char == 0) || (Char == 128)) break;

E' per essere piu' chiari:

char Char;
if ((Char == 0) || (Char == -1)) break;

siete daccordo ?

128 in binaio è
10000000

se lo trasformiamo in SIGNED, il più a sinistra è il bit di segno, e gli altri sono 0, che per il COMPLEMENTO A DUE (tutti bocciati xD) vale -128 (infatti il range da 127 a -128 è datoi proprio dal fattoche si sono 256 simboli, 128 per "segno", ma a quelli positivi si conta anchelo 0, e tra i negativi si è preferito avere il -128 anzichè un inutile(?) -0, anche perchè se non avrebbe rotto l'ultilità del complemento a due)

che dire, senza vedere da dove e come pesca quel char/byte, è dura capire perchè si comporti così, magari tiene in considerazioni altri charset? la ascii estesa "ISO 8859-1" (usata da molti siti) dice che il carattere 128 è il €

lesto:
..., che per il COMPLEMENTO A DUE (tutti bocciati xD) ...

E vabbè dai, un pò di ruggine con la rappresentazione interna :grin:

quindi ricapitolando quello strano ==128 non ha nessun senso, sia lasciando la variabile Byte, sia cambiandola in Char

A questo punto o si usa la mia seconda ipotesi, che modifica il byte in char e si va ad intercettare il -1 (restituito come errore dalla funzione di lettura)
oppure cambiare del tutto e fare un pre controllo sul dato arrivato (idea di lesto), accettando solo dati tra 0-127 il resto lo si butta
Aggiungo un ultima idea, modificare il controllo per accettare solo dati tra 1-127, trattando lo 0 di fine stringa alla pari di un eventuale -1 di errore, oppure di qualsiasi altro dato che non interessa, cioe' se mi arriva un 128 non mi interessa, ma nemmeno se mi arriva un 129 o un 250 ecc

Testato:
oppure cambiare del tutto e fare un pre controllo sul dato arrivato (idea di lesto), accettando solo dati tra 0-127 il resto lo si butta
Aggiungo un ultima idea, modificare il controllo per accettare solo dati tra 1-127, trattando lo 0 di fine stringa alla pari di un eventuale -1 di errore, oppure di qualsiasi altro dato che non interessa, cioe' se mi arriva un 128 non mi interessa, ma nemmeno se mi arriva un 129 o un 250 ecc

Però così ti perdi :

¡¢£¤¥¦§¨©ª«¬®¯°± ... le lettere accentate e altri simboli che sono tra il 128 e il 255 ... quindi ...
... come al solito, non esiste un unica soluzione, ma dipende da quello che devi fare :grin: :grin: :grin:

Guglielmo

e' anche questo e' vero :slight_smile:
ok, credo l'argomento sia stato sviscerato,

karma per tutti :slight_smile:

Dalle mie conoscenze di C mi ricordo che ci sono 2 modi per utilizzare il char...
All'inizio era stato utilizzato a 7 bit + 1 bit per il check parrity di controllo degli errori.
Dopo è stato esteso a 8 bit per inserire le lettere accentate e i simboli strani....

ciao
Manuel

esatto, il 7 bit è lo standard ascii, per l'estesa.. ci sono mille standard, il più famoso è l'ISO 8859-1 grazie al fatto che pè usato per moltissime pagine web, ma dato che non contiene altri alfabeti oltrea quello latino, sta venedo rimpiazzato dall'UTF-8 che utilizza da 1 a 4 o 6 (non ricordo bene) byte. i caratteri ASCII sono compatibili, ma non l'estesa; in oltre l'UTF-8 viene evitato per i micro visto che occupa un numerovariabile di bye, è cpiù complesso da gestire oltre che occupare più risorse.
però visrtualmente non ha limiti sul numero di alfabeti da memorizzare, quindi almeno peri sistemi più potenti l'UTF-8 piano piano sta diventando standard universale.

L'ASCII definisce solo i primi 127 caratteri, dal 128° è "giungla" ossia ognuno fa come vuole. Il set di caratteri dell'MS-DOS conteneva caratteri semigrafici usati per costruire maschere a video in modalità testuale, mentre sui Commodore c'erano altri tipi di caratteri semigrafici usati per "simulare" una grafica a bassa risoluzione (soluzione usata anche sui computer Sinclair). Poi con l'avvento delle localizzazioni si è avuto il problema dei caratteri delle varie lingue e dei loro caratteri speciali (noi Italiani pensiamo solo alle lettere accentate nostre, ma guardate una lingua del nord-europa quanti accenti ha!) per cui hanno inventato nuovi set.