簡體   English   中英

如何讀取帶有特殊字符的文件? - C

[英]How to read file with special characters? - C

我有一個 countries.txt 文檔,其中以西班牙語列出了國家/地區的名稱。 這意味着例如有“´”和“ñ”字符。

我有一個小的 function 用於計算文檔中的行數,它最初是用fgets() function 制作的,我對其進行了編輯,因此它使用fgetws() ,因為我知道特殊字符應該存儲在wchar_t變量中。

  int linesCount = 0;
    wchar_t line[MAX_SIZE];

    while(fgetws(line, sizeof(line), f) != NULL){
        linesCount++;
    }
    rewind(f);

    return linesCount;
}

1) 如果 function 找到包含“´”的字符串,則程序崩潰。 2) 如果沒有找到任何特殊字符,valgrind 會發現更多的 memory 泄漏,而不是只有 1 個泄漏,如果至少有一個特殊字符,如“ñ”。

這是主要的:

int main (void)
{
 setlocale(LC_ALL, "spanish");
 countries = fopen("countries.txt", "r");
 int counCount = count_lines(countries);
 fclose(countries);
}

這是 countries.txt 的第一部分:

Aruba
Angola
Albania
Andorra
Argelia
Armenia
Austria
Alemania
Antártida
Argentina

程序在到達帶有“á”字母的“Antártida”時崩潰。

我附上錯誤 valgrind 顯示:

1 errors in context 1 of 1:
==16211== Conditional jump or move depends on uninitialised value(s)
==16211==    at 0x4FCB443: __wmemchr_avx2 (memchr-avx2.S:97)
==16211==    by 0x4EBE164: _IO_getwline_info (iogetwline.c:86)
==16211==    by 0x4EBDD2C: fgetws (iofgetws.c:53)
==16211==    by 0x108BC3: count_lines (people_generator.c:10)
==16211==    by 0x108B3C: main (main.c:15)
==16211==  Uninitialised value was created by a heap allocation
==16211==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16211==    by 0x4EBB858: _IO_wfile_doallocate (wfiledoalloc.c:79)
==16211==    by 0x4ECA378: _IO_doallocbuf (genops.c:365)
==16211==    by 0x4EC172B: _IO_wfile_underflow (wfileops.c:179)
==16211==    by 0x4EBF691: _IO_wdefault_uflow (wgenops.c:204)
==16211==    by 0x4EBE1C0: _IO_getwline_info (iogetwline.c:61)
==16211==    by 0x4EBDD2C: fgetws (iofgetws.c:53)
==16211==    by 0x108BC3: count_lines (people_generator.c:10)
==16211==    by 0x108B3C: main (main.c:15)

保存在 dis 上的文件不使用“wchars” - 它將以“編碼”編碼,最常見的是 utf-8 或 latin-1。

您可能會得到的是“西班牙語”沒有提供有關字符集編碼的信息 - 因此,盡管您在調用 `setlocale 時沒有收到錯誤,但您可能正在嘗試讀取 utf-8 文件(具有多字節編碼),使用charmap(每個字符一個字節)編碼。

如果您只需要計算行數,只需使用字符,您的程序就會按預期運行。

因此,與其試圖猜測,不如立即閱讀: https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about- unicode-and-character-sets-no-excuses/

之后,您應該能夠使用您可以使用的其他工具來確定您的文件編碼,然后在您的 set-locale 調用中設置正確的編碼。 “es_ES.UTF-8”或“es_ES.ISO8859-1”之一應該可以工作。

然后,如果您有一個“現實世界”的任務必須如此簡單地處理國際文本文件,我強烈建議您遠離 C 並使用更高級別的語言。 您仍然必須知道文件編碼 - 但生活將(至少)容易一個數量級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM