Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
 Аватар для Claemor
1 / 0 / 0
Регистрация: 12.04.2021
Сообщений: 15

Чтение строк на кириллице в UTF-8 из файла

01.05.2025, 20:03. Показов 8071. Ответов 79
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <windows.h>
 
 
#define CHUNK_SIZE 1024 // Строка будет не больше 1024 символов
 
BOOL check_a_substr(wchar_t* string, wchar_t* substring) {
    return wcsstr(string, substring) != NULL;
}
 
int main() {
    // Переменные
    wchar_t file_name[250] = L"";
    char buffer[CHUNK_SIZE];
    wchar_t searched_name[60];
    wchar_t searched_surname[60];
 
    // Кодировка вывода/ввода в консоль (Windows-1251)
    system("chcp 1251");
    setlocale(LC_ALL, "Russian_Russia.1251");
    SetConsoleOutputCP(1251);
 
    // Получения пути файла
    wprintf_s(L"Введите путь до файла: ");
    wscanf_s(L"%249s", file_name, (unsigned)_countof(file_name));
 
    FILE* file = _wfopen(file_name, L"r");
    if (!file) {
        wprintf_s(L"Ошибка при открытии файла базы!\n");
        wprintf(L"Код ошибки: %d\n", errno);
        return 1;
    }
 
    // Получение ФИО
    wprintf_s(L"Введите имя человека (БЕЗ ОШИБОК! В НИЖНЕМ РЕГИСТРЕ!): ");
    wscanf_s(L"%59s", searched_name, (unsigned)_countof(searched_name));
    wprintf_s(L"Введите фамилию человека (БЕЗ ОШИБОК! В НИЖНЕМ РЕГИСТРЕ!): ");
    wscanf_s(L"%59s", searched_surname, (unsigned)_countof(searched_surname));
 
    // Поиск в файле
    while (fgets(buffer, CHUNK_SIZE, file)) {
        size_t dummy;
        wchar_t wbuffer[CHUNK_SIZE]; // Буфер для хранения строки в формате wchar_t
        wchar_t wbuffer1251[CHUNK_SIZE]; // Буфер для хранения строки в формате Windows-1251
 
        mbstowcs_s(&dummy, wbuffer, CHUNK_SIZE, buffer, _TRUNCATE); // Преобразование в wchar_t
        WideCharToMultiByte(1251, 0, wbuffer, -1, wbuffer1251, CHUNK_SIZE, NULL, NULL); // Преобразование в Windows-1251
        for (int i = 0; wbuffer1251[i] != L'\0'; i++) {
            wbuffer1251[i] = towlower(wbuffer1251[i]);
        }
        if (check_a_substr(wbuffer1251, searched_name) && check_a_substr(wbuffer1251, searched_surname)) {
            wprintf(L"%ls", wbuffer1251);
        }
    }
 
    fclose(file);
    return 0;
}
Я пытаюсь обработать текстовый файл, содержащий строки на кириллице, и отфильтровать эти строки, содержащие определенные подстроки. Файл сохранен в кодировке UTF-8. Я пробовал ставить и utf-8 в консоли но тогда в билиберду превращается кириллица с ввода, поэтому решил перевести строку с файла в кодировку 1251, но почему-то не выходит. Вобщем какая-то проблема с кодировкой, помогите пожалуйста.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.05.2025, 20:03
Ответы с готовыми решениями:

Программа для конвертации тектового файла из кодировки UTF-8 в UTF-16
Привет. Как можно реализовать эту программу на чистом си?

Написать функцию для распознавания кириллицы (больших и маленьких букв) в кодировке UTF-8
Помогите я никак не могу написать функцию для распознавания кириллицы (больших и маленьких букв) в...

Чтение кириллицы из консоли
Всем добрый вечер. Собственно проблема: есть функция считывающая текст либо из файла, либо из...

79
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
07.05.2025, 22:06
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Раньше я думал, что ее все-таки можно заставить работать как положено.
В той теме использовались w-функции (wprintf, wscanf). У вас в коде обычные. С обычными не будет работать, потому что этот способ переводит консоль в UTF-16 режим, а не в режим конвертации UTF-16->UTF-8.
0
 Аватар для COKPOWEHEU
4056 / 2691 / 432
Регистрация: 09.09.2017
Сообщений: 11,986
07.05.2025, 22:38
Цитата Сообщение от DrOffset Посмотреть сообщение
В той теме использовались w-функции (wprintf, wscanf). У вас в коде обычные.
С wprintf я тоже пробовал. Вот только ни wscanf("%s"), ни wcstomb нормально не работают. Можно, конечно, упороться и написать функцию utf16->utf8 руками, но это уже совсем извращение. Получится именно то, что я описал: отдельно нормальный код, соответствующий стандарту, отдельно адовая гора костылей под винду.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
07.05.2025, 22:58
COKPOWEHEU, код-то есть, который показывает как оно не работает?

Добавлено через 7 минут
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
wscanf("%s")
И как минимум надо wscanf(L"%s").
0
 Аватар для COKPOWEHEU
4056 / 2691 / 432
Регистрация: 09.09.2017
Сообщений: 11,986
08.05.2025, 00:35
Цитата Сообщение от DrOffset Посмотреть сообщение
код-то есть, который показывает как оно не работает?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
 
#if defined(WIN32) || defined(_WIN32) //специальные костыли для виндовой консоли
  #pragma warning(disable : 4996)
  #define _CRT_SECURE_NO_WARNINGS 1
  #include <windows.h>
  #include "fcntl.h"
  #include <io.h>
  void coninit(){
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    setlocale(LC_ALL, ".UTF8");
  }
#else
  #define coninit() setlocale(LC_ALL, "")
#endif
 
int main(){
  coninit();
  
  char buf[100];
  wchar_t wbuf[100];
  
  wprintf(L"Проверка ввода текста в консоли, wchar_t (h,в,λ)\n");
  wscanf(L"%ls", wbuf);
  wcstombs(buf, wbuf, 100);
  wprintf(L"[%ls] -> [%s]\n", wbuf, buf);
  for(int i=0; buf[i]!=0; i++)wprintf(L"[%i] = %u[%c]\n", i, (unsigned char)buf[i], buf[i]);
  
  wprintf(L"Проверка ввода текста в консоли, utf-8 (h,в,λ)\n");
  wscanf(L"%s", buf);
  mbstowcs(wbuf, buf, 100);
  wprintf(L"[%s] -> [%ls]\n", buf, wbuf);
  for(int i=0; wbuf[i]!=0; i++)wprintf(L"[%i] = %u[%lc]\n", i, (unsigned int)wbuf[i], wbuf[i]);
}
Вот как оно работает в нормальной консоли:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ gcc main.c -Wall -Wextra -Wpedantic -Werror -Os
$ ./a.out 
Проверка ввода текста в консоли, wchar_t (h,в,λ)
h,в,λ
[h,в,λ] -> [h,в,λ]
[0] = 104[h]
[1] = 44[,]
[2] = 208[]
[3] = 178[]
[4] = 44[,]
[5] = 206[]
[6] = 187[]
Проверка ввода текста в консоли, utf-8 (h,в,λ)
h,в,λ
[h,в,λ] -> [h,в,λ]
[0] = 104[h]
[1] = 44[,]
[2] = 1074[в]
[3] = 44[,]
[4] = 955[λ]
$
Добавлено через 12 минут
А вот так - в виндовой:
Code
1
2
3
4
5
6
7
8
9
10
11
PS C:\Users\test\Downloads> .\a.exe
Проверка ввода текста в консоли, wchar_t (h,в,λ)
h,в,λ
[h,в,λ] -> [h,]
[0] = 104[h]
[1] = 44[,]
Проверка ввода текста в консоли, utf-8 (h,в,λ)
h,в,λ
[h,] -> [h,]
[0] = 104[h]
[1] = 44[,]
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
08.05.2025, 00:48
COKPOWEHEU, я бы начал с проверки того, что вернула setlocale. Скорее всего в MinGW просто нет такой локали. Отсюда сразу же неверная работа wcstombs.
0
 Аватар для COKPOWEHEU
