С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176

Stringlist и кириллица

22.06.2016, 06:32. Показов 3007. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!
Имеется служба и обычное приложение, которое может подключаться к этой службе через Socket и передавать сообщения. Таким образом приложение отправляет сообщение, а служба принимает и рассылает всем терминальным пользователям на сервере (через msg). Так-же есть логирование основных моментов: запуск службы,подключение пользователя, сообщение, отключение, остановка службы. Всё логируется на кириллице (русскими буквами) и при открытии лога в блокноте нормально читается, английский текст и цифры тоже нормально логируется, и живёт по соседству с сопровождающими его пояснениями на русском. Но стоит отправить службе что-нибудь русскими буквами-весь файл становится не читаемым (т.е. в кракозябрах кроме цифр и самого сообщения), и продолжает также писАться, а сообщения в логах видны нормально. Т.е. коряво отображается только русский текст, который жёстко зашит в программе. Запись идёт следующим кодом:
C++
1
log_write( log_Path, ( "Ко мне подключился " + Socket->RemoteHost + " с IP " + Socket->RemoteAddress ), 1 );
Пробовал запись в разных кодировках и кодировать входящую строку-не помогло.
Код который сохраняет текст:
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
int log_write( String logPath, String my_stroka, int session )
{
    TStringList* lst = new TStringList( );
    if ( FileExists( logPath ) )
    {
        lst->LoadFromFile( logPath );
    }
    // Memo1->Lines->Add( my_stroka );
    if ( session == 0 )
    {
        lst->Add( my_stroka );
    }
    else
    {
        lst->Add( Now( ).FormatString( "DD.MM.YYYY  hh:mm:ss:zzz " ) + my_stroka );
    }
 
    if ( session == 1 )
    {
        lst->Add( "=========Begin=========" );
    }
    if ( session == 2 )
    {
        lst->Add( "=========END========" );
    }
    lst->SaveToFile( logPath );
 
    lst->Clear( );
    lst->Free( );
}
logPath-путь сохранения лога
my_stroka-сам текст, который приходит службе
session-переменная, которая определяет что дополнительно писать к строке
Загрузкой файла в stringlist и снова сохранением его я обеспечил добавление новых строк в файл (по другому у меня тоже не выходило)
Лог после отправки английского сообщения
Кликните здесь для просмотра всего текста
22.06.2016 10:14:55:806 +++Я запустился. Слушаю порт 8090
22.06.2016 10:15:12:592 Ко мне подключился user с IP 192.168.*.*
=========Begin=========
22.06.2016 10:15:13:652 Клиент user с IP 192.168.*.* написал сообщение
qwerty
22.06.2016 10:15:13:746 Функция вывода отработала без ошибок, что удивительно.
22.06.2016 10:15:14:807 От меня отключился user с IP 192.168.*.*
=========END========
22.06.2016 10:15:39:314 ---Я остановился
======================================== =====

Лог после отправки русского сообщения
Кликните здесь для просмотра всего текста
22.06.2016 10:18:34:362 +++Я запустился. Слушаю порт 8090
22.06.2016 10:18:46:156 Ко мне подключился user с IP 192.168.*.*
=========Begin=========
22.06.2016 10:18:47:217 Клиент user с IP 192.168.*.* написал сообщение
йцукен
22.06.2016 10:18:47:248 Функция вывода отработала без ошибок, что удивительно.
22.06.2016 10:18:48:309 От меня отключился user с IP 192.168.*.*
=========END========

Есть предположения, что надо что-то со строками в программе сделать, но что?
Заранее спасибо!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.06.2016, 06:32
Ответы с готовыми решениями:

Подсчитать количество вхождений буквы (кириллица) в строку (кириллица)
Суть такая: по требованию программы ввести строку символов (обыкновенный текст, кириллица(!!!)) и посчитать количество вхождений, если...

StringList в VB
Есть ли подобная переменная в VB?

Поиск в Stringlist
Подскажите как найти нужную строку в stringlist? Я загружаю текстовый файл в stringlist ,а далее надо пройти по всем строкам и найти...

20
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
22.06.2016, 08:24
the_maksimka, то есть приход русского текста уродует уже записанный лог? Так не бывает. Разве что вы на самом деле не пишите его в момент вывода строчек а накапливаете где-то. Зачем вам стринглист? Почему в нормальный файл на прямую не пишите? Поясните ещё раз в какой строке записывается Русский текст и как он отправляется и принимается. Отправитель на той же машине?
0
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
22.06.2016, 08:44  [ТС]
vxg, да, после прихода русского текста весь лог портится и читаются только сами сообщения, но не "сопровождающий" текст.
Я сначала считываю весь лог в стринглист, затем в стринглист добавляю пришедшие строки,и затем снова всё сохраняю. В нормальный файл напрямую у меня не получалось записать-проблемы с кодировками.
Функция записи одна и та-же. Разница только в том, на каком языке отправляется текст.
Отправитель-хост, приёмник-виртуалка
0
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
22.06.2016, 09:01
the_maksimka, очень странная схема работы с логом. я допускаю что на виртуальной машине может быть другая кодировка и сообщения от нее отображались бы убого но что бы они портили лог... в чем была проблема с кодировками которая заставила вас кувыркаться с стринглистом?
0
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
22.06.2016, 10:35  [ТС]
vxg, проблема в том, что оно изначально так-же коряво отображалось, даже когда изначально была не служба, а простое приложение (т.е. я изначально сделал приложение, а потом код переносил в службу). И как только я не изворачивался-всё время записывались только кракозябры. Нашёл на каком-то стороннем форуме вариант использования стринглиста. Некоторое время противился, но потом сдался.
0
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
22.06.2016, 10:40
the_maksimka, не знаю как у вас но у меня если я пишу к примеру
C++
1
2
3
std::ofstream os("c:\\temp\\test.log", std::ios::app);
os << "йцукен" << std::endl;
os.close();
все нормально выводится в лог. попробуйте в начале вырезать стринглист
0
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
23.06.2016, 07:02  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
попробуйте в начале вырезать стринглист
Попробовал, даже ради интереса изменил саму функцию на вот такую:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int log_write( String logPath, String my_stroka, int session )
{
    std::ofstream os( logPath.c_str( ), std::ios::app );
    os << my_stroka.c_str( ) << std::endl;
 
    String s = Now( ).FormatString( "DD.MM.YYYY  hh:mm:ss:zzz " ) + my_stroka;
    os << s.c_str( ) << std::endl;
 
    os << "=========Begin=========" << std::endl;
 
    os << "=========END========" << std::endl;
 
    os.close( );
}
Строки заходили юникодовые, и компилятор на них ругался добавил c_str()
Но в лог теперь выводится
Кликните здесь для просмотра всего текста
21d1ca4
2166f4c
=========Begin=========
=========END========

Лог вывелся только в корень системного диска, в мою папку (которая существует, но в которой есть кириллица) не захотел.
Уже не знаю что ещё можно попробовать.Выложил проект
Вложения
Тип файла: 7z Prog(C++).7z (345.1 Кб, 9 просмотров)
0
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
23.06.2016, 10:25  [ТС]
Вместо String использовать AnsiString ?
Вроде немного допилил, и лог стал выводиться по правильному пути

Добавлено через 57 минут
И всё равно переписывается полностью файл и всё, кроме самого сообщения и чисел, становится не читаемым
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
23.06.2016, 10:53
Лучший ответ Сообщение было отмечено the_maksimka как решение

Решение

Обязательно колоться, но есть любимый кактус? Пишем в файл Юникод, читаем в StringList тоже Юникод:
C++
1
2
3
4
// ...
    lst->LoadFromFile(logPath, TEncoding::UTF8);
// ...
    lst->SaveToFile(logPath, TEncoding::UTF8);
Пишем в лог:
C++
1
log_write(log_Path, String().sprintf(L"Ко мне подключился %s с IP %s", Socket->RemoteHost, Socket->RemoteAddress), 1);
, не будет никаких сбоев с кодировкой.
1
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
23.06.2016, 11:43
the_maksimka, у меня получилось вывести юникод вот таким вот костылем
C++
1
2
3
4
    std::wstring s = L"йцукен";
    std::ofstream os("c:\\temp\\test.log", std::ios::binary);
    os.write((char *)s.c_str(), s.size() * 2);
    os.close();
в итоге в файле вижу йцукен в кодировке UTF-16 LE
по идее если вы сидите в XE и ваша String по факту содержит wchar_t то этот путь подойдет и для вас (в s будет ваша строка, возможно c_str надо будет подать как t_str а size наверное станет Length)
1
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
24.06.2016, 09:28  [ТС]
volvo, работает! Что-то я даже не подумал о таком варианте (с кодировкой).
vxg, попробовал, тоже работает, но в бинарном режиме всё пишется в одну строку, и я разными вариантами пробовал сделать перенос, но что-то не получилось (файл полностью портится). Ваш вариант, на самом деле, более правильный, но в этом случае у меня постоянно возникают проблемы.

Добавлено через 1 час 18 минут
А это может быть из-за того, что разрабатываю на 10 винде x64, а тестирую на 7 x86 ?

Добавлено через 9 минут
или службы что-то по своему делают, что даже первый вариант не работает...
0
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
24.06.2016, 11:45
the_maksimka, для разделения строк используйте \n или \r\n.
0
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
24.06.2016, 11:49  [ТС]
vxg, эти символы добавлять непосредственно в конец строки(когда она уже в переменной) или отдельной записью типа
C++
1
os.write((char *)"\r\n", 4);
0
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
24.06.2016, 14:50
the_maksimka, эти символы добавлять при формировании строки если по нормальному. и кстати так как вы написали оно не выведет юникод
0
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
27.06.2016, 10:11  [ТС]
vxg, я на делфях переписал-там сразу всё завелось.
Я конечно прошу прощения за свою наглость, тем не менее можете подсказать кодом, как правильно сделать запись, учитывая, что у меня заходит простая юникодовая строка, без символов переноса.
0
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
27.06.2016, 13:26
Лучший ответ Сообщение было отмечено the_maksimka как решение

Решение

the_maksimka
вот так
C++
1
2
3
4
5
6
7
8
    std::wstring s1 = L"строка1";
    std::wstring s2 = L"строка2";
    std::wstring s3 = L"строка3";
 
    std::wstring s = s1 + L"\r\n" + s2 + L"\r\n" + s3 + L"\r\n";
    std::ofstream os("c:\\temp\\test.log", std::ios::binary);
    os.write((char *)s.c_str(), s.size() * 2);
    os.close();
1
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
29.06.2016, 08:45  [ТС]
vxg,
к сожалению не заработало, пишет вот так
29.06.2016 12:42:12:384 Функция вывода отработала без ошибок, что удивительно.
Причём сразу
0
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
29.06.2016, 09:21
the_maksimka, тот код что написал я работает. покажите свой код который я мог бы запустить без дописывания 1001 модуля и можно будет сказать почему он у вас не работает
0
2 / 2 / 2
Регистрация: 29.07.2012
Сообщений: 176
29.06.2016, 09:35  [ТС]
vxg, в принципе я серверную часть сделал на делфи, там заработало...думаю дальше решать проблему не стоит
0
Модератор
 Аватар для vxg
3407 / 2178 / 354
Регистрация: 13.01.2012
Сообщений: 8,448
29.06.2016, 10:09
Цитата Сообщение от the_maksimka Посмотреть сообщение
думаю дальше решать проблему не стоит
ну у этого высказывания есть плюс и минус)
плюс: работает и ладно
минус: прогрессирующее невежество и тиражирование уродства
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.06.2016, 10:09
Помогаю со студенческими работами здесь

Из ListView в StringList
В ListView несколько колонок, и установлен checkboxes в ListView. Интересует первая колонка, как все отмеченные записи чикетом из первой...

Поиск по StringList
Требуется осуществить бинарный поиск по StringList. В StringList находятся строки около 6 миллионов. Переменная dic это сам StringList. В...

StringList и OutOfMemory
Всем привет! Имею следующий код: std::auto_ptr&lt;TStringList&gt;fileSave(new TStringList); for (int j=0; j&lt;=999999999; j++){ s =...

Вывести из stringlist
Как выводить из stringlist по одной строке по порядку? Загрузил текст в stringlist sl.Add('Строка1'); sl.Add('Строка2'); ...

Lines в StringList
Как сделать, чтобы бралось по одному значению из TStringList как в Memo? Бралось например как в Memo1.Lines; и удалялось...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru