Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

TDD o Test-Driven Development
immagine docker per lavorare con lazarus e free pascal
Indice
Installare lazarus su mac osx sierra
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non)
Advanced Record Syntax: un esempio pratico
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
DB concetti fondamentali e DBGrid
Advanced Record Syntax
DB concetti fondamentali e ZeosLib
DB concetti fondamentali e connessioni standard
guida all'installazione di fpc trunk da subversion in linux gentoo
Creare un server multithread
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Free Pascal e Lazarus sul Raspberry Pi
fpcup: installazioni parallele di lazarus e fpc
Ubuntu - aggiornare free pascal e lazarus
Come interfacciare periferica twain
Lazarus 1.0
Aspetto retrò (Cmd Line)
Disporre le finestre in un blocco unico (come Delphi)
Zeos ... dietro le quinte (prima parte)
Lavorare con file in formato JSON con Lazarus
Overload di operatori
Dataset virtuale
Linux + Zeos + Firebird
Pascal Script
La gestione degli errori in Lazarus
Indy 10 - Invio email con allegati
Brute force
Le permutazioni
Da DataSource a Excel
StatusBar - aggirare l'errore variabile duplicata
Visualizzare un file Html esterno
Evidenziare voci TreeView
Toolbar
Direttiva $macro
Indy gestiore server FTP lato Client
TImage su Form e Panel
PopUpMenu sotto Pulsante (TSpeedButton)
Conversione numerica
Proprietà
Funzioni a parametri variabili
Overload di funzioni
Liste e puntatori
Conferma di chiusura di un applicazione
Il file: questo sconosciuto
UIB: Unified Interbase
System Tray con Lazarus
Intercettare tasti premuti
LazReport, PDF ed immagini
Lazarus e la crittografia
Ampliare Lazarus
Generare controlli RUN-TIME
TTreeview e Menu
TTreeView
Utilizzare Unità esterne
Lavorare con le directory
Realizzare programmi multilingua
Codice di attivazione
File INI
Esempio lista in pascal
Stabilire il sistema operativo
Recuperare codice HTML da pagina web
Trascinare un file nel programma
Mandare mail con Lazarus
Welcome to Italian community of Lazarus and Free Pascal. Please login or sign up.

Recenti

How To

Utenti
Stats
  • Messaggi totali: 20.582
  • Totale discussioni: 2.471
  • Online today: 310
  • Online ever: 5.949 (Luglio 30, 2026, 09:49:59 PM)
Utenti online
5 Visitatori, 1 Utente

[Risolto] Caratteri non più leggibili con le nuove versioni di Lazarus

Aperto da tito_livio, Novembre 12, 2024, 12:57:16 AM

Discussione precedente - Discussione successiva

tito_livio

Ciao a tutti,
ho un progetto in Lazarus 2.0.6 per Windows a 32 bit che lavora con dati in un DB MySql 5.0, che vorrei convertire in Lazarus con una versione attuale a 64 bit.
Quindi ho compilato con la nuova versione di lazarus (3.6) ma c'è un problema.
I caratteri con lettere accentate, e anche altri, non sono più leggibili. Per esempio per un certo campo, di una tabella del db, prima leggevo àèìòù @€# adesso con il nuovo programma leggo à èìòù @â,¬#.
Nel programmi, sia quello vecchio che quello nuovo, non definisco il charset, mentre quello del db Mysql è latin1.
Come si potrebbe risolvere, secondo voi, questo problema?
Grazie

bonmario

Ciao,
scusami se sarò impreciso, ma sono anni che non mi capita questa cosa !!!
Per prima cosa, fai un backup del tuo progetto.

Fatto il backup, apri il progetto e poi vai su Strumenti ==> Converti codifica dei progetti/pacchetti (da me è il quintultimo).
nella prima combobox, scegli "Progetto corrente", e compili tu quello che ti interessa dei campi successivi. In fondo al dialogo, c'è una tabellina che ti riassume sorgente per sorgente qual è la codifica che ha rilevato prima di fare il lavoro.

Fammi sapere se risolvi o meno così, perché se non risolvi, oltre a questo, bisogna fare un altro lavoro, che però non ricordo a memoria, ma dovrei andare a cercare nei miei appunti

Ciao, Mario

DragoRosso