4056 / 2691 / 432
Регистрация: 09.09.2017
Сообщений: 11,986
08.05.2025, 01:44
Цитата Сообщение от DrOffset Посмотреть сообщение
с проверки того, что вернула setlocale
Да, вы правы, она возвращает NULL какие бы варианты локали я не пробовал передать. Вплоть до всякой дичи вроде "Russian_Russia.65001"

Добавлено через 23 минуты
C
1
2
3
4
BOOL CALLBACK proc(LPTSTR loc){
  wprintf(L"loc [%s]\n", loc);
}
EnumSystemLocalesA(proc, LCID_SUPPORTED);
показывает только один вариант: [000436]. Вменяемой расшифровки этого кода я не нашел.
0
 Аватар для COKPOWEHEU
4056 / 2691 / 432
Регистрация: 09.09.2017
Сообщений: 11,986
08.05.2025, 12:41
C
1
2
3
4
5
6
7
8
9
10
11
12
13
BOOL proc(LPWSTR p1, DWORD p2, LPARAM p3){
    wprintf(L"loc [%ls]\n", p1);
    return 1;
  }
  
  char* coninit(){
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    
    EnumSystemLocalesEx(proc, 0, 0, NULL);
    
    return setlocale(LC_ALL, ".UTF8");
  }
Так чуть лучше: оно выдает кучу
Code
1
2
3
4
loc [ru]
loc [ru-BY]
loc [ru-KG]
loc [ru-KZ]
Но упоминаний о юникоде как не было, так и нет.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6278 / 3002 / 1051
Регистрация: 01.06.2021
Сообщений: 11,228
08.05.2025, 12:51
Цитата Сообщение от DrOffset Посмотреть сообщение
MinGW
там локали корявые и никогда нормально не работают
0
 Аватар для volodin661
6811 / 2312 / 350
Регистрация: 10.12.2013
Сообщений: 7,974
08.05.2025, 17:36
А зачем в принципе нужна Locale, если речь идёт только о превращениях типа большая/маленькая буква ?
0
Нарушитель
622 / 380 / 67
Регистрация: 09.03.2016
Сообщений: 4,163
08.05.2025, 22:11
Найти слова текста содержащие только гласные буквы русского алфавита
Читал...
0
Windows must die
595 / 867 / 103
Регистрация: 23.11.2021
Сообщений: 5,131
Записей в блоге: 19
09.05.2025, 00:23
А мысли о том, что хрюникод вообще ни в коем случае нельзя себе локалью ставить не возникало?
Кириллица отлично вписывается в любую 8-битную кодировку. И нечего мудрить! Я вот сколько КОИ8 пользую (лет 25 уже, наверное), ни разу не видел проблем. Да и в латеховских документах идеал - восьмибитная кодировка, чтобы всякой гадости не повылезало (вроде разрывов строк, страниц, непонятных диакритических знаков и т.д., и т.п.).
1
09.05.2025, 00:27

Не по теме:

Цитата Сообщение от Eddy_Em Посмотреть сообщение
Я вот сколько КОИ8 пользую (лет 25 уже
Это где такие подвалы существуют?

0
 Аватар для volodin661
6811 / 2312 / 350
Регистрация: 10.12.2013
Сообщений: 7,974
09.05.2025, 00:56
а я ногти на ногах тоже не стригу, просто покупаю обувь на 4 размера больше (лет 25 уже, наверное).
0
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
09.05.2025, 07:45
Цитата Сообщение от Eddy_Em Посмотреть сообщение
А мысли о том, что хрюникод вообще ни в коем случае нельзя себе локалью ставить не возникало?
Кириллица отлично вписывается в любую 8-битную кодировку. И нечего мудрить! Я вот сколько КОИ8 пользую (лет 25 уже, наверное), ни разу не видел проблем. Да и в латеховских документах идеал - восьмибитная кодировка, чтобы всякой гадости не повылезало (вроде разрывов строк, страниц, непонятных диакритических знаков и т.д., и т.п.).
Ты втираешь нам какую-то дичь.
2
 Аватар для COKPOWEHEU
4056 / 2691 / 432
Регистрация: 09.09.2017
Сообщений: 11,986
09.05.2025, 09:16
Цитата Сообщение от Eddy_Em Посмотреть сообщение
А мысли о том, что хрюникод вообще ни в коем случае нельзя себе локалью ставить не возникало?
Возникало. Лет 20 назад, а то и больше. Потом от нее отказались по понятной всем причине.
100500 локальных кодировок не нужны.
0
Нарушитель
622 / 380 / 67
Регистрация: 09.03.2016
Сообщений: 4,163
09.05.2025, 12:29
Что бы писать юникодные программы,
на которых работают с разными всякими словами, существуют гуёвые контрукторы.
Типа бильдера, или ку те. (Там по дефолту юникод.)
Не побоюсь написать, что в консоли юникод, только срачи устраивать нужен.

Добавлено через 7 минут
Вот Edit... Перетащеный на форму. Пишешь в него любое слово, хоть иероглифы копирешь. В нём UTF8.
Перегоняешь в ихнее String... Там тоже по дефолту UTF8. И так далее. И тому подобное....
0
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
09.05.2025, 12:30
Цитата Сообщение от Наталья8 Посмотреть сообщение
Что бы писать юникодные программы,
на которых работают с разными всякими словами, существуют гуёвые контрукторы.
Типа бильдера, или ку те. (Там по дефолту юникод.)
Не побоюсь написать, что в консоли юникод, только срачи устраивать нужен.
0
Нарушитель
622 / 380 / 67
Регистрация: 09.03.2016
Сообщений: 4,163
09.05.2025, 12:33
На консоли, слова перекладывают туда- сюда, только на киберфоруме.

Добавлено через 2 минуты
*************************
0
 Аватар для COKPOWEHEU
4056 / 2691 / 432
Регистрация: 09.09.2017
Сообщений: 11,986
09.05.2025, 12:43
Цитата Сообщение от Наталья8 Посмотреть сообщение
На консоли, слова перекладывают туда- сюда, только на киберфоруме.
Глупость редкостная. Вы вообще в консоли-то работать пробовали?
Ну и да, юникод это не только русские буквы. Можно, например, выводить результаты расчетов в каноничном научном формате 9.109⋅10⁻³¹. Можно всякие математические знаки ±≈. Даже окошки во всяком TUI тоже юникодом рисуются ─ │ ┌ ┐ └ ┘.
0
Нарушитель
622 / 380 / 67
Регистрация: 09.03.2016
Сообщений: 4,163
09.05.2025, 12:46
Можно вот такое устроить легко...
В зависимости от функций, принимает и char и wchar_t



Таким же образом и ввод организуеться.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.05.2025, 12:46
Помогаю со студенческими работами здесь

Как заменить чтение массива на чтение файла с .txt
что делать если программа подстроена под чтение массива, а нужно читать .тхт

UTF-8
Здравствуйте! В общем разбираюсь я тут с UTF-8. Имеет место быть следующая функция: int...

C, Linux, UTF-8 - не видно русских символов
Здравствуйте. Я только начинаю разбираться с языком и кодировками и возник следующий вопрос. ...

Сложности понимания работы utf-8 и ascii
Привет! Давненько заметил вот такую штуку: $ echo &quot;abcde&quot; &gt; test_utf-8_en.txt $ echo &quot;абвг&quot; &gt;...

Написать функцию выполняющую перевод строки с символами русского алфавита в кодировке UTF-8 в заданный набор символов
Помогите пожалуйста написать функцию выполняющую перевод строки с символами русского алфавита в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
Модель здравосохранения 18. Чем здоровее работник, тем быстрее выгорает
anaschu 24.05.2026
Имитационная модель корпоративного здравоохранения: что показывает математика Сегодня в модели рабочего коллектива на AnyLogic появились три новые механики — выгорание через накопленную усталость,. . .
Модель здравосохранения 17. Планы на выгорание
anaschu 23.05.2026
Вот конкретная схема реализации: В классе Работник добавить: накопленнаяУсталость — растёт каждый час работы, снижается в перерывы и болезни коэффициентПрезентеизма — снижает продуктивность. . .
Изменение цветов в палитре gif файла aka фавикона
russiannick 23.05.2026
Изменение цветов в палитре gif файла, юзаемого как фавиконка в составе html-файла, помещенная в base64, средствами нативного Java Script, навеянное сном в майский день. Для работы необходим браузер,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru