none
file .txt con caratteri UTF - 8 RRS feed

  • Domanda

  • Buongiorno a tutti ,

    ho necessità di salvare su disco dati alfabetici con caratteri accentati .

    ho provato con la specifica  UTF - 8  ma vengono poi letti ed evidenziati in forma non corretta : con simboli strani

    premesso che vorrei utilizzare caratteri  SOLO  unicode  quindi ( se non sbaglio ) di 2 bytes ognuno

    dove sbaglio  ??

    Grazie per l'attenzione

    sabato 28 maggio 2022 09:51

Risposte

  • Ciao Vittorio,

    non puoi utilizzare il codice che hai scritto, perchè la codifica Unicode non prevede un numero fisso di bit (cioè 16), quindi non sai a priori di quanti bytes è composto il tuo vettore di char (char[] vet). Se cerchi su Wikipedia vedi che possono essere utilizzati fino a 21 bit. E anche le altre codifiche, utilizzano sistemi con un numero variabile di bit.

    Pertanto, quando leggi il file con BinaryReader, non puoi sapere, con una divisione, di quante righe è composto. Quindi, anche il cast (byte)vet[i] perde significato, perchè potresti trovare un byte a zero, senza essere arrivato alla fine della riga.

    • Contrassegnato come risposta vittorio 50 martedì 14 giugno 2022 09:04
    domenica 12 giugno 2022 17:17