@tito_livio

Ti rimando a questa discussione sui caratteri: https://www.lazaruspascal.it/index.php?topic=2848.msg19416#msg19416

Per quello che riguarda il set caratteri, il tuo DB usa il set standard che comprende anche caratteri accentati, è necessario che il tuo programma si allinei a queste set.

Normalmente "Latin 1" comprende i caratteri ASCII (i primi 128) più altri 128 "Latin-1 Supplemental".

Quelli che vedi ora sono i caratteri del "Latin-1 supplemental" come definiti dallo standard.

Il tuo vecchio programma ha inserito i caratteri nel database secondo la vecchia notazione a "CodePage", mentre il nuovo lavora in modalità diversa.

Questa è la pagina github che ti fà vedere una utility (dovrebbe essere compresa in Lazarus già) che converte stringhe da un set all'altro. Devi trovare il set usato dal tuo programma vecchio (probabilmente "CP1250").

https://github.com/alrieckert/lazarus/blob/master/components/lazutils/lconvencoding.pas

O in alternativa settare il set di caratteri di default x Lazarus, ma non saprei come fare.
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

Ahh, nota aggiuntiva.

Consiglio spassionato, se ti è possibile ovviamente, è quello di lavorare in Utf-8.

Quindi una volta aggiornato il programma, convertire tutto il database in UTF-8. Da quel momento li non avrai più problemi di codifica e potrai lavorare con tutte le lingue del mondo (o quasi tutte) senza pensieri.

Ricodificare i testi in utf-8 nel database non rappresenta un problema, sempre che non usi ovviamente chiavi o indici o "campi collegati" di tipo stringa. Se è così allora meglio che dimentichi questa ultima parte.

C'è anche da dire rispetto a questo punto (utf-8), che occorre fare attenzione al fatto che Lazarus e FPC non sono ancora totalmente compatibili con Unicode (Utf-8 è una delle codifiche comprese nell'universo unicode).

Per esempio se cerchi di trovare un carattere tramite la funzione POS in una stringa unicode il risultato potrebbe essere errato. Per farlo devi usare le funzioni specifiche e abilitare UNICODE in Lazarus.

Più volte ho riportato ciò, ma ho avuto solo smentite parziali.

Se qualcuno che lavora con Lazarus a livello professionale potesse chiarire in modo definitivo questo  punto sarebbe utile (anche a me, ringrazio anticipatamente).

Ciao
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

nomorelogic

ciao tito_livio

potresti vedere con quale charset è stato creato il DB in MySql?

Se ad esempio trovi qualcosa tipo:
CREATE DATABASE `database_di_prova` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */;

già sappiamo che i dati sono memorizzati nel DB in uft8.

Poi dovresti vedere anche la tabella che ti interessa, vedere se nel DDL c'è qualcosa tipo:

CREATE TABLE `tabella_001` (
   ...
   ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;



Secondo me potrebbe chiarirci meglio il problema.

Ciao



Edit:
se ad esempio fai un backup - che in fondo è uno script SQL - al suo interno puoi trovare sia le varie "CREATE" che le "INSERT"...
Imagination is more important than knowledge (A.Einstein)

tito_livio

Comincio a rispondere:

Citazione di: bonmario il Novembre 12, 2024, 07:27:34 AM
Fatto il backup, apri il progetto e poi vai su Strumenti ==> Converti codifica dei progetti/pacchetti (da me è il quintultimo).
nella prima combobox, scegli "Progetto corrente", e compili tu quello che ti interessa dei campi successivi. In fondo al dialogo, c'è una tabellina che ti riassume sorgente per sorgente qual è la codifica che ha rilevato prima di fare il lavoro.

Ho eseguito i passi che tu mi consigli ma come ti posso fare vedere nell'immagine allegata, lo strumento mi dice che è già tutto con la codifica corretta.
Vorrei aggiungere che:
-Questi problemi di codifica accadono solo nella memorizzazione su db, se, per esempio, la vecchia versione salva un file di testo con i caratteri accentati, la nuova li legge correttamente.
-Ho provato a compilare con una versione intermedia, la 2.2.4 a sia a 64 che a 32 bit, e il problema rimane. Quindi è qualcosa che è cambiato in Lazarus fra queste due versioni, la 2.0.6 e la 2.2.4


bonmario

Citazione di: tito_livio il Novembre 12, 2024, 11:57:52 AM
Comincio a rispondere:
Ho eseguito i passi che tu mi consigli ma come ti posso fare vedere nell'immagine allegata, lo strumento mi dice che è già tutto con la codifica corretta.

Ok, allora non sei nella situazione a cui pensavo io.
Ti conviene rispondere alle domande fatte dagli altri, e poi si vedrà come proseguire

DragoRosso

Citazione di: tito_livio il Novembre 12, 2024, 11:57:52 AM
-Questi problemi di codifica accadono solo nella memorizzazione su db, se, per esempio, la vecchia versione salva un file di testo con i caratteri accentati, la nuova li legge correttamente.

File di testo e DB sono cosa assolutamente diverse e non comparabili. Ciò che viene scritto e letto in un file di testo ha nei due "sensi" read/write un processamento ben diverso da quella che ha un DB (sempre read/write). Non parliamo poi della visualizzazione dei caratteri, anche questa ci mette del suo.

Giusto per capirsi: se io scrivo il carattere $D2 ovunque, questa viene interpretata in mille modi a seconda di chi lo legge (non di chi lo scrive).... $D2 in codepage 1250 è il carattere "Ń", ma se lo faccio leggere ad un giapponese (codepage 932) è il carattere "メ ".
(a titolo di curiosità, il carattere $D2 in UTF-8 è "Ò", giusto per agitare ancora più le acque).

Questo è più o meno accaduto a te. Hai scritto in un modo e il software odierno lo legge in un altro. Prima si usava il codepage 1250 ora si usa altro. Nel DB il dato è grezzo (dovrebbe essere ...) in binario.

Il DB non ha la capacità di convertire i dati, presuppone che entrino in un formato e escano in quel formato. Ma se hai scritto ciò mille anni fà, magari il formato non è più compatibile con quello attuale, o meglio non è più lo standard.
La compatibilità la si ottiene con le conversioni.

E' per questo che si sono inventati l'UNICODE, altrimenti sarebbe un disastro con l'interconnessione che c'è oggi tra i popoli.
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

#8
Giusto per darti una soluzione alla mano, i dati nel DB vengono trattai come Unicode (utf-8), ma è probabile che il software avesse scritto i dati in CP 1250.

Prova semplicemente a leggere una stringa e convertirla in CP1250 ... guarda il risultato e sono convinto che potrebbe funzionare.

La conversione è solo in fase di visualizzazione .... spero che sia chiaro ... Però in questo momento mi sfugge come visualizzare i caratteri di una stringa in un CPxxx o in un CPyyy ...

... bhè certo con le funzioni che ti ho indicato nel mio primo post ...
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

tito_livio

Citazione di: DragoRosso il Novembre 12, 2024, 02:56:32 PM
Giusto per darti una soluzione alla mano, i dati nel DB vengono trattai come Unicode (utf-8), ma è probabile che il software avesse scritto i dati in CP 1250.

Al momento sto "elaborando" tutto il materiale che mi hai fornito con i tuoi post, però ti posso dire che ho letto i dati scritti (col prog nuovo) come se fossero stati scritti in CP1250 (col prog vecchio).
In effetti quello che leggo cambia ma sono sempre caratteri indefiniti: ??é??? @#°€.
Mi spiego come ho fatto a leggerli in CP1250:
Premetto che uso i componenti "di serie" per accedere al db, quindi uso questa istruzione:
MySQL50Connection1.CharSet := 'CP1250';
Il problema è capire quale charset è stato utilizzato dal prog vecchio, quindi ho fatto diverse prove sostituendo al CP1250 i vari CP850, CP852,..., latin1, latin2 e altri, ne ho provato circa 20, i caratteri letti cambiano ma non sono mai quelli giusti.
Ho provato pure a mettere nel prog vecchio: showmessage(MySQL50Connection1.CharSet) ma non visualizza niente.

per adesso grazie a tutti per le risposte, continuo a sbatterci la testa.

Nota: I dati non sono stati scritti poi tanto tempo fa, la vers. 2.0.6 avrà circa 6-7 anni. Quest'estate ho convertito meglio da Delphi3-Paradox.

DragoRosso

I dati sono stati scritti probabilmente nel codepage della lingua usata al momento, che era lo standard per tutti gli applicati che non erano UNICODE.

Ma, essendo stati solo scritti a un solo carattere, ossia senza combinazioni UTF-8, sicuramente il DB non li ha convertiti in UTF8, li ha presi così come sono (fatto salvo i caratteri di "controllo" per certi valori sopra il codice ASCII 140 che possono alterare in lettura gli stessi caratteri).

Quindi dovrebbe essere relativamente semplice trovare la codifica giusta ....

Mi riesci a passare i valori esadecimali della stringa che leggi e i caratteri che dovrebbero essere visualizzati ... in cinque minuti dovrei risolverti il problema.

Basta anche che copi uno screenshot del debgger con i valori esadecimali (o anche decimali se ti và meglio), sempre però con i caratteri equivalenti che dovrebbero apparire nell'ordine.
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

tito_livio

Citazione di: DragoRosso il Novembre 12, 2024, 05:27:56 PM
Basta anche che copi uno screenshot del debgger con i valori esadecimali (o anche decimali se ti và meglio), sempre però con i caratteri equivalenti che dovrebbero apparire nell'ordine.

Mi potresti spiegare come si fa a far apparire il debbugger con i valori esadecimali della stringa?
Scusami ma io i valori in esadecimali non li guardo ed adesso non mi appaiono.

Citazione di: nomorelogic il Novembre 12, 2024, 10:03:51 AM
Edit:
se ad esempio fai un backup - che in fondo è uno script SQL - al suo interno puoi trovare sia le varie "CREATE" che le "INSERT"...

Fatto, questo è quello che compare: DEFAULT CHARSET=latin1. Ottenuto con un dump del database.

nomorelogic

se usi windows è quindi certo che il charset usato dal DB sia CP1250
quindi dovresti assicurarti che quando ti connetti come client, lo fai con lo stesso charset
quando dici che già usi
MySQL50Connection1.CharSet := 'CP1250';
dovrebbe funzionare...

per curiosità, nel backup, se guardi nelle INSERT le lettere accentate sono corrette vero?
Imagination is more important than knowledge (A.Einstein)

tito_livio

Citazione di: nomorelogic il Novembre 12, 2024, 06:34:47 PM
se usi windows è quindi certo che il charset usato dal DB sia CP1250
quindi dovresti assicurarti che quando ti connetti come client, lo fai con lo stesso charset
quando dici che già usi
MySQL50Connection1.CharSet := 'CP1250';
dovrebbe funzionare...

per curiosità, nel backup, se guardi nelle INSERT le lettere accentate sono corrette vero?
Ho provato a mettere quella istruzione, impostando il charset cp1250, ma non funziona, lettere illegibili. Anche nel Backup le lettere appaiono illeggibili.

Da notare che se eseguo nel lazarus nuovo:
showmessage(inttostr(sqlquery1descriz.CodePage))
ottengo 1252.
Nel lazarus vecchio (2.0.6) questa proprietà non esiste.
Poi se imposto, sempre nel nuovo:
MySQL50Connection1.CharSet := 'CP1252';
mi da errore:
Failed to set connection character set: Can't initialize character set cp1252 in c:\program Files\MySql\MySql server 5.0\share\charsets\
E in effetti in quella cartella CP1252.xml non c'è mentre ci sono altri codepage come cp1250,cp1252 ecc.

DragoRosso

Citazione di: tito_livio il Novembre 12, 2024, 06:15:45 PM
Mi potresti spiegare come si fa a far apparire il debbugger con i valori esadecimali della stringa?
Scusami ma io i valori in esadecimali non li guardo ed adesso non mi appaiono.

Metti un breakpoint dopo l'assegnazione, quando il programma si ferma selezioni la variabile e con il tasto destro del mouse vai a DEBUG / AGGIUNGI A WATCH.

Vai nella finestra di WATCH e seleziona l'espressione, poi premi il tasto in alto "chiave inglese-cacciavite" e imposta la finestra di set come nell'allegato.

"RIPETI CONTEGGIO" DEVI VALORIZZARLO CON LA LUNGHEZZA DELLA STRINGA (ANCHE SE IL VALORE ECCEDE NON IMPORTA).
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.