繁体   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