Problema con la Gestione delle Parole Accentate

di il
8 risposte

Problema con la Gestione delle Parole Accentate

Il programma funziona bene nel complesso; tuttavia, incontra un problema quando elabora parole accentate. Quando il programma incontra parole con caratteri accentati, smette di funzionare correttamente. La ragione esatta di questa interruzione non è chiara, e sono necessari ulteriori debug per identificare la causa di questo problema con le parole accentate.

Attraverso alcuni debug con varie print inserite qua e là, ho potuto circoscrivere che il problema risiede nella funzione readCharacters quando legge carattere per carattere.

Il programma accetta solo librerie standard C e dev funzionare su macchine Unix-like (no Windows) o kernel Linux. È progettato per leggere un file di testo italiano che può contenere caratteri speciali come ., ?, ! e '. Scansiona le parole nel testo e le aggiunge a un file CSV, mantenendo la frequenza di ciascuna parola. Il programma utilizza una matrice per memorizzare le parole e le loro rispettive frequenze e coordinate, mentre una struttura a dizionario viene utilizzata per gestire l'alfabeto e i sotto-alfabeti.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>

// Definizione della struttura per un oggetto contenente una Stringa, la sua frequenza, e le coordinate nella matrice
typedef struct {
    wchar_t Stringa[31]; // Stringa di massimo 30 caratteri più il terminatore null
    float frequenza; // Frequenza della parola
    int occorrenza; // Numero di occorrenze della parola
    int x; // Coordinata x nella matrice
    int y; // Coordinata y nella matrice
} oggetto;

// Definizione della struttura per una matrice contenente una lista di oggetti e le sue dimensioni
typedef struct {
    oggetto** lista; // Lista di oggetti (matrice)
    int* x; // Array delle dimensioni delle righe
    int y; // Numero di righe
} matrice;

// Definizione della struttura per l'alfabeto contenente un sottoalfabeto e una parola
struct Alfabeto {
    struct Alfabeto* sottoalfabeto[46]; // Sottoalfabeto (array di puntatori ad altre strutture Alfabeto)
    oggetto* parola; // Parola associata al nodo dell'alfabeto
};

// Definizione del tipo Dizionario come un puntatore a struct Alfabeto
typedef struct Alfabeto Dizionario;

// Dichiarazione delle funzioni
Dizionario* deallocazione(Dizionario* diz);
void stampaMatrice(matrice* matrix, FILE* foglio);
int indiceAscii(wchar_t carattere);
bool confrontaStringhe(wchar_t* Stringa1, wchar_t* Stringa2);
int fineStringa(wchar_t Stringa1[], matrice* matrix, Dizionario* diz, int fine);
void leggiCaratteri(FILE* file, matrice* matrix, Dizionario* dizionario);

int main() { // Funzione principale

    setlocale(LC_ALL, "it_IT.UTF-8");  // Imposta una locale che supporta Unicode
    FILE* file = fopen("prova.txt", "r"); // Apre il file di input in lettura
    FILE* foglio = fopen("controprova.csv", "w"); // Apre il file di output in scrittura
    if (file == NULL || foglio == NULL) { // Se uno dei file non si apre
        exit(EXIT_FAILURE); // Esce con errore
    }

    Dizionario* dizionario = (Dizionario*)calloc(1,sizeof(Dizionario)); // Alloca il dizionario
    dizionario->parola = (oggetto*)calloc(1,sizeof(oggetto)); // Alloca una parola nel dizionario

    matrice matrix;
    matrix.y = 1; // Inizializza il numero di righe della matrice
    matrix.x = (int*)calloc(1,sizeof(int)); // Alloca memoria per l'array delle dimensioni delle righe
    matrix.x[0] = 1; // Inizializza la dimensione della prima riga
    matrix.lista = (oggetto**)calloc(1,matrix.y * sizeof(oggetto*)); // Alloca memoria per la matrice
    matrix.lista[matrix.y - 1] = (oggetto*)calloc(1,2 * sizeof(oggetto)); // Alloca memoria per una riga della matrice

    leggiCaratteri(file, &matrix, dizionario); // Chiama la funzione leggiCaratteri
    stampaMatrice(&matrix, foglio); // Chiama la funzione stampaMatrice

    fclose(foglio); // Chiude il file di output
    fclose(file); // Chiude il file di input

    for (int i = 0; i < matrix.y -1; i++) { // Libera la memoria allocata per la matrice
        free(matrix.lista[i]);
    }
    free(matrix.lista);
    free(matrix.x);

    for (int i = 0; i < 46; i++) { // Libera la memoria del dizionario
        dizionario->sottoalfabeto[i] = deallocazione(dizionario->sottoalfabeto[i]); // Chiama la funzione deallocazione
    }
    free(dizionario->parola); // Libera la memoria della parola
    free(dizionario); // Libera la memoria del dizionario

    return 0; // Ritorna 0
}

Dizionario* deallocazione(Dizionario* diz) { // Funzione per deallocare la memoria del dizionario
    if (diz == NULL) { // Se il dizionario è NULL
        return NULL; // Ritorna NULL
    }

    for (int i = 0; i < 46; i++) { // Scorre i 46 elementi del sottoalfabeto
        diz->sottoalfabeto[i] = deallocazione(diz->sottoalfabeto[i]); // Chiama la funzione deallocazione ricorsivamente
    }
    free(diz->parola); // Libera la memoria della parola
    free(diz); // Libera la memoria del dizionario
    return NULL; 
}

int indiceAscii(wchar_t carattere) { // Funzione per ottenere l'indice ASCII di un carattere
    // Converte il carattere in minuscolo
    wchar_t c = towlower(carattere);

    if (iswalpha(c)) { // Gestisce le lettere non accentate
        return c - L'a';
    } else { // Gestisce i caratteri accentati
        switch (c) {
            case L'à': return 26;
            case L'è': return 27;
            case L'é': return 28;
            case L'ì': return 29;
            case L'ò': return 30;
            case L'ù': return 31;
            case L'!': return 32;
            case L'?': return 33;
            case L'.': return 34;
            case L'\'': return 35;
        }
    }

    // Gestisce i numeri
    if (c >= L'0' && c <= L'9') {
        return 36 + (c - L'0');
    }

    // Carattere non riconosciuto
    return -1;
}

// Funzione per confrontare due stringhe
bool confrontaStringhe(wchar_t* Stringa1, wchar_t* Stringa2) { 
    if (*Stringa1 == L'\0' && *Stringa2 == L'\0') { // Se entrambe le stringhe sono terminate
        return true; // Ritorna true
    }
    
    if (*Stringa1 == *Stringa2 || (towlower((wchar_t)*Stringa1) == towlower((wchar_t)*Stringa2))) { // Controlla se i caratteri sono uguali o se sono uguali in minuscolo
        return confrontaStringhe(Stringa1 + 1, Stringa2 + 1); // Richiama la funzione sul prossimo carattere
    }

    return false; // Se i caratteri non sono uguali, ritorna false
}

// Funzione per la ricerca operativa di una Stringa nella matrice
bool ricercaOperativa(wchar_t Stringa[], int indice, Dizionario* diz, int i, int p, matrice* m) { 
    Dizionario* dizAttuale = diz; // Inizializza dizAttuale con diz
    int ASCII; // Dichiara la variabile ASCII

    if (Stringa[indice] == L'\0') { // Se il carattere corrente è il terminatore di Stringa
        if (confrontaStringhe(dizAttuale->parola->Stringa, m->lista[i][0].Stringa)) { // Se la Stringa della parola del dizionario è uguale alla Stringa della matrice
            int n = 1;
            int y = dizAttuale->parola->y;
            int x = dizAttuale->parola->x;
            int trovato = 0;

            m->lista[y][0].occorrenza++;
            while (n <= m->x[y] && m->lista[y][n].x == n) { // Finché n è minore o uguale alla dimensione x della matrice e l'elemento della matrice è uguale a n
                if (confrontaStringhe(m->lista[y][n].Stringa, m->lista[i][p].Stringa)) { // Se la Stringa corrente è uguale alla Stringa della matrice
                    m->lista[y][n].occorrenza++; // Incrementa l'occorrenza
                    m->lista[y][n].frequenza = (float)m->lista[y][n].occorrenza / (float)m->lista[y][0].occorrenza; // Calcola la frequenza
                    trovato = 1; // Imposta trovato a 1
                }
                m->lista[y][n].frequenza = (float)m->lista[y][n].occorrenza / (float)m->lista[y][0].occorrenza; // Calcola la frequenza
                n++; // Incrementa n
            }
            if (!trovato) {
                if (n > m->x[y]) {
                    m->x[y] = n;
                }
                m->lista[y] = realloc(m->lista[y], (n + 1) * sizeof(oggetto)); // Rialloca la memoria per la riga
                wcscpy(m->lista[y][n].Stringa, m->lista[i][p].Stringa); // Copia la Stringa nella matrice
                m->lista[y][n].occorrenza = 1; // Inizializza l'occorrenza a 1
                m->lista[y][n].frequenza = (float)m->lista[y][n].occorrenza / (float)m->lista[y][0].occorrenza; // Calcola la frequenza
                m->lista[y][n].x = n; // Assegna n alla coordinata x
            }

            return true; // Ritorna true
        }

        wcscpy(dizAttuale->parola->Stringa, Stringa); // Copia la Stringa nella parola del dizionario
        dizAttuale->parola->x = p; // Assegna p alla coordinata x della parola
        dizAttuale->parola->y = i; // Assegna i alla coordinata y della parola
        m->lista[i][1].x = 1; // Assegna 1 alla coordinata x della matrice
        m->lista[i][0].x = 0; // Assegna 0 alla coordinata x della matrice
        m->lista[i][1].occorrenza = 1; // Inizializza l'occorrenza a 1
        m->lista[i][0].occorrenza = 1; // Inizializza l'occorrenza a 1
        m->lista[i][1].frequenza = (float)m->lista[i][1].occorrenza / (float)m->lista[i][0].occorrenza; // Calcola la frequenza

        return false; // Ritorna false
    }

    ASCII = indiceAscii(Stringa[indice]); // Calcola l'indice ASCII del carattere corrente
    if (dizAttuale->sottoalfabeto[ASCII] == NULL) { // Se il sottoalfabeto corrente è NULL
        dizAttuale->sottoalfabeto[ASCII] = (Dizionario*)calloc(1,sizeof(Dizionario)); // Alloca memoria per il sottoalfabeto
        if (dizAttuale->sottoalfabeto[ASCII] == NULL) { // Se la memoria non è stata allocata
            exit(1); // Esce con errore
        }
        dizAttuale->sottoalfabeto[ASCII]->parola = (oggetto*)calloc(1,sizeof(oggetto)); // Alloca memoria per la parola del sottoalfabeto
        if (dizAttuale->sottoalfabeto[ASCII]->parola == NULL) { // Se la memoria non è stata allocata
            exit(1); // Esce con errore
        }
    }
    dizAttuale = dizAttuale->sottoalfabeto[ASCII]; // Assegna il sottoalfabeto corrente a dizAttuale
    return ricercaOperativa(Stringa, indice + 1, dizAttuale, i, p, m); // Richiama la funzione ricorsivamente
}

// Funzione per gestire la fine di una Stringa
int fineStringa(wchar_t Stringa1[], matrice* matrix, Dizionario* diz, int fine) { 
    if (Stringa1[0] == L'\0') { // Se la Stringa è vuota
        return 0; // Ritorna 0
    }
    wcscpy(matrix->lista[matrix->y - 1][1].Stringa, Stringa1); // Copia la Stringa nella matrice
    matrix->lista[matrix->y - 1][1].x = 1; // Assegna 1 alla coordinata x in posizione 1
    matrix->lista[matrix->y - 1][0].x = 0; // Assegna 0 alla coordinata x in posizione 0
    
    int controllo = ricercaOperativa(matrix->lista[matrix->y - 1][0].Stringa, 0, diz, matrix->y - 1, 1, matrix); // Chiama la funzione ricercaOperativa
    if (controllo == 0) {
        matrix->y++;
        matrix->lista = realloc(matrix->lista, matrix->y * sizeof(oggetto*)); // Rialloca memoria per la matrice
        matrix->x = realloc(matrix->x, matrix->y * sizeof(int));
        matrix->x[matrix->y - 1] = 1;
        matrix->lista[matrix->y - 1] = (oggetto*)calloc(1,2 * sizeof(oggetto));
    }

    wcscpy(matrix->lista[matrix->y - 1][0].Stringa, Stringa1); // Copia la Stringa nella matrice
    if (fine == 1) { // Se fine è 1
        wcscpy(matrix->lista[matrix->y - 1][1].Stringa, matrix->lista[0][0].Stringa); // Copia la Stringa iniziale nella matrice
        int controllo = ricercaOperativa(matrix->lista[matrix->y - 1][0].Stringa, 0, diz, matrix->y - 1, 1, matrix); // Chiama la funzione ricercaOperativa
        return 0; // Ritorna 0
    }

    Stringa1[0] = L'\0'; // Resetta la Stringa
    return 0; // Ritorna 0
}

