Pagina 1 di 2
Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 19:05
da gila75
Mi sono imbattuto per caso in un fatto a me sconosciuto.
Stavo facendo un programma che in ogni frase dice quante virgole, spazi, lettere, insomma tutto ci sono
non funziona però per caratteri tipo
ù,è ecc... tutti quelli che vengono dopo il 126 nel codice ascii.
Pensavo fosse un problema dichiarare
visto che char è di tipo signed, ma anche facendo unsigned char (quindi da 0 a 255) non ottengo nulla!!
Mi sa che mi sto perdendo in un bicchier d'acqua

Re: Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 19:08
da Zoff
ù occupa due byte (l'inserimento da tastiera utilizza come codifica UTF8).
Prova questo nella console:
Maggiori info. Unicode e multibyte characters:
http://www.cprogramming.com/tutorial/unicode.html
Re: Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 19:16
da gila75
Grazie Zoff
Infatti mi da
Codice: Seleziona tutto
warning: multi-character character constant [-Wmultichar]
Adesso guardo
Re: Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 20:07
da gila75
Purtroppo l'argomento wide-char e multichar che ho sul manuale l'ho (stupidamente) saltato pensando non mi servisse come base del C.
provvederò.
Se non è troppo disturbo, mi potreste fare un esempio di stampa per esempio di 'ù' ?
la cosa strana è che in una stringa con la specifica di conversione %s stampa correttamente.
Intanto grazie, aspetto se qualcuno mi fornisce un esempio, se no metto risolto (che poi non è risolto

) e studio per i fatti mie.
Grazie @Zoff
Re: Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 20:08
da Claudio_F
Ne ho accennato diverse volte, ad esempio (e c'è la prova di stampa!):
forum.ubuntu-it.org/viewtopic.php?f=33&t=572659&view=unread#p4518705
Il fatto è che 'ù' non è un carattere previsto nel set ASCII originale a 7 bit, quindi il compilatore lo deve convertire (codificare) in un qualche formato (encoding), che però non è detto sia lo stesso che verrebbe usato da altri compilatori su architetture o sistemi operativi diversi.
Questo vuol dire che se non si affronta esplicitamente il problema dell'encoding si possono scrivere cose illeggibili su altri sistemi.
Per mettere d'accordo tutti si è inventato l'unicode (i primi 128 valori corrispondono esattamente all'ASCII originale). In unicode il carattere 'ù' ha un valore ben preciso e universale. Da questo punto di vista le stringhe di caratteri dovrebbero essere sempre di tipo unicode (non so se il C le supporta in qualche modo), e strlen riporterebbe sempre l'esatto numero di caratteri.
Solo al momento di trasmettere o salvare su disco questi "caratteri astratti" (rappresentati nella macchina con l'unicode universale) le stringhe andrebbero encodate, ottenendo così delle stringhe codificate (in ASCII, utf-8, iso-8859-1, windows-1252 ecc ecc), cioè in sostanza gli array di caratteri/byte che hai usato fino ad adesso.
La codifica implicita in Ubuntu vedo che è la utf-8, questo vuol dire che un file di testo prodotto da un tuo programma C su Linux potrebbe apparire errato se letto da un programma windows che non tiene conto dell'encoding con cui è stato scritto (e viceversa). In sostanza affinché un testo contenente caratteri diversi da quelli ASCII 7 bit sia leggibile è sempre necessario conoscere l'encoding usato per generarlo (ad esempio ho dei vecchi testi scritti con l'MS-DOS che sono riuscito a rileggere correttamente solo quando ho scoperto che in lettura dovevo effettuare un decode con cp-437).
Sintesi del papiello: ricorda che in C su Linux stai trattando stringhe di caratteri codificati in utf-8, e strlen non riporta il numero di "caratteri astratti", ma il numero di bytes che servono a codificarli con quell'encoding.
Re: Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 20:12
da gila75
Grazie Claudio_F non ricordavo quella discussione
Adesso leggo per bene
EDIT: il bello che al 3d ho partecipato anche io...mazza oh 40 anni è già perdo la memoria

Re: Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 20:55
da gila75
Il programmino che mi ha fatto notare la stranezza è questo (scrittura di prova):
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 127
int main(int argc, char *argv[])
{
char testo[1000]="Sto chiedendo aiuto al Forum Ubuntu!! :)";
char index[N]={0};
int i,len,x;
len=strlen(testo);
for (i=0; i<len; i++)
{
x=testo[i];
index[x]++;
}
for (x=0; x<N; x++)
{
if(index[x]!=0)
{
printf ("%c=%d ",x,index[x]);
}
}
return 0;
}
ma con i multicaratteri non funziona. Mi serve solo per tenere in memoria nella mia libreria. In se è una sciocchezza, ma almeno lo conservo.
Ora studio come farlo funzionare anche con multi caratteri
Re: Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 21:18
da Claudio_F
Strutturato così com'è è mi sembra un non senso parlare di farlo funzionare con i multicaratteri, il carattere 'ù' in ogni caso non troverà mai posto nel range 0..127. Si può invece sicuramente scrivere un riconoscitore di caratteri codificati utf-8, in tal caso il carattere 'ù' è la sequenza di byte: 195 185
Il problema è che per trattare coerentemente del testo (1 carattere == 1 posizione nell'array) in modo indipendente dalla piattaforma/linguaggio *non* bisognerebbe lavorare con stringhe codificate (a meno di usare solo l'ASCII stretto) ma solo stringhe unicode, allora la 'ù' vale (sempre) 248, la '€' vale (sempre) 8364, la '戎' vale sempre 25102 ecc.
Re: Perplessità codice ASCII
Inviato: giovedì 4 giugno 2015, 21:37
da gila75
Claudio_F [url=http://forum.ubuntu-it.org/viewtopic.php?p=4765619#p4765619][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Strutturato così com'è è mi sembra un non senso parlare di farlo funzionare con i multicaratteri, il carattere 'ù' in ogni caso non troverà mai posto nel range 0..127. Si può invece sicuramente scrivere un riconoscitore di caratteri codificati utf-8, in tal caso il carattere 'ù' è la sequenza di byte: 195 185
Il problema è che per trattare coerentemente del testo (1 carattere == 1 posizione nell'array) in modo indipendente dalla piattaforma/linguaggio *non* bisognerebbe lavorare con stringhe codificate (a meno di usare solo l'ASCII stretto) ma solo stringhe unicode, allora la 'ù' vale (sempre) 248, la '€' vale (sempre) 8364, la '戎' vale sempre 25102 ecc.
Sicuramente non avrà senso il mio programma, non metto in dubbio.
Il problema è sorto dopo, non sapevo di questa cosa, o perlomeno l'avevo scordata.
Il programma lo posso o meglio lo devo rifare daccapo a sto punto.
Range 0-127 come prontamente hai notato è perchè non sapevo.
Devo fare prove e approfondire l'argomento sul libro.
Sono in ascolto di consigli intanto
Re: Perplessità codice ASCII
Inviato: venerdì 5 giugno 2015, 6:23
da gila75
Mi sto documentando sul set unicode e UTF-8.
Da quanto ho capito dopo il 127 del codice asci, si usano 2 byte da 128 a 2047 poi 3 byte da 2047 a x ecc.. ecc...
Per esempio ù è composto da 2 byte che in valore decimale sono:
195
185
La spiegazione del valore dei 2 bytes sopra, l'ho letta e capita, ma devo approfondire bene, ma per ora tralasciamo.
la mia domanda è: come faccio sapendo il codice a stampare il carattere:
Codice: Seleziona tutto
#include <stdio.h>
#include <string.h>
void main(void)
{
char s[] = "§"; //151
int i = 0;
while (s[i] != '\0') ++i;
printf("\n\nLunghezza con strlen simulata: %d\n", i);
i = strlen(s);
printf("Lunghezza con strlen vera: %d\n", i);
printf("\nBytes che compongono l'array:\n");
for (i=0; i<strlen(s); i++)
printf("\t%d\n", 0xFF&s[i]);
}
@Claudio, sono andato sul link da te proposto e ho copiato il tuo programma.
io so che la a con i 2 puntini sopra (non ricordo mai il nome), ha codice unicode E4 e i due bytes sono 195 e 164.
Come posso fare per stampare il carattere sapendo i suddetti codici?
Il mio manuale parla anche di wide character, ma credo non sia una cosa portabile giusto?
Re: Perplessità codice ASCII
Inviato: venerdì 5 giugno 2015, 20:49
da gila75
Sto leggendo tutto ciò che riguarda i caratteri multibyte e i wide character e le varie funzioni di conversione.
Mamma mia che carnaio!!! Quanta roba.
Domanda: è conveniente studiarci su o sono casi molto particolari da programmatore esperto?
Re: Perplessità codice ASCII
Inviato: venerdì 5 giugno 2015, 21:06
da gila75
Per stampare in base al codice unicode per ora ho risolto così:
Codice: Seleziona tutto
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
int main()
{
wchar_t wchar=0;
int i;
setlocale(LC_CTYPE, "it_CH.utf8");
for (i=wchar; i<300; i++)
wprintf(L"[%d]%lc\n", i,i);
return 0;
}
è solo una prova rozza, ma inizio un po' a capire.
Fatemi sapere (se vi va ) se è corretto
EDIT il programma era incompleto ora funziona. Ecco alcuni cartatteri:
丄 丅 丆 万 丈 三 上 下 丌 不 与 丏 丐 丑 丒 专 且 丕 世 丗 丘 丙 业 丛 东 丝 丞 丟 丠 両 丢 丣 两 严 並 丧 丨 丩 个 丫 丬 中 丮 丯 丰 丱 串 丳 临 丵 丶 丷 丸 丹 为 主 丼 丽 举 丿 乀 乁 乂 乃 乄 久 乆 乇 么 义 乊 之 乌 乍 乎 乏 乐 乑 乒 乓 乔 乕 乖 乗 乘 乙 乚 乛 乜 九 乞 也 习 乡 乢 乣 乤 乥 书 乧 乨 乩 乪 乫 乬 乭 乮 乯 买 乱 乲 乳 乴 乵 乶 乷 乸 乹 乺 乻 乼 乽 乾 乿 亀 亁 亂 亃 亄 亅 了 亇 予 争 亊 事 二 亍 于 亏 亐 云 互 亓 五 井 亖 亗 亘 亙 亚 些 亜 亝 亞 亟 亠 亡 亢 亣 交 亥 亦 产 亨 亩 亪 享 京 亭 亮 亯 亰 亱 亲 亳 亴 亵 亶 亷 亸 亹 人 亻 亼 亽 亾 亿 什 仁 仂 仃 仄 仅 仆 仇 仈 仉 今 介 仌 仍 从 仏 仐 仑 仒 仓 仔 仕 他 仗 付 仙 仚 仛 仜 仝 仞 仟 仠 仡 仢 代 令 以 仦 仧 仨 仩 仪 仫 们 仭 仮 仯 仰 仱 仲 仳 仴 仵 件 价 仸 仹 仺 任 仼 份 仾 仿 伀 企 伂 伃 伄 伅 伆 伇 伈 伉 伊 伋 伌 伍 伎 伏 伐 休 伒 伓 伔 伕 伖 众 优 伙 会
Re: Perplessità codice ASCII
Inviato: sabato 6 giugno 2015, 21:08
da gila75
Mi sto accorgendo però che il programma che ho pensato è praticamente impossibile.
I caratteri unicode sono decine di migliaia. Se non restringo il cerchio è praticamente impossibile.
Per ora a me interessa includere caratteri come è,à,ù ecc..
La cosa però che mi preme un po' sapere è:
è conveniente studiarci su o sono casi molto particolari da programmatore esperto?
Grazie a tutti per eventuali consigli
Re: Perplessità codice ASCII
Inviato: sabato 6 giugno 2015, 21:25
da Claudio_F
è conveniente studiarci su o sono casi molto particolari da programmatore esperto?
È qualcosa da gestire tutte le volte che si ha a che fare con testo non strettamente ASCII (anche la prima lettera di questo testo non è ASCII

)
Re: Perplessità codice ASCII
Inviato: domenica 7 giugno 2015, 8:53
da gila75
Capisco.
Devo riflettere bene sul caso. Con la conversione delle stringhe classica %s ottengo un output giusto anche con carattermi multibyte, idem se non erro
scrivendo un testo su file da programma C. Il discorso cambia per esempio con strlen, che mi riporta 2 su 'ù', quindi a conti fatti, vero che 'ù' è composto da 2 bytes, ma
al lato pratico io lo devo interpretare come un carattere nella lunghezza complessiva di una stringa (umanamente parlando).
Insomma ho capito, ma al tempo stesso non ne colgo appieno le potenzialità.
Ora proverò tutte le funzioni di conversione messe a disposizione del C per poter convertire da multibytes a wide e viceversa.
Grazie
Re: Perplessità codice ASCII
Inviato: domenica 7 giugno 2015, 13:22
da Claudio_F
Con la conversione delle stringhe classica %s ottengo un output giusto anche con carattermi multibyte
Probabilmente perché il terminale è impostato per default per ricevere stringhe codificate utf-8, idem per l'immissione di caratteri da tastiera. Ma abbiamo un funzionamento corretto solo perché il programma funziona all'interno di un contesto già impostato in un certo modo.
idem se non erro scrivendo un testo su file da programma C
Magari rileggendo quel file da windows i caratteri sono scombinati (in effetti ogni file di testo non ASCII non è leggibile correttamente se manca l'informazione sull' encoding usato).
al lato pratico io lo devo interpretare come un carattere nella lunghezza complessiva di una stringa (umanamente parlando)
Per questo tutto il testo non ASCII andrebbe sempre trattato in forma unicode (immagino sia il tipo wide del C), e codificato in utf-8 o altro solo al momento di salvarlo. Ovviamente in lettura va sempre decodificato per farlo tornare unicode "astratto e universalmente compatibile".
Insomma ho capito, ma al tempo stesso non ne colgo appieno le potenzialità.
Più che altro è un sovraccarico di lavoro per il programmatore dovuto al fatto che quando sono nate le prime codifiche si pensava che sarebbero bastati 7 bit. Poi hanno tamponato con le codepage per sfruttare anche i rimanenti 128 valori, creando però incompatibilità tra sistemi impostati per codificare/decodificare il testo con codepage diverse. L'unicode è l'ultimo tentativo di mettere d'accordo tutti, ma le diverse codifiche fisiche sottostanti rimangono.
Ma da una parte è anche un bene, perché basta specificare l'encoding giusto e si è in grado di leggere qualsiasi file di testo... poi la corretta visualizzazione a video di quei caratteri dipende dai glifi installati sullo specifico sistema.
Invece una possibile fonte di guai colossali è andare a codificare caratteri non ASCII nei nomi di file e directory...
Re: Perplessità codice ASCII
Inviato: domenica 7 giugno 2015, 13:47
da Vincenzo1968
Per ottenere la lunghezza della stringa in caratteri(anziché byte) devi usare la funzione wcslen.
In generale, per array di tipo wchar_t, esistono le corrispondenti funzioni di libreria ma con prefisso wcs al posto di str.
Per esempio, strcpy diventa wcscpy:
widechar.c:
Codice: Seleziona tutto
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <wchar.h>
/*
gcc -Wall -Wextra -pedantic -O2 widechar.c -o widechar
*/
int main()
{
wchar_t str[1024];
int index;
int len;
if ( !setlocale(LC_CTYPE, "it_IT.utf8") )
{
fprintf(stderr, "Impossibile selezionare it_IT.utf8!\n");
return EXIT_FAILURE;
}
wcscpy(str, L"き ki, ひ hi, み mi\n");
len = wcslen(str);
printf("\n%ls\n", str);
for ( index = 0; index < len; index++ )
{
printf("str[%d] = %lc\n", index, str[index]);
}
return EXIT_SUCCESS;
}
output:
Codice: Seleziona tutto
[vincenzo]$ gcc -Wall -Wextra -pedantic -O2 widechar.c -o widechar
[vincenzo]$ ./widechar
き ki, ひ hi, み mi
str[0] = き
str[1] =
str[2] = k
str[3] = i
str[4] = ,
str[5] =
str[6] = ひ
str[7] =
str[8] = h
str[9] = i
str[10] = ,
str[11] =
str[12] = み
str[13] =
str[14] = m
str[15] = i
str[16] =
Ti consiglio di utilizzare la libreria ICU:
http://site.icu-project.org/
http://userguide.icu-project.org/howtouseicu
Codice: Seleziona tutto
sudo apt-get install libicu-dev icu-devtools icu-doc
Re: Perplessità codice ASCII
Inviato: domenica 7 giugno 2015, 14:12
da gila75
Grazie Claudio&Vincenzo.
é una scatola cinese il C

Fai un programmino stupido e capisci di non sapere ancora una mazza dopo un paio d'anni!!!
Ora leggo bene (@Claudio) quello che hai scritto e poi provo (@Vin) quello che hai postato.
Ho provato qui, su vista, a testare con strlen la stringa 'à' e mi da un byte a differenza di ubuntu.
Ma io dico, al di la di tutto, ma non si possono mettere una volta per tutte nel 2015 d'accordo sulla portabilità?
Win fa una cosa, linux altre, mac...
Lo so è un discorso da ignorante, le cose non sono così semplice però....
Qui che davvero la "globalizzazione" sarebbe d'aiuto, non si fa

Re: Perplessità codice ASCII
Inviato: domenica 7 giugno 2015, 15:32
da Vincenzo1968
Ti conviene togliere Windows e installare Ubuntu.
Scherzo(ma non troppo

).
Il programmino postato sopra funziona solo su Linux.
In buona sostanza, su windows, devi impostare il codepage per utf-8 tramite il comando(da console)
chcp
Codice: Seleziona tutto
C:\prova> chcp
Active code page: 437
C:\prova> chcp 65001
Active code page: 65001
o, da codice, tramite la chiamata alla API
SetConsoleOutputCP:
Devi anche impostare il font "Lucida console" (click destro sulla console -> proprietà -> tipo di carattere).
Re: Perplessità codice ASCII
Inviato: domenica 7 giugno 2015, 18:39
da gila75
Ti conviene togliere Windows e installare Ubuntu.
non è il mio pc, faccio solo prove al week-end quando non sono sul mio pc,ma su vista. Io ormai non uso più windows, se non per applicazioni
che girano solo sotto win