* * * *

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

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

Inserisci il nome utente, la password e la durata della sessione.

107 Visitatori, 0 Utenti

Autore Topic: TrueName  (Letto 2606 volte)

Riccardo Ferrari

  • Newbie
  • *
  • Post: 34
  • Karma: +0/-0
TrueName
« il: Febbraio 07, 2024, 10:01:25 pm »
Ho la seguente esigenza, che temo non sia molto comune perché ho cercato in rete una soluzione ma non ho trovato nulla, non solo la soluzione (succede di non trovarla) ma nemmeno qualcun altro che abbia posto la solita questione.
Dunque: Windows non è case-sensitive. Per fortuna, quando uso linux impazzisco dietro alle maiuscole, però ciò ha un portato estetico che mi disturba (lo so non è un gran problema).
Se un file si chiama Abcdefhi.Jkl e invece digito abcDEFHI.jkL al programma va bene comunque, lo riconosce e va avanti con la elaborazione.
L’estetica risiede nel fatto che rimane scritto "male" per tutto il programma. Quando il programma deve restituire il nome del file lo fa come è stato impostato non come realmente è.
Per cui ho scritto una funzione, che ho chiamato TrueName, che converte il nome impostato nel nome reale, mantenendo la sequenza di maiuscole/minuscole. Purtroppo ExpandFileName non lo fa, come avevo sperato, se hai scritto "male", non raddrizza la cosa.
TrueName funziona così: invece di verificare l’esistenza del file con FileExists, come faccio in genere, cerco con FindFirst il nome impostato, poi leggo la variabile <punto>Name del record TSearchRec che corrisponde al nome reale con le maiuscole/minuscole giuste, ovviamente FindFirst<>0 corrisponde a False di FileExists.
Tutto risolto? Manco per niente.
In primo luogo magari esiste un algoritmo più efficiente del mio, se ci fosse ne sarei felice. In secondo luogo il trucchetto del FindFirst vale solo per il nome, tutto il resto del percorso, cioè i nomi delle varie directory sovraordinate continuano a mantenere il case impostato da tastiera, anche se diverso dall’originale per quanto al case.
Dovrei quindi applicare il trucchetto del FindFirst ad ogni directory contenuta nel path. Una alla volta. Quindi se il mio algoritmo non fosse efficiente, l’inefficienza verrebbe moltiplicata per la profondità del path.
Magari, mi sono chiesto, esiste una funzione già fatta che restituisce il vero nome completo di path.
Ne sapete qualcosa? Grazie per l’attenzione.
Scusate la lunghezza ma non mi pare un problema molto sentito, quindi ho dovuto spiegarlo bene per evitate fraintendimenti.





« Ultima modifica: Febbraio 07, 2024, 10:03:49 pm da Riccardo Ferrari »

quack

  • Jr. Member
  • **
  • Post: 84
  • Karma: +7/-0
Re:TrueName
« Risposta #1 il: Febbraio 07, 2024, 10:33:53 pm »
Mai provata ma sembra essere quello che cerchi:

https://www.freepascal.org/docs-html/rtl/sysutils/expandfilenamecase.html

Per gestire le collisioni la funzione assegna un valore a MatchFound da cui puoi capire se non ha trovato nessun file, uno o più.

PS: sarà anche scomodo digitare in maniera corretta il nome, ma così rischi di processare il file sbagliato  ;D .

Ciao
qk
« Ultima modifica: Febbraio 07, 2024, 10:40:02 pm da quack »
SO: Fedora\W10
Lazarus: Trunk
FPC: Trunk\3.2.2

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1395
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:TrueName
« Risposta #2 il: Febbraio 07, 2024, 10:47:43 pm »
La problematica generale, che è praticamente irrisolvibile, è che nomi di file e path dissimili per il case sono differenti. Quindi non esiste soluzione a:

Citazione
/FPS/Pollo/Pluto.txt
/fps/Pollo/Pluto.txt
/Fps/pollo/Pluto.txt

Su Windows sono identiche e identificano le stesso file, mentre su Linux (ad esempio) sono diverse (anche il file "Pluto.txt" ovviamente) e non c'è modo di distinguerle a partire da un "nome" case insensitive.