// Funzione per leggere i caratteri dal file e gestire la Stringa temporanea
void leggiCaratteri(FILE* file, matrice* matrix, Dizionario* dizionario) { 

    wchar_t Stringa1[31]; // Dichiara una Stringa di 30 caratteri
    int indice = 0; // Inizializza l'indice a 0
    wchar_t carattere; // Dichiara la variabile carattere
    int primaParola = 0;
    const wchar_t* caratteriAccentati = L"àèéìòóùÀÈÉÌÒÓÙ";

    while ((carattere = fgetwc(file))) { // Legge il carattere dal file
        wchar_t successivo = fgetwc(file); // Legge il prossimo carattere
        fseek(file, -1, SEEK_CUR); // Riposiziona il cursore del file indietro di un carattere
        if ((carattere == L' '||carattere ==L'\n') && successivo == WEOF) {
            // Aggiunge la parola al dizionario per evitare che l'ultima parola non venga considerata come finale
            wcscpy(matrix->lista[matrix->y - 1][1].Stringa, matrix->lista[0][0].Stringa); // Copia la Stringa iniziale nella matrice
            ricercaOperativa(matrix->lista[matrix->y - 1][0].Stringa, 0, dizionario, matrix->y - 1, 1, matrix); // Chiama la funzione ricercaOperativa per controllare se la chiave è stata già incontrata nel testo
            return;
        }
        // Legge la prima parola
        if (primaParola == 0 && (carattere == L'\n' || carattere == L' ')) { // Se i primi caratteri sono \n o spazio saltali
            continue;
        } else if (primaParola == 0 && (iswalnum(carattere) || (wcschr(caratteriAccentati, carattere) != NULL))) {  // Se trovi o quando troverai dei caratteri alfanumerici aggiungili alla matrice in prima posizione
            matrix->lista[0][0].Stringa[indice] = carattere;
            indice++;
            if (successivo == L' ' || successivo == L'\n' || successivo == L'!' || successivo == L'?' || successivo == L'.') { // Se seguito da spazio o da a capo termina la Stringa 
                matrix->lista[0][0].Stringa[indice] = L'\0';
                indice = 0;
                primaParola = 1;
            } else if (successivo == L'\'') { // Se seguito da apostrofo appendi l'apostrofo e termina la Stringa e la primaparola
                matrix->lista[0][0].Stringa[indice] = L'\'';
                matrix->lista[0][0].Stringa[indice + 1] = L'\0';
                indice = 0;
                primaParola = 1;
                // Incrementa il cursore per impedire di leggere 2 volte l'apostrofo
                fseek(file, 1, SEEK_CUR);
            }
            continue;
        } else if (primaParola == 0 && (carattere == L'!' || carattere == L'?' || carattere == L'.')) { // Se incontri dei caratteri speciali aggiungili alla matrice come dei caratteri a sé
            matrix->lista[0][0].Stringa[indice] = carattere;
            matrix->lista[0][0].Stringa[indice + 1] = L'\0';
            primaParola = 1;
            indice = 0;
            continue;
        }

        if (carattere == L'!' || carattere == L'?' || carattere == L'.') {
            if (indice > 0) {
                Stringa1[indice] = L'\0';
                fineStringa(Stringa1, matrix, dizionario, 0); // Chiama la funzione fineStringa
                indice = 0;
            }
            Stringa1[0] = carattere;
            Stringa1[1] = L'\0';
            if (successivo == WEOF) {
                fineStringa(Stringa1, matrix, dizionario, 1); // Chiama la funzione fineStringa con il parametro fine a 1
                break;
            }
            fineStringa(Stringa1, matrix, dizionario, 0);
            indice = 0;
        } else if (iswalnum(carattere) || (wcschr(caratteriAccentati, carattere) != NULL) || carattere == L'\'') {
            Stringa1[indice++] = carattere; // Aggiunge il carattere alla Stringa
            wprintf(L"%lc", carattere); // Stampa il carattere

            if (successivo == L' ' || successivo == L'\n' || successivo == WEOF ||
                successivo == L'!' || successivo == L'?' || successivo == L'.' || carattere == L'\'') {
                Stringa1[indice] = L'\0';
                fineStringa(Stringa1, matrix, dizionario, (successivo == WEOF) ? 1 : 0); // Chiama la funzione fineStringa
                indice = 0;
            }
        } else if (carattere == L' ' || carattere == L'\n') {
            if (indice > 0) {
                Stringa1[indice] = L'\0';
                fineStringa(Stringa1, matrix, dizionario, 0); // Chiama la funzione fineStringa
                indice = 0;
            }
        } else if (!(iswalnum(carattere) || (wcschr(caratteriAccentati, carattere) != NULL) ||
                      carattere == L'\'' || carattere == L'!' ||
                      carattere == L'?' || carattere == L'.') &&
                      successivo == L' ' || successivo == L'\n') {
            if (indice > 0) {
                Stringa1[indice] = L'\0';
                fineStringa(Stringa1, matrix, dizionario, 0); // Chiama la funzione fineStringa
                indice = 0;
            }
            continue;
        }

        if (successivo == WEOF) { // Se raggiunge la fine del file
            break;
        }
    }
    return;
}

