Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C++] Lettura File e confronto stringhe UNICODE

    Buongiorno a tutti,
    sono nuova del linguaggio C++ , ho sempre programmato in altri linguaggi ad oggetti.
    Problemino
    devo leggere un file e quando trovo una determinata stringa deve settarmi delle altre variabili

    dunque
    ho dichiarato scritto quanto segue
    codice:
    #include <Windows.h> 
    #include <string.h> 
    #include <stdio.h> 
    #include <wchar.h>
    
    
    
    #define  OGGETTO_RECT L"ObjectID=2"
    
    
    /* dichiara lo stream e il prototipo della funzione fopen */
    FILE *stream, *fopen();
    
    void main()
    {
        WCHAR riga[255];
            
      
        //apro file  e leggo i dati
        
       /* apre lo stream del file */
      // stream = _wfopen(L"stampa.lst", L"r");
     
       /* controlla se il file viene aperto */
       if ((stream = _wfopen(L"stampa.lst", L"r")) == NULL)
       {
          printf("Non posso aprire il file %sn", "stampa.lst");
          exit(1);
       }
       else
       {
           //cicla nel file leggendo riga per riga
    
           while (!feof(stream))
           { 
              if (fgetws ( (wchar_t*) riga, sizeof(riga), stream) == NULL) break; 
              
              if ( wcsstr ((wchar_t*) riga,OGGETTO_RECT))
             
               {
                   printf("ok trovato");
               }
            
              
           }
           fclose(stream);
    
           //
       }
    
       
    }
    ora non trova mai corrispondenza
    nel mio file con estensione .lst
    ci sono le seguenti righe:
    riga1
    riga2
    riga3
    ObjectID=2
    riga4

    Grazie!!!!
    Ultima modifica di MItaly; 04-05-2016 a 22:31 Motivo: Tag CODE

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    A parte il fatto che dovresti indentare e usare i tag code per mostrare il codice nel forum, comunque il programma funziona.
    Ultima modifica di oregon; 04-05-2016 a 14:44
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Ciao, scusami
    Il mio problema è che non entra mai nell'IF .Quindi non trova corrispondenza e non capisco il perchè

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Ti dicevo che funziona proprio nel senso che trova la stringa.

    Il file di testo è UNICODE ? Puoi farlo scaricare?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Io ho provato ad aprire il file e verificare che sia in UNICODE e lo è.
    Ma quando faccio girare il mio programmino non entra nell'if e non fa il printf("ok trovato");

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Con cosa apri il file di testo?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Come strumento ho usato notepad e ho salvato in unicode.
    Nel codice uso le funzioni per unicode.

  8. #8
    Dire che un file "è Unicode" non vuol dire niente (di Unicode ci sono numerose codifiche, tra cui UTF-8, UTF-16 e UCS-4, le ultime due nelle varianti little endian e big endian e con e senza il BOM iniziale); inoltre, il fatto che _wfopen accetti un nome di file "wide", fgetws riempia un buffer di wchar_t e quello che è effettivamente l'encoding del file sono concetti ortogonali:
    • fopen/_wfopen: l'unica differenza è che _fwopen accetta un nome file in caratteri wide, ovvero puoi aprire anche file con nomi "strani"; questo non impatta in alcuna maniera la modalità di lettura del file;
    • fgets/fgetws: la differenza è che una riempie un buffer di caratteri "normali", una un buffer di caratteri "wide"; come avvenga la conversione dai byte del file a quello che viene messo nel buffer non è direttamente legato all'usare l'una o l'altra:
      • se il file è aperto in modalità testo, la CRT cerca di effettuare una transcodifica del file "dietro le quinte", da "encoding del file" a "encoding del buffer target" ("encoding locale" nel caso di fgets, "UTF-16 LE" nel caso di fgetws); di default, fopen marca il file come in "encoding locale" (su macchine Windows italiane windows-1252), e se fai una fgetws di fatto vengono letti caratteri nell'encoding in questione e convertiti in caratteri wide; purtroppo, nel tuo caso questo comportamento non va bene, dato che il file non è in "encoding locale", ma con ogni probabilità è in UTF-16 LE (quello che notepad chiama "Unicode");
      • se il file è aperto in modalità binaria, la CRT non si impiccia e legge direttamente dal file i codepoint UTF-16 (su Windows i wchar_t sono di 2 byte)

    A questo punto, per risolvere questo problema hai due possibilità:
    • puoi spiegare alla CRT che il tuo file non è in encoding locale, ma bensì in UTF-16; questo si può fare aggiungendo nella stringa di modo di apertura del file il parametro "ccs=UTF-16LE" (_wfopen(L"stampa.lst", L"r,ccs=UTF-16LE")); questo fa sì che quando leggi con la fgetws i byte del file vengano interpretati correttamente; incidentalmente, in questa maniera puoi anche usare la normale fgets se non ti interessano i caratteri non-locali (la CRT fa la transcodifica UTF-16=>encoding locale dietro le quinte);
    • puoi dire alla CRT di farsi i cavoli suoi, e aprire il file in modalità binaria (_wfopen(L"stampa.lst", L"rb")); a questo punto, se il file è effettivamente in UTF-16 LE, puoi leggere senza problemi con la fgetws (ma non con la fgets - otterresti i byte "grezzi"); principale effetto collaterale: non viene rimosso automaticamente dal runtime il doppio terminatore di riga (in coda alle righe ti trovi \r\n invece del solo \n).

    (incidentalmente, per quanto mi riguarda sono della scuola di pensiero che gli stream C sono il posto sbagliato dove "nascondere" conversioni di encoding e similari, sia perché il supporto ai vari encoding è malamente documentato, in una zona grigia tra lo standard e il non standard e molto variabile a seconda della piattaforma e delle configurazioni, sia perché la trasformazione "trasparente" dei dati del file "rompe" concettualmente diverse operazioni di libreria che nascono per lavorare sui byte grezzi - per dire, una fseek su un file aperto in modalità testo è rotta by design; quindi, se chiedi a me i file si aprono sempre in modalità binaria e se c'è da fare conversioni di encoding si usano librerie che danno qualche garanzia in più per quanto riguarda il supporto dei vari encoding - dalle API di Windows a Qt o a ICU)

    Riferimenti:
    https://msdn.microsoft.com/en-us/library/yeby3zcb.aspx
    https://msdn.microsoft.com/en-us/library/c4cy2b8e.aspx
    https://msdn.microsoft.com/en-us/library/c37dh6kf.aspx
    Ultima modifica di MItaly; 04-05-2016 a 23:05
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Ciao!
    ti ringrazio. Ho effettuato la modifica del codice e ho aperto il file in modalità binaria . Così riesco ad entrare nell'IF.
    Grazie ancora e penso ci risentiremo presto, sono una novellina di c++

  10. #10
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.