如何读取具有特殊字符的文件?-C
我有一个countries.txt文档,其中列出了西班牙语国家的名称。这意味着例如有“')和“ñ”字符 我有一个小函数,用来计算文档中的行数,它最初是用如何读取具有特殊字符的文件?-C,c,unicode,special-characters,C,Unicode,Special Characters,我有一个countries.txt文档,其中列出了西班牙语国家的名称。这意味着例如有“')和“ñ”字符 我有一个小函数,用来计算文档中的行数,它最初是用fgets()函数制作的,我对它进行了编辑,使它使用fgetws(),因为我知道特殊字符应该存储在wchar\u t变量中 int linesCount = 0; wchar_t line[MAX_SIZE]; while(fgetws(line, sizeof(line), f) != NULL){ lin
fgets()
函数制作的,我对它进行了编辑,使它使用fgetws()
,因为我知道特殊字符应该存储在wchar\u t
变量中
int linesCount = 0;
wchar_t line[MAX_SIZE];
while(fgetws(line, sizeof(line), f) != NULL){
linesCount++;
}
rewind(f);
return linesCount;
}
1) 如果函数找到包含“')的字符串,程序将崩溃。
2) 如果没有找到任何特殊字符,valgrind会发现更多的内存泄漏,而不是在至少有一个特殊字符(如“ñ”)的情况下仅发现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”时崩溃,该“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或拉丁语-1 您可能得到的是,“西班牙语”没有提供有关字符集编码的信息-因此,尽管调用`setlocale'时没有出现错误,但您可能正在尝试读取一个utf-8文件(具有多字节编码),该文件采用字符映射(每个字符一个字节)编码 如果您只需要计算行数,只需使用字符,您的程序就会按预期工作 因此,与其尝试猜测,不如现在就阅读以下内容: 之后,您应该能够使用其他工具确定文件编码,然后在set locale调用中设置正确的编码。“es_es.UTF-8”或“es_es.ISO8859-1”中的一个应该可以工作
然后,如果你有一个“现实世界”的任务,必须处理这么简单的国际文本文件,我强烈建议你离开C语言,使用更高级的语言。你仍然需要知道文件编码——但生活将变得简单(至少)一个数量级。文件在dis上保存时,不要使用“wchars”-它将以“编码”进行编码,通常是utf-8或拉丁语-1 您可能得到的是,“西班牙语”没有提供有关字符集编码的信息-因此,尽管调用`setlocale'时没有出现错误,但您可能正在尝试读取一个utf-8文件(具有多字节编码),该文件采用字符映射(每个字符一个字节)编码 如果您只需要计算行数,只需使用字符,您的程序就会按预期工作 因此,与其尝试猜测,不如现在就阅读以下内容: 之后,您应该能够使用其他工具确定文件编码,然后在set locale调用中设置正确的编码。“es_es.UTF-8”或“es_es.ISO8859-1”中的一个应该可以工作
然后,如果你有一个“现实世界”的任务,必须处理这么简单的国际文本文件,我强烈建议你离开C语言,使用更高级的语言。你仍然需要知道文件编码——但生活将变得简单(至少)一个数量级。好吧,
valgrind
输出不是很有帮助,除非你包括分配你正在使用的内存的代码部分?(如果这是您的全部代码,则它必须是有问题的无掩码系统分配。)请提供。文件countries.txt
的字符编码是什么?LC_CTYPE
环境变量的值是多少?您应该以二进制模式将文件读取为char
,然后自己进行字符集转换,这样您就知道发生了什么。@DavidC.Rankin我用更多信息完成了这篇文章,我认为这会使valgrind输出更有用。我相信您的选择是“es_es.UTF-8”
或“es_es”
(适用于ISO-8859-1)或可能的“es”_ES@euro“
(适用于ISO-8859-15)(尽管“es”
部分可能因您的位置而异)那么,valgrind
输出不是很有帮助,除非您包括分配您正在使用的内存的代码部分?(如果这是您的全部代码,那么它必须是有问题的无掩码系统分配。)请提供。文件countries.txt
的字符编码是什么?LC\u CTYPE
环境变量的值是什么?您应该以二进制模式将文件读取为char
,然后自己进行字符集转换,这样您就知道发生了什么。@DavidC.Rankin我用更多信息完成了这篇文章我认为它使valgrind输出更有用我相信您的选择是“es_es.UTF-8”
或“es_es”
(对于ISO-8859-1)或可能的“es”_ES@euro“
(适用于ISO-8859-15)(尽管“es”
零件可能因位置而异)