// Funzione per stampare la matrice sul file
void stampaMatrice(matrice* matrix, FILE* foglio) {
    for (int i = 0; i <= matrix->y - 1; i++) {
        if (matrix->lista[i][1].frequenza == 0) {
            return;
        }
        fwprintf(foglio, L"%ls", matrix->lista[i][0].Stringa); // Stampa la prima colonna (parola)
        for (int j = 1; j <= matrix->x[i]; j++) {
            fwprintf(foglio, L",%ls,%.4f", matrix->lista[i][j].Stringa, matrix->lista[i][j].frequenza); // Stampa la parola e la sua frequenza
        }
        if (i != matrix->y - 1) {
            fwprintf(foglio, L"\n");
        }
    }
}

8 Risposte

  • Re: Problema con la Gestione delle Parole Accentate

    Per provare manca il codice di operationalSearch

    E anche un esempio di file di testo in input (con cui hai l'errore)

  • Re: Problema con la Gestione delle Parole Accentate

    30/06/2024 - oregon ha scritto:


    Per provare manca il codice di operationalSearch

    E anche un esempio di file di testo in input (con cui hai l'errore)

    Ho tradotto per comodità il codice in italiano e ho provveduto a specificare il codice delle funzioni omesse. Le ho omesse per minimizzare il codice dato che è abbastanza lungo. Comunque, dopo numerosi tentativi di printf, ti posso già dire che il problema è circoscritto alla funzione leggiCaratteri e al massimo alla funzione indiceAscii. Quando devo leggere parole con accento, il programma termina, cosa che è assurda perché le ho gestite con wchar_t per gestire questi caratteri speciali di Unicode.

    La funzione operationalSearch l'ho tradotta in ricercaOperativa, che aggiunge lettere grazie a un indice che do di default per ogni lettera grazie alla funzione indiceAscii a un dizionario per vedere se sono state già lette.

  • Re: Problema con la Gestione delle Parole Accentate

    Ho usato un file di dati di prova che non ha dato alcun problema.

    Se vuoi fornire tu, come ti avevo chiesto, un file di prova che crea il problema, posso fare un test.

  • Re: Problema con la Gestione delle Parole Accentate

    30/06/2024 - oregon ha scritto:


    Ho usato un file di dati di prova che non ha dato alcun problema.

    Se vuoi fornire tu, come ti avevo chiesto, un file di prova che crea il problema, posso fare un test.

    Se tu provi come file di input un testo del genere (da “ a ”):

    prova.txt

    "


       ciao com'è andata lì su la festa?

       "

    mi aspetto un output controprova.csv:

    ciao, com' 1,000

    com', è 1,000

    è andata 1,000

    andata lì 1,000

    lì, su 1,000

    su, la 1,000

    la, festa 1,000

    festa, ? 1,000

    ?, ciao 1,000

    come puoi notare l'output termina quando incontra un accento, se tu provi a fare la medesima cosa senza accenti funziona bene

  • Re: Problema con la Gestione delle Parole Accentate

    Non ho provato (sono in autobus) MA questi pasticci sono legati, al 99.9 periodico %, a problemi di encoding.

    NON BASTA scrivere

    setlocale(LC_ALL, "it_IT.UTF-8")

    sperando che tutti funzioni. 

    ANCHE IL CODICE SORGENTE che contiene le costanti accentate DEVE usare lo stesso encoding OPPURE i caratteri devono essere scritti direttamente in esadecimale (codifica UTF-8) in modo da ovviare all'encoding in cui il file e' salvato.

    MA NON BASTA ANCORA! 

    TUTTA LA PIPELINE che coinvolge i caratteri DEVE USARE LO STESSO ENCODING .

    Insomma, bisogna fare le pulci a tutto il funzionamento di tutto quello che sta attorno al programma che stai scrivendo e a come lo userai. 

  • Re: Problema con la Gestione delle Parole Accentate

    01/07/2024 - migliorabile ha scritto:


    Non ho provato (sono in autobus) MA questi pasticci sono legati, al 99.9 periodico %, a problemi di encoding.

    NON BASTA scrivere

    setlocale(LC_ALL, "it_IT.UTF-8")

    sperando che tutti funzioni. 

    ANCHE IL CODICE SORGENTE che contiene le costanti accentate DEVE usare lo stesso encoding OPPURE i caratteri devono essere scritti direttamente in esadecimale (codifica UTF-8) in modo da ovviare all'encoding in cui il file e' salvato.

    MA NON BASTA ANCORA! 

    TUTTA LA PIPELINE che coinvolge i caratteri DEVE USARE LO STESSO ENCODING .

    Insomma, bisogna fare le pulci a tutto il funzionamento di tutto quello che sta attorno al programma che stai scrivendo e a come lo userai. 

    Ho seguito i tuoi consigli e ho fatto diversi tentativi per migliorare la gestione dell'encoding nel mio codice.

    1. Ho verificato che il mio file sorgente fosse salvato in UTF-8.

    2. Ho modificato la dichiarazione dei caratteri accentati usando la notazione Unicode:

      const wchar_t* caratteriAccentati = L"\u00E0\u00E8\u00E9\u00EC\u00F2\u00F3\u00F9\u00C0\u00C8\u00C9\u00CC\u00D2\u00D3\u00D9";
    3. Ho mantenuto l'uso di setlocale(LC_ALL, "it_IT.UTF-8"); all'inizio del programma.

    4. Ho creato un piccolo programma di test per verificare la corretta lettura e gestione dei caratteri accentati:

    
      #include <stdio.h>
      #include <wchar.h>
      #include <locale.h>
      #include <string.h>
      #include <wctype.h>
      int main() {
          setlocale(LC_ALL, "it_IT.UTF-8");
          const wchar_t* caratteriAccentati = L"àèéìòóùÀÈÉÌÒÓÙ";
          FILE* file = fopen("prova.txt", "r");
          if (file == NULL) {
              perror("Errore nell'apertura del file");
              return 1;
          }
          wchar_t carattere;
          wchar_t stringa[30] = {0};
          int indice = 0;
          while ((carattere = fgetwc(file)) != WEOF) {
              if (iswalnum(carattere) || (wcschr(caratteriAccentati, carattere) != NULL)) {
                  stringa[indice++] = carattere;
                  if(wcschr(caratteriAccentati, carattere) != NULL) {
                      if(carattere == L'è') {
                          wprintf(L"true\n");
                      }
                  }
              }
          }
          fclose(file);
          wprintf(L"%ls\n", stringa);
          return 0;
      }

      Questo programma che uso un approccio identico sulla gestione dei caratteri accentati legge da un file di testo, identifica correttamente i caratteri accentati e li stampa correttamente.

    Tuttavia, nel mio programma principale, continuo ad avere alcune difficoltà. Potresti darmi ulteriori suggerimenti su come posso assicurarmi che l'intera pipeline di input/output stia utilizzando correttamente l'encoding UTF-8? 

  • Re: Problema con la Gestione delle Parole Accentate

    Secondo me l'errore è qui:

    fseek(file, -1, SEEK_CUR); // Riposiziona il cursore del file indietro di un carattere

    Da cplusplus.com:

    int fseek ( FILE * stream, long int offset, int origin );

    Reposition stream position indicator

    Sets the position indicator associated with the stream to a new position.

    For streams open in binary mode, the new position is defined by adding offset to a reference position specified by origin.

    For streams open in text mode, offset shall either be zero or a value returned by a previous call to ftell, and origin shall necessarily be SEEK_SET.

    If the function is called with other values for these arguments, support depends on the particular system and library implementation (non-portable).

    Tu hai aperto il file in ‘text mode’, quindi devi usare un altro modo per arretrare di un carattere. Provando con il debugger, si pianta proprio sulla fseek quando ha raggiunto la ‘è’.

  • Re: Problema con la Gestione delle Parole Accentate

    In pratica il problema e' questo: nella codifica UTF-8, un carattere e' rappresentato da uno o PIU' byte.

    un byte per L'ASCII standard, 2 o piu' (fino a 4 se ricordo) per tutto gli altri.

    in seek ragiona in termini di BYTE NON  di caratteri secondo una specifica codifica. 

    Per cui tornare indietro in quel modo di un carattere NON FUNZIONA! 

    Funziona ‘per sbaglio' SOLO per l' ASCII.

Devi accedere o registrarti per scrivere nel forum
8 risposte