Tutte le risposte

  • Buongiorno, Vittorio,

    senza un codice o i step presi fin ora, non potrei dare un'idea precisa, comunque proverò.

    Il problema potrebbe essere nel comando di codifica, ad esempio il VARCHAR e per questo motivo i caratteri non ASCII potrebbero non essere convertiti correttamente.
    Potresti provare con NVARCHAR.
    Se non è possibile utilizzare il tipo NVARCHAR, una soluzione potrebbe essere quella di eseguire il cast della stringa in esadecimale, quindi passarla al database come Types.VARBINARY (o qualcosa di simile): il database dovrebbe gestire correttamente la conversione del tipo.


    • Microsoft offre questo servizio gratuitamente, per aiutare gli utenti e aumentare il database dei prodotti e delle tecnologie. Il contenuto fornito “as is“ non comporta alcuna responsabilità da parte dell’azienda.

    lunedì 30 maggio 2022 07:18
    Moderatore
  • Ciao Vittorio,

    se tu salvi su disco un file .txt, con qualunque codifica (UTF8, UTF16, Unicode, ...), poi viene letto automaticamente correttamente:

    File.WriteAllText(@"d:\prova.txt", "àèìòù",System.Text.Encoding.UTF8);
    string lettere = File.ReadAllText(@"d:\prova.txt");
    Console.WriteLine(lettere);

    lunedì 30 maggio 2022 13:46
  • Grazie Yordan  gazie  fabiocaruso ,

    ci riprovo ma c'è qualcosa che mi sfugge

    già creando un file  .txt  con caratteri accentati  usando  Blocco note  comunque lo salvo in rilettura i caratteri non coincidono

    quindi quando questo file  .txt  lo leggo nell'applicazione comunque i dati sono in partenza inquinati

    Ora mi assento una settimana , quando torno ci riprovo.

    Grazie ancora

    martedì 31 maggio 2022 06:24
  • Grazie dell aviso, Vittorio,

    appena hai informazione, farci sapere. 

    • Microsoft offre questo servizio gratuitamente, per aiutare gli utenti e aumentare il database dei prodotti e delle tecnologie. Il contenuto fornito “as is“ non comporta alcuna responsabilità da parte dell’azienda.

    martedì 31 maggio 2022 08:46
    Moderatore
  • Ok, ho capito: quando tu salvi con il Blocco Note di Windows, se tu selezioni "Salva con nome", in basso sotto il nome del file troverai la "Codifica". Da te ci sarà selezionata sicuramente ANSI. Quindi è ovvio che il salvataggio del blocco note avviene in modo non conforme alle specifiche UTF-8.

    Prova a cambiare tale codifica con UTF-8 e vedrai che il problema sarà risolto.

    martedì 31 maggio 2022 17:37
  • Grazie  Yordan , grazie  fabiocaruso

    sono tornato operativo . Ho salvato in formato  UTF - 8  ed  anche  UTF - 16 LE / BE             FileName.txt

    va tutto bene fin quando rileggo con Blocco note . Posso anche  leggere e salvare in formato binario           FileName.000


                List<string> tab = new List<string>();
                tab = File.ReadAllLines(FileName.txt).ToList();   

    int lenStringa = 64;     

                int quantiRec = tab.Count();
                BinaryWriter bw = new BinaryWriter(new FileStream(FileName.000, Create, FileAccess.Write));
                for (int r = 0; r < nRg; r++) {

    stringa = tab[r];     

     StrTOvet(tp, stringa);          // la stringa in un vettore di char
                    bw.Seek(r * lme[tp], SeekOrigin.Begin);    bw.Write(vet);  }        bw.Close();

    mercoledì 8 giugno 2022 12:15
  • Scusate ho fatto qualcosa di sbagliato con le dita

    mi preparo meglio la risposta perchè è un pò complessa

    mercoledì 8 giugno 2022 12:26
  • Bene riprendo :

    recupero un FileName.txt con stringhe di lunghezza variabile e lo trasformo in  FileName.000 contenente stringhe a lunghezza fissa

    int LunghezzaFissa = 64;                                           // lunghezza fissa della stringa

    char[] vet;                                                  

    string[] mg = new string[LunghezzaFissa];              // vettore dei messaggi (stringhe a lunghezza fissa)

                                                                   // converte una stringa a lunghezza variabile in un vet[] a lunghezza fissa

    void StrTOvet(int LunghezzaFissa, string stringa)

    {

               vet = new char[LunghezzaFissa];                   // un vettore pieno di zeri

                              // nel vettore i caratteri della stringa, troncata se eccede bytes

               for (int i = 0; i < stringa.Length && i < LunghezzaFissa; i++)

                     vet[i] = Convert.ToChar(stringa.Substring(i, 1));

    }

                             // vet = stringa.ToCharArray(0, stringa.Length); NON MANTIENE LA LUNGHEZZA FISSA DEL VETTORE

    List<string> tab = new List<string>();

                                                                                           // leggo le stringhe variabili in FileName.txt

    tab = File.ReadAllLines(FileName.txt).ToList();

    int quantiRec = tab.Count();

    string stringa;

                                                                                          // riscrivo le stringhe in lunghezza fissa in FileName.000

    BinaryWriter bw = new BinaryWriter(new FileStream(FileName.000, Create, FileAccess.Write));

    for (int r = 0; r < quantiRec; r++)

    {

           stringa = tab[r];

                                                                                   // converto la stringa variabile in un vettore di LunghezzaFissa di char

           StrTOvet(LunghezzaFissa, stringa);

           bw.Seek(r * LunghezzaFissa, SeekOrigin.Begin);

           bw.Write(vet);

    }

    bw.Close();

    Fino ad ora tutto bene : se leggo con Blocco note il FileName.000 gli accenti sono corretti

    Il problema sorge quando li riprendo :

    FileStream fs = new FileStream(FileName.000, FileMode.Open, FileAccess.Read);

    BinaryReader br = new BinaryReader(fs, Encoding.Default);

    int quantiRec = (int)fs.Length / (LunghezzaFissa * 2);

    mg = new string[quantiRec];

    string g;

    for (int r = 0; r < quantiRec; r++)

    {

              fs.Seek(r * (LunghezzaFissa * 2),SeekOrigin.Begin);

              vet = br.ReadChars(LunghezzaFissa);

                                                                                 //  riconverto  il  vet[]  in stringa

              g = "";

              for (int i = 0; i < LunghezzaFissa; i++)

             {

                      if ((byte)vet[i] == 0) break;             // se c’è carattere \0 termina else accoda

                      g += vet[i];

             }

             mg[r] = g; // salva la stringa nel vettore dei messaggi

    }

    br.Close();

    fs.Close();

    In lettura : vet = br.ReadChars(LunghezzaFissa); c’è già errore :  presumo che ReadChars non tenga conto di UTF …

    Può essere che sbaglio nel calcolare i caratteri a due bytes MA non credo : l’ errore è solo negli accenti .

    Può anche essere che ci sia un modo più furbo per fare tutto questo : ma non lo conosco .

    Grazie per l'eventuale attenzione

    mercoledì 8 giugno 2022 13:53
  • Ciao Vittorio,

    se vuoi riversare tutte le righe di un file, in un altro file con le righe di lunghezza predefinita di 64 caratteri, potresti fare così:

    //riempie con gli spazi i caratteri che mancano per raggiungere la lunghezza 64. int lunghezzaFissa = 64; string[] elenco = File.ReadAllLines(@"d:\prova1.txt");

    for (int i = 0; i < elenco.Length; i++) elenco[i] = (elenco[i] + new string(' ', lunghezzaFissa)).Substring(0,lunghezzaFissa); File.WriteAllLines(@"d:\prova2.txt", elenco);




    giovedì 9 giugno 2022 20:20
  • Ciao  fabiocaruso ,

    grazie per l'attenzione . Prendo nota del tuo suggerimento .

    Il problema che ho però , non è quello di convertire stringhe variabili in fisse ( viene fatto una tantum )

    Quello che non funziona è che dato un file di stringhe ( correttamente scritto  a lunghezza  fissa )

    l' istruzione         vet = br.ReadChars(LunghezzaFissa);

    non rende i caratteri con l'accento anche se nel file sono correttamente scritti

    o almeno così mi sembra . Sbaglio  ??

    domenica 12 giugno 2022 13:12
  • Ciao Vittorio,

    non puoi utilizzare il codice che hai scritto, perchè la codifica Unicode non prevede un numero fisso di bit (cioè 16), quindi non sai a priori di quanti bytes è composto il tuo vettore di char (char[] vet). Se cerchi su Wikipedia vedi che possono essere utilizzati fino a 21 bit. E anche le altre codifiche, utilizzano sistemi con un numero variabile di bit.

    Pertanto, quando leggi il file con BinaryReader, non puoi sapere, con una divisione, di quante righe è composto. Quindi, anche il cast (byte)vet[i] perde significato, perchè potresti trovare un byte a zero, senza essere arrivato alla fine della riga.

    • Contrassegnato come risposta vittorio 50 martedì 14 giugno 2022 09:04
    domenica 12 giugno 2022 17:17
  • Grazie  fabiocaruso ,

    è una gran brutta notizia , tutta l'applicazione è basata sui record a dimensione fissa.

    Comunque , per quanto ho capito l'errore succede SOLO con i caratteri accentati

    è possibile testare una stringa e sostituire i caratteri accentati con i simili NON accentati ??

    In tal caso potrei FORSE risolvere  ??

    martedì 14 giugno 2022 09:11
  • Se il problema riguarda soltanto i caratteri accentati, una soluzione più precisa potrebbe essere quella di usare la codifica ASCII, che utilizza sempre solo 8 bit.

    mercoledì 15 giugno 2022 10:58
  • Ciao  fabiocaruso , 

    come sempre grazie per l'attenzione .

    Non vorrei creare diversità nella gestione dei dati . 

    Ho creato una funzione che sostituisce le vocali accentate con le stesse senza accento ma seguire da   "  '  "

    Sembra funzionare . Se non ci sono altre  "trappole "   !!!

    Comunque ancora grazie a tutti ed a te in particolare .

    mercoledì 15 giugno 2022 13:28