Как прочитать файл со специальными символами? - C - PullRequest
1 голос
/ 21 апреля 2020

У меня есть документ country.txt, в котором перечислены названия стран на испанском sh языке. Это означает, что есть символы «´» и «ñ», например.

У меня есть небольшая функция, которую я использую для подсчета строк в документе, которая изначально была сделана с помощью функции fgets(), и я отредактировал его так, что он использует fgetws(), так как я понимаю, что специальные переменные должны храниться в wchar_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);
}

Это первая часть страны. прикрепить ошибку, показывает 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)

1 Ответ

0 голосов
/ 21 апреля 2020

Файл, который хранится в файле dis, не использует «wchars» - он будет закодирован в «encoding», чаще всего в utf-8 или в latin-1.

То, что вы можете получить, это то, что "spani sh" не дает информацию о кодировке charset - поэтому, хотя вы не получаете ошибки при вызове `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 и использовать язык более высокого уровня. Вам все равно придется знать кодировку файла - но жизнь будет на порядок (как минимум) проще.

...