Infatti le funzioni che "sbrogliano" tale situazione riportano che viene prospettato il primo matching trovato, matching che non è possibile prevedere.

E' per quello che nessuno si è mai posto "il problema" più di tanto.

Diciamo che una soluzione più o meno "scritta" è quella di usare nomi di file minuscoli nei SO case sensitive.

Ciao

EDIT: ... e ovviamente anche le path minuscole
« Ultima modifica: Febbraio 07, 2024, 10:59:54 pm da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2921
  • Karma: +20/-4
Re:TrueName
« Risposta #3 il: Febbraio 08, 2024, 10:44:08 am »
ciao Riccardo

ti direi di abbandonare FindFirst/FindNext per la funzione/procedura FindAllFiles che trovi nella unit FileUtil.

La trovi documentata in: https://wiki.freepascal.org/FindAllFiles

La differenza sta nel fatto che hai a disposizione una TStringList con tutti i file trovati che corrispondono alla ricerca effettuata.

Non ho fatto la prova che hai descritto nel post iniziale ma credo che potrebbe funzionare in quanto, a prescindere dal "case" di ricerca, nella lista di stringhe dovresti già avere i nomi corretti (percorso cartelle incluso).

Credo che con un po' di fortuna potrebbe risolvere il tuo problema.
Facci sapere.

nomorelogic
Imagination is more important than knowledge (A.Einstein)

Riccardo Ferrari

  • Newbie
  • *
  • Post: 34
  • Karma: +0/-0
Re:TrueName
« Risposta #4 il: Febbraio 08, 2024, 06:24:03 pm »
Mai provata ma sembra essere quello che cerchi:
https://www.freepascal.org/docs-html/rtl/sysutils/expandfilenamecase.html
Grazie.
Funziona, ma solo per il nome del file, non per l’intero path.
Per l’intero Path occorre andare all’indietro e cercare tutti i nomi.
Ho scritto una funzione che lo fa, più semplice di così non mi è venuta.
Codice: [Seleziona]
{--------------------------------------------------------------------------}
Uses sysutils;
{--------------------------------------------------------------------------}
Const
  PATH_SEP=#92;
{--------------------------------------------------------------------------}
Var
  FName,TName:String;
{--------------------------------------------------------------------------}
Function TrueName(F:AnsiString):AnsiString;
  var
    u,v:Unicodestring;
    a,z:AnsiString;
    m:TFilenameCaseMatch;
  {----------------------------------------}
  Function DueSlash(Sh:AnsiString):Boolean;
      begin
      // delete(Sh,1,pos(PATH_SEP,Sh)); e' sempre 3
      delete(Sh,1,3);
      if pos(PATH_SEP,Sh)>0 then DueSlash:=True else DueSlash:=False;
      end; // Function DueSlash
  {----------------------------------------}
  Function  StripEnd(Se:AnsiString):AnsiString;
      begin
      if AnsiLastChar(Se)=PATH_SEP then delete(Se,length(Se),1);
      StripEnd:=Se;
      end; // Function StripEnd
  {----------------------------------------}
  begin
      z:='';
      u:=f;
      v:=ExpandFileNameCase(u,m);
      a:=v;
      while DueSlash(a) do
        begin
          if z='' then z:=ExtractFileName(a) else z:=ExtractFileName(a)+PATH_SEP+z;
          a:=StripEnd(ExtractFilePath(a));
          u:=a;
          v:=ExpandFileNameCase(u,m);
          a:=v;
        end;
        z:=copy(a,1,3)+ExtractFileName(a)+PATH_SEP+z;
        TrueName:=z;
  end;
{--------------------------------------------------------------------------}
Begin
  FName:=paramstr(1);
  TName:=TrueName(FName);
  WriteLn;
  WriteLn('Input   : ',FName);
  WriteLn('Truename: ',TName);
End.
{--------------------------------------------------------------------------}
Inoltre la compilazione mi dà 4 warning:

(31,10) Warning: Implicit string type conversion from "AnsiString" to "UnicodeString"
(33,10) Warning: Implicit string type conversion with potential data loss from "UnicodeString" to "AnsiString"
(38,14) Warning: Implicit string type conversion from "AnsiString" to "UnicodeString"
(40,14) Warning: Implicit string type conversion with potential data loss from "UnicodeString" to "AnsiString"

Lavoro sempre con le AnsiString, e prima con le String. Mai usate le UnicodeString.
Mi sono documentato (un po’) e per ora non voglio complicare ulteriormente il codice inserendo delle conversioni corrette, dovrei studiare a fondo come si facciano queste conversioni, e dovrei anche implementarle, ammesso che ci riesca.
Comunque credo di aver capito che da Ansi a Unicode non ci dovrebbero essere problemi (allora perché esce il warning?) mentre da Unicode ad Ansi si potrebbero perdere i caratteri "strani". Trattandosi di nomi di file i caratteri strani non ci dovrebbero essere, a meno di non lavorare con nomi di file Russi, o peggio, Cinesi. Non credo che mi succederà mai. Hint: vengo dall’ 8+3.

Riccardo Ferrari

  • Newbie
  • *
  • Post: 34
  • Karma: +0/-0
Re:TrueName
« Risposta #5 il: Febbraio 08, 2024, 06:37:25 pm »
ti direi di abbandonare FindFirst/FindNext per la funzione/procedura FindAllFiles che trovi nella unit FileUtil.

La trovi documentata in: https://wiki.freepascal.org/FindAllFiles
Grazie del suggerimento, studierò.

Credo che con un po' di fortuna potrebbe risolvere il tuo problema.
Facci sapere.
Ho postato il codice della funzione TrueName() che ho scritto utilzzando la funzione ExpandFileNameCase dell'unit sysutils, suggerita da quack.
Se hai tempo fammi sapere cosa ne pensi, grazie.

quack

  • Jr. Member
  • **
  • Post: 84
  • Karma: +7/-0
Re:TrueName
« Risposta #6 il: Febbraio 08, 2024, 09:10:44 pm »
La funzione ExpandFileName non cerca il file ma si occupa solamente di trasfomare il percorso da relativo in assoluto.
Se nel nome del file non è incluso il percorso completo aggiunge quello della directory corrente.

Infine se il nome restituito esiste assegna a FileMatch il valore mkExactMatch, mkSingleMatch o mkAmbiguous, in base alla situazione, se non esiste assegna il valore mkNone. 

Per esempio:

la directory corrente è "/pippo" e contiene solo il file "pluto.pas"

ExpandFileNameCase('PLUTO.pas', match) restituirà "/pippo/pluto.pas" e mkSingleMatch
ExpandFileNameCase('pluto.pas', match) restituirà "/pippo/pluto.pas" e mkExactMatch
ExpandFileNameCase('Mucca.pas', match) restituirà "/pippo/Mucca.pas" e mkNone.

In definitiva con ExpandFileName risali a quello che dovrebbe essere il percorso assoluto ipotetico del nome file in input, indipendentemente che il file esista o meno nel sistema.

Spero che questo ti aiuti a capire quale è la strada migliore da seguire nel tuo caso.
PS: prova ad usare il tipo string invece di ansistring.

Ciao
« Ultima modifica: Febbraio 08, 2024, 10:26:26 pm da quack »
SO: Fedora\W10
Lazarus: Trunk
FPC: Trunk\3.2.2

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1395
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:TrueName
« Risposta #7 il: Febbraio 08, 2024, 10:37:04 pm »
Comunque credo di aver capito che da Ansi a Unicode non ci dovrebbero essere problemi (allora perché esce il warning?) mentre da Unicode ad Ansi si potrebbero perdere i caratteri "strani". Trattandosi di nomi di file i caratteri strani non ci dovrebbero essere, a meno di non lavorare con nomi di file Russi, o peggio, Cinesi. Non credo che mi succederà mai. Hint: vengo dall’ 8+3.

Unicode (ce ne sono vari) e AnsiString non hanno nulla a che fare l'uno con l'altro. In comune hanno solo che entrambi sono "contenitori", la codifica dei caratteri è totalmente differente.
AnsiString si basa su un elenco di codepage di 256 caratteri, ogni codepage rappresenta un set a se stante: la "a" di un codepage potrebbe essere differente dalla "a" di un altro codepage.

AnsiString è costruita su un array di caratteri in cui ogni carattere occupa un byte. Ogni carattere Unicode invece occupa una lunghezza variabile da 1 a 5 byte a seconda degli standard (UTF-8, UTF-16LE, UTF-16BE, UTF-32, etc ...)
 
Unicode, in particolare UTF-8 che è una codifica a lunghezza variabile ha i primi 128 caratteri uguali alla codifica ANSI (conosciuta anche come "ASCII Base" + "ASCII Esteso" o informalmente "Windows 1252"). C'è una forte contrapposizione con la norma ISO-8859-1 che anch'essa rivendica la paternità di ANSI in cui alcuni caratteri "ASCII Esteso" cioè i caratteri dal 128 al 255 sono però diversi dal "Windows 1252".

UTF-8 come si diceva ha i primi 128 caratteri uguali all' "ASCII base" chiamato nei tempi moderni universalmente "Basic Latin", e i successivi 128 caratteri uguali all' "ASCII esteso" (aka "Latin-1 Supplement").

ATTENZIONE che i nomi "Basic Latin" e "Latin-1 Supplement" sono normati e li troverete spesso tra le definizioni delle codifiche nei DATABASE.

La ISO/IEC 10646:2020 è la normativa (ultima edizione del 2020) che definisce a livello universale la codifica dei caratteri (UCS) e in particolare le sette possibili codifiche dei caratteri: UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE e UTF-32LE.

Con AnsiString, inteso come contenitore dei caratteri ANSI, è impossibile definire tutti i caratteri usati in una qualsiasi lingua e ciò complica la programmazione: si utilizza il CODEPAGE per definire quali caratteri il set ANSI rappresenta. Un elenco aggiornato di codepage è presente qui: https://learn.microsoft.com/it-it/windows/win32/intl/code-page-identifiers?redirectedfrom=MSDN

Ovviamente in una stringa AnsiString non possono essere rappresentate più "lingue" contemporaneamente ... a meno di non ricorrere a trucchi assolutamente da NON METTERE IN ATTO.

Per risolvere questo problema (pensate un doc scritto in Italia e letto in Olanda o Germania ... a parte la traduzione  ;) ) è stato inventato l'UNICODE.

Diciamo che essenzialmente vengono usati due tipi di UNICODE: UTF-8 e UTF-16LE.

UTF-8 ha caratteri che sono lunghi fino a 5 byte e può rappresentare un qualsiasi carattere in maniera universale. Posso quindi "misciare" caratteri arabi, cinesi, latini, etc. senza creare alcuna confusione. Per tale motivo tale codifica è usata praticamente universalmente nel WEB: tutte le pagine WEB e quasi tutti i formati dati (JSON, XML, etc ..) usano la codifica UTF-8.

Unicode codifica 16 "piani" ognuno dei quali contiene 65536 caratteri. Il primo "piano" chiamato BMP contiene la stragrande maggioranza di tutti i caratteri oggi noti (tra cui i cinesi, giapponesi e coreani). UTF-16 può codificare un piano completo, e normalmente viene usato con il il primo (BMP).

Per chi volesse dare una occhiata in maniera testuale descrittiva all'elenco dei caratteri oggi definiti (ultimo aggiornamento 2022) può vederlo qui: https://www.unicode.org/Public/15.0.0/ucd/UnicodeData.txt

Perchè la conversione AnsiString genera quell'avviso ? Perchè essendo il carattere legato ad un codepage non definito (qualunque sia non è "scritto" nella stringa) la conversione in Unicode potrebbe non avere senso.

Per convertire le AnsiString in Unicode occorrerebbe usare le funzioni specifiche che consentono di eseguire correttamente l'operazione. Ovviamente è peggio l'incontrario (UNICODE string -> AnsiString).

Dal 2001 in poi Windows ha introdotto l'uso di unicode (o meglio un subset simile al BMP di UTF-16LE) a livello di kernel e API. Dal 2005 anche Linux ha implementato nel kernel l'uso di unicode preferendo però UTF-8.

Gli ambienti di programmazione ci hanno messo un pò e con il tempo sono diventati UNICODE compatibili, anzi essenzialmente UNICODE: Delphi dal 2009, mentre FPC non è pienamente compatibile (FPC non ha il core compatibile con unicode).

Ma di fatto per il programmatore che cosa cambia (a parte non scrivere più "è" in Italiano e magari leggere "§" in tedesco ... è un esempio non sò se fosse così): cambia che l'uso di UNICODE ha portato inevitabilmente il fatto che un carattere non è più lungo 1 byte ma bensì diventa di 2 byte. Uno stravolgimento per il programmatore, molto spesso abituato a lavorare senza considerare la lunghezza effettiva dei dati (il famigerato sizeof() ).

Qui mi fermo perchè già sono state scritte pagine e pagine anche in questo forum sull'argomento ...

Ciao

P.S.: dimenticavo la cosa più importante, anche se si legge tra le righe sopra, ossia che in Lazarus / FPC la definizione di "String" equivale alla "AnsiString" come definizione di lunghezza del carattere ed è di 1 byte, a differenza dei linguaggi di programmazione "unicode" come Delphi in cui la "String" definisce un carattere di due byte e la "AnsiString" invece è di 1 byte.
« Ultima modifica: Febbraio 09, 2024, 12:29:06 am da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

bonmario

  • Hero Member
  • *****
  • Post: 1358
  • Karma: +11/-1
Re:TrueName
« Risposta #8 il: Febbraio 09, 2024, 10:00:06 am »
Scusa, ma ho letto solo oggi ...
Avevo avuto lo stesso problema su Windows, e ne avevamo discusso qui:
https://www.lazaruspascal.it/index.php?topic=2534.msg16335#msg16335

Alla fine avevo usato "expandfilenamecase", partendo dal nome del file, ed andando a ritroso per i domi delle varie cartelle del percorso.

Ciao, Mario

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2921
  • Karma: +20/-4
Re:TrueName
« Risposta #9 il: Febbraio 09, 2024, 10:13:41 am »
[...]
Ho postato il codice della funzione TrueName() che ho scritto utilzzando la funzione ExpandFileNameCase dell'unit sysutils, suggerita da quack.
Se hai tempo fammi sapere cosa ne pensi, grazie.

ok, appena ho modo gli do un'occhiata

riporto anche il link sul forum internazionale con lo stesso argomento
https://forum.lazarus.freepascal.org/index.php/topic,66144.0.html


@Riccardo Ferrari
chiedere aiuto anche nel forum internazionale è un'ottima idea  :)
quando capita sarebbe bene mettere il link così si possono sfruttare anche le altre  risposte ;)

Imagination is more important than knowledge (A.Einstein)

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2921
  • Karma: +20/-4
Re:TrueName
« Risposta #10 il: Febbraio 09, 2024, 06:00:17 pm »
[...]
Ho postato il codice della funzione TrueName() che ho scritto utilzzando la funzione ExpandFileNameCase dell'unit sysutils, suggerita da quack.
Se hai tempo fammi sapere cosa ne pensi, grazie.

ok, appena ho modo gli do un'occhiata

ho provato il tuo codice e devo dire che sembra una buona soluzione

un paio di appunti:
  • invece di dichiarare la tua costante PATH_SEP, puoi usare la costante predefinita PathDelim
  • credo sia scritto con windows in mente (mi riferisco a copy(a,1,3) ), forse dovresti mettere qualche direttiva per fare in modo che negli OS *nix non ci siano risultati anomali
Imagination is more important than knowledge (A.Einstein)

Riccardo Ferrari

  • Newbie
  • *
  • Post: 34
  • Karma: +0/-0
Re:TrueName
« Risposta #11 il: Febbraio 10, 2024, 02:30:07 pm »
Per esempio:

la directory corrente è "/pippo" e contiene solo il file "pluto.pas"

ExpandFileNameCase('PLUTO.pas', match) restituirà "/pippo/pluto.pas" e mkSingleMatch
ExpandFileNameCase('pluto.pas', match) restituirà "/pippo/pluto.pas" e mkExactMatch
ExpandFileNameCase('Mucca.pas', match) restituirà "/pippo/Mucca.pas" e mkNone.
Così dice la documentazione, ma non è questo ciò che accade, almeno nel mio sistema (Win 10 e Fpc 3.2.2, ho provato sia compilato a 32 bit che a 64).
Anche se il case è diverso, TFilenameCaseMatch restituisce sempre mkExactMatch oppure mkNone se il file non c’è; mkSingleMatch e mkAmbiguous non escono mai.
mkExactMatch esce anche se metti una wildcard, e viene restituito anche il nome esatto (il primo che trova con quella wildcard).

PS: prova ad usare il tipo string invece di ansistring.
Avevo già provato, con poca convinzione, ed infatti non cambia nulla.
Per quel poco che ho capito la String e l’AnsiString differiscono solo per la lunghezza massima, per il resto si comportano allo stesso modo.


quack

  • Jr. Member
  • **
  • Post: 84
  • Karma: +7/-0
Re:TrueName
« Risposta #12 il: Febbraio 10, 2024, 02:54:39 pm »
[
Così dice la documentazione, ma non è questo ciò che accade, almeno nel mio sistema (Win 10 e Fpc 3.2.2, ho provato sia compilato a 32 bit che a 64).
Anche se il case è diverso, TFilenameCaseMatch restituisce sempre mkExactMatch oppure mkNone se il file non c’è; mkSingleMatch e mkAmbiguous non escono mai.

I risultato che hai riscontrato è corretto. Su window non ci possono essere due file i cui nomi differiscono solo per qualche lettere in maiuscolo o minuscolo.
Appena ho un attimo faccio quanche prova e ti risondo anche sul resto.
Ciao
SO: Fedora\W10
Lazarus: Trunk
FPC: Trunk\3.2.2

Riccardo Ferrari

  • Newbie
  • *
  • Post: 34
  • Karma: +0/-0
Re:TrueName
« Risposta #13 il: Febbraio 10, 2024, 03:09:49 pm »
Perchè la conversione AnsiString genera quell'avviso ? Perchè essendo il carattere legato ad un codepage non definito (qualunque sia non è "scritto" nella stringa) la conversione in Unicode potrebbe non avere senso.

Per convertire le AnsiString in Unicode occorrerebbe usare le funzioni specifiche che consentono di eseguire correttamente l'operazione. Ovviamente è peggio l'incontrario (UNICODE string -> AnsiString).
Ti ringrazio per la lunga spiegazione. Ho capito qualcosa in più, anche se non posso dire di padroneggiare l’argomento, tutt’altro.
Se ho capito bene, Ansistring e Unicodestring sono uguali solo per ASCII < 127
Infatti il warning che ho ricevuto funziona, nel senso che era un effettivo invito all’attenzione.
Ho nominato un file con una lettera accentata e la funzione TrueName che ho scritto l’ha sbagliata, solo un carattere sbagliato. Tutto il resto giusto.
Sbagliano anche i professionisti, se passo un testo (copia/incolla) da Notepad a Scite, alcune volte mi sbaglia gli accenti, non ho capito ancora bene come e perché. Se ho entrambi i programmi aperti il copia incolla viene bene. Se passo dal disco, cioè se salvo il file di Notepad e lo apro in Scite i caratteri non a 7 bit sono mal interpretati. Magari ho sbagliato qualche settaggio iniziale.
Studierò anche come fare una conversione seria tra Ansistring e Unicodestring. Anche il contrario, ma, se ho ben capito, non è detto che si possa fare: Da Ansi ad Uni si aggiunge, quindi si fa sapendo cosa si deve aggiungere. Da Uni ad Ansi si toglie e non credo che sia sempre possibile.
Detto questo devo ricordare che sono partito dai nomi dei file ed i loro percorsi. Che necessità c’è di superare l’ASCII 127? Basterebbe scrivere i nomi di file a 7-bit, così vanno bene in tutto mondo.
Ultimamente mi hanno inviato via email il file Carta_identità.Pdf Ma che bisogno c’è??? Se scrivessi Carta_Identita.Pdf non si capisce? Forse 8.3 era troppo limitante ma qui si esagera. Che poi era 8 e basta visto che il 3 spesso era  "prenotato"


DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1395
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:TrueName
« Risposta #14 il: Febbraio 10, 2024, 03:18:38 pm »
@Riccardo Ferrari

Ho provato sotto Linux e la funzione "ExpandFileNameCase" funziona correttamente, fatto salvo che bisogna vedere come ho detto quali sono i tuoi scopi ...

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

 

Recenti

How To

Utenti
  • Utenti in totale: 803
  • Latest: maXim.FI
Stats
  • Post in totale: 19169
  • Topic in totale: 2286
  • Online Today: 94
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 107
Total: 107

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.