Non riesco a capire cosa fa codePointAt(). Mi potete spiegare e fare un esempio semplicissimo?
grazie
Non riesco a capire cosa fa codePointAt(). Mi potete spiegare e fare un esempio semplicissimo?
grazie
Le stringhe Java internamente sono memorizzate come sequenze di char da 2 byte ciascuno; questo deriva dal fatto che, nel momento in cui Java è stato inizialmente progettato, 2 byte bastavano per ogni carattere Unicode (e dunque le stringe Java in principio usavano un encoding con caratteri di lunghezza fissa, proprio perché un char bastava per qualunque caratter Unicode).
Da un certo punto in poi (mi pare attorno al 1996) lo standard Unicode è stato espanso a più di 65536 caratteri, motivo per cui 2 byte non sono più sufficienti per poter rappresentare qualunque carattere Unicode; per questo, praticamente tutti i sistemi che in passato usavano dei char da 2 byte per memorizzare caratteri Unicode sono passati dall'encoding UCS-2 (1 codepoint Unicode = 1 carattere da 2 byte) all'UTF-16 (1 codepoint Unicode = 1 carattere da 2 byte se è sotto un certo valore, altrimenti viene separato in due caratteri distinti).
Anche Java, quindi, è passato a UTF-16, motivo per cui una stringa non è più un oggetto così semplice, ma può contenere i cosiddetti "surrogate pairs", ovvero coppie di char (riconoscibili perché hanno un pattern di bit particolare) che in realtà rappresentano un singolo codepoint Unicode.
Ed è qui che entra in gioco la funzione codePointAt; se ti limiti ad usare la funzione charAt ottieni il char memorizzato nella stringa alla posizione specificata. Problema: e se quel char è il primo di un surrogate pair? In tal caso, il char che ottieni non è un codepoint completo, ma solo la prima parte, per cui hai ottenuto un'informazione incompleta (e sostanzialmente inutile). Per questo motivo, esiste la funzione codePointAt, che, se alla posizione specificata c'è un surrogate pair, legge anche il char successivo e ricostruisce il codepoint così codificato, altrimenti funziona come la charAt.
Da leggere assolutamente: http://www.joelonsoftware.com/articles/Unicode.html; da darci almeno un'occhiata: http://en.wikipedia.org/wiki/UTF-16.
Amaro C++, il gusto pieno dell'undefined behavior.
In pratica è una funzione che permette di interpretare i nuovi caratteri char a 32 bit definiti con 2 vecchi char a 16 bit. Questo discorso l'ho capito ma quello che non ho compreso è cosa fa fisicamente la funzione così vorrei vedere un esempio pratico se possibile. Su google non trovo esempi con questo metodo e i link che mi hai passato non sono visionabili.
Grazie
Un minimo di intraprendenza dai, stai cercando la pappa pronta...Originariamente inviato da peruzzo
i link che mi hai passato non sono visionabili.
Il forum ha inserito nell'url anche il ; e il . (punto) Toglili e magia, i link funzionano...Originariamente inviato da MItaly
Da leggere assolutamente: http://www.joelonsoftware.com/articles/Unicode.html; da darci almeno un'occhiata: http://en.wikipedia.org/wiki/UTF-16.
SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
Di questo libro e degli altri (blog personale di recensioni libri) | NO M.P. TECNICI
Ho provato a scrivere un codice per visualizzare un carattere a 32 bit per vedere la differenza tra charAt e codePointAt ma non ci sono riuscito, potete aiutarmi per favore senza mandarmi pagine in inglese lunghissime da leggere?
Esempio con domande:
codice:class Esempio { public static void main(String[] args) { String s = "hbubh}§╬┘─_¶1ì水"; char char1 = (char) s.codePointAt(14); //Non capisco perché devo fare il casting char char1b = (char) s.charAt(14); System.out.println(char1); System.out.println(char1b); char d[] = Character.toChars(0x10FFFF); String g = d.toString(); //Speravo di vedere i 2 caratteri char che definiscono il char n° 1114111 System.out.println(d); //Valori maggiori di FFFF sono tutti quadrati! Come fare per vedere i caratteri a 32 bit su windows 8? System.out.println(g); //Non capisco cosa stampa! char char2 = (char) g.codePointAt(0); char char2b = (char) g.charAt(0); System.out.println(char2); System.out.println(char2b); } }![]()
Scusa eh, ma se la questione è ricorrente ed è già spiegata (molto meglio di come potrei fare io) da altri perché devo perdere mezz'ora a riscriverti le stesse cose?Originariamente inviato da peruzzo
potete aiutarmi per favore senza mandarmi pagine in inglese lunghissime da leggere?
In ogni caso, la prima la devi leggere, c'è tanto di scritta nel titolo: "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)"; della seconda devi almeno avere un'idea, altrimenti stiamo a parlare di surrogate pairs ma non hai idea di cosa siano.
Infatti non devi. codePointAt non restituisce un char ma un int, proprio perché in Java un char è da 2 byte, e non può contenere tutti i codepoint Unicode (tutto il punto della codePointAt è che certi codepoint non possono essere rappresentati da un singolo char, ma da dei surrogate pairs).Non capisco perché devo fare il casting
Se li rimetti in una stringa al momento di stamparli li vedrà come un codepoint singolo - è esattamente il punto dei surrogate pairs!char d[] = Character.toChars(0x10FFFF);
String g = d.toString(); //Speravo di vedere i 2 caratteri char che definiscono il char n° 1114111Piuttosto, puoi stamparli singolarmente come se fossero interi e vederne i valori.
Questo è un problema indipendente, la console di Windows ha un supporto quantomeno bizzarro per Unicode - cioè, lo supporta ma (1) di default usa dei codepage senza senso e (2) il font di default usato fornisce solo un set ristretto di caratteri.System.out.println(d); //Valori maggiori di FFFF sono tutti quadrati! Come fare per vedere i caratteri a 32 bit su windows 8?
Un esempio più sensato può essere:
Output:codice:class Main { public static void main(String[] args) { // I caratteri alle posizioni 4/5, 7/8, 10/11 richiedono surrogate pairs String s = "abcd𝒞a𝒮b𝔹asdf"; System.out.println((int)s.charAt(0)==s.codePointAt(0)); // true, infatti il primo carattere sta in un solo char System.out.println((int)s.charAt(4)==s.codePointAt(4)); // false, il carattere alla posizione 4 richiede surrogate pairs // esaminiamo da "vicino" un carattere strambo System.out.print(s.substring(4,6) + " = codepoint " + Integer.toString(s.codePointAt(4),16)); System.out.println(" = coppia surrogata " + Integer.toString(s.charAt(4),16) + " - " + Integer.toString(s.charAt(5),16)); } }
Lo vedi in azione qui (sulla console di Windows potrebbe dare problemi per i motivi scritti prima).codice:true false 𝒞 = codepoint 1d49e = coppia surrogata d835 - dc9e
(per pescare caratteri che sicuramente richiedono surrogate pairs ma sono ragionevolmente diffusi, vedi ad esempio qui)
Amaro C++, il gusto pieno dell'undefined behavior.