223 / 37 / 4
Регистрация: 18.11.2012
Сообщений: 1,502
|
||||||
1 | ||||||
Вывод информации в файл, Кириллица корректно не выводится23.09.2022, 06:43. Показов 5765. Ответов 81
Метки нет (Все метки)
Здравствуйте! Решил вывести информацию в файл по нажатии на кнопку "сохранить", но в файл отображается либо кракозябры, либо ничего, если текст на русском.
Вот код той части кода, которая должна выполнить задуманное: Кликните здесь для просмотра всего текста
Если честно, то я иссяк и хоть это не так важно на данный момент - я про вывод информации в файл, но, думаю, что лишним подобные знания не будут. В чём мой косяк? По идее должно выводить без проблем. Считывая строку из элемента управления "edit" в каком формате ANSII или UNICODE она попадает в буфер?
0
|
23.09.2022, 06:43 | |
Ответы с готовыми решениями:
81
Вывод информации - кириллица и латиница вместе Вывод информации с файла на консоль. Не выводится информация с файлов Ввод вывод в файл и консоль.(Кириллица) Кодировка , кириллица не корректно отображается |
фрилансер
5499 / 5095 / 1047
Регистрация: 11.10.2019
Сообщений: 13,345
|
|
23.09.2022, 09:19 | 2 |
0
|
223 / 37 / 4
Регистрация: 18.11.2012
Сообщений: 1,502
|
|
23.09.2022, 09:34 [ТС] | 3 |
Т.е. в данном случает нужно конкретизировать просто SendMessage зло. Получается нужно выбирать SendMessageA?
0
|
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,888
|
|
23.09.2022, 09:35 | 4 |
В какой кодировке ваш исходный текст и в какой вы открываете файл после записи? Не забывайте, что информация о кодировке в файле не хранится, блокнот ее сам угадывает, но вы ему можете указать и другую (хотя именно на счет блокнота не уверен, это все-таки довольно примитивная программа).
Можете просто вывести байты исходной строки и полученного файла в шестнадцатеричном виде и проверить. Тут, увы, помочь не смогу. Если бы код на Си был, был бы шанс. Впрочем, попробую перевести, вдруг да получится... Тут имелось в виду что-то вроде snprintf(sz, 128, "%s", "["); ? А не проще было sz[0]='['; sz[0]=0; ? Или strcpy(sz, "["); , или хотя бы sprintf(sz, "["); Судя по msdn, это извращение - аналог strtok / mbstok / wcstok в зависимости от настроек среды. А что, сразу указать кодировку исходника нельзя? Или вообще пользоваться стандартной utf-8 / ascii? Нормального прототипа для _tcstok_s я не нашел, но если он отображается на wcstok, то последний аргумент это не NextToken, а полуфабрикат строки для извлечения следующих токенов. Не вижу, где оно у вас используется, но название все равно лучше сменить. Э? Тут, наверное, chTmp должен добавляться, а не пустая строка? Хорошее название для кнопки 1. У нее же наверняка есть прототип, где тип возвращаемого значения описан. Хотя если это извращение вроде TCHAR, то, конечно... 2. Вам ничто не мешает вывести шестнадцатеричные коды char'ов оттуда в консоль и проверить.
1
|
223 / 37 / 4
Регистрация: 18.11.2012
Сообщений: 1,502
|
|
23.09.2022, 10:24 [ТС] | 5 |
То что советовали в книгах, так и пишу, а именно, пользоваться функциями и типами из tchar.h, соответственно тип объявляется как TCHAR, открываю Notepad++-ом, кодировка установленная в нём по умолчанию(я так понимаю) ansi. Проекты создаю в Visual studio 2019 с параметрами по умолчанию, в кодировке точно ничего не менял.
Нет, тут 't' это 'a' или 'w' в зависимости от того установлен unicode в системе или нет, во всяком случае я так полагаю. По поводу форматирования строк, с этим спорить не буду наверняка есть более компактные, читабельные, менее ресурсозатратные, но я пока что делаю так, просто так в книге описано) Я так понял, что это для универсальности кода, по крайней мере так у Рихтера написано... Он у меня нигде не используется я вообще полагал, что это пустой аргумент, и без него функция работает. Нет, здесь всё верно, я хочу добавить пробел между словами, если переменная не 0, то добавляю пробел, иначе, пробел добавлять не нужно. ))) Это про пол и не более. Это именно оно. Сейчас в файле кое что стало отображаться в удобочитаемом виде, только после полезных данных идёт мусор. Пробовал добавить в конец завершающий нуль, но это ничего не изменило. Вместо SendMessage(...) использую уточнённый вариант SendMessageW(...) вывожу данные в файл с помощью функции fwrite(). Остальной код как и прежде.
0
|
фрилансер
5499 / 5095 / 1047
Регистрация: 11.10.2019
Сообщений: 13,345
|
|
23.09.2022, 10:26 | 6 |
SendMessage - макрос, раскрывающийся в зависимости от настроек проекта в SendMessageA или SendMessageW
что именно требуется - сам решай
1
|
223 / 37 / 4
Регистрация: 18.11.2012
Сообщений: 1,502
|
||||||
23.09.2022, 11:16 [ТС] | 7 | |||||
А что если так сделать?
Кликните здесь для просмотра всего текста
Так пишет, но правильно ли это в контексте задачи, хотя, с другой стороны это тоже функции WinApi. Добавлено через 2 минуты Это я понял я же выше на этот вопрос ответил. Но всё равно не работает, в смысле уже данные на Русском печатает, но данные выводятся с артифактами т.е. в коне полезных данных идёт хвост мусора. Добавлено через 23 минуты По моему всё работает, а как сделать так чтобы функция WriteFile() дописывала данные в конец файла, а не уничтожала прежнюю информацию? SetEndOfFile() почему то не помогает. С выводом через функции Си всё работает, артефакты более не выводятся. Добавлено через 13 минут Всё, с этим тоже разобрался.
0
|
фрилансер
5499 / 5095 / 1047
Регистрация: 11.10.2019
Сообщений: 13,345
|
||||||
23.09.2022, 11:18 | 8 | |||||
Liss29,
0
|
223 / 37 / 4
Регистрация: 18.11.2012
Сообщений: 1,502
|
|
23.09.2022, 12:03 [ТС] | 9 |
Алексей1153,
Что это?! Я полагал, что смешивать коды Си, С++, WinApi - плохой тон. К тому же тут английские буквы, и я пробовал так писать, но получилось никак, так же, если вводил текст на русском, то в фале ничего не было.
0
|
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,888
|
|
23.09.2022, 12:34 | 10 |
Насколько я понял, оно жестко дефайнится либо в одно, либо в другое в зависимости от того, как у вас настроен компилятор. То есть как оно собралось, так и будет, независимо от того, будете ли вы запускать на других системах. А систем без поддержки юникода сейчас днем с огнем не сыщешь.
Поэтому, на мой взгляд, будет проще сразу пользоваться конкретным вариантом функций и точно знать, что именно используется. Сравните поведение strtok и wcstok. В первом случае этого аргумента нет, и "полупереваренная" строка хранится где-то в недрах библиотеки. Во втором - в вашей переменной. Соответственно первый вариант проще, но второй надежнее. Вдруг вы захотите разложить на токены две строки одновременно. Или просто воспользоваться этой функцией из разных потоков. Но пробела там тоже нет. Наверное, форум сожрал. Это уж вам виднее, ваша ведь задача. Лично я бы не использовал платформо-зависимые функции там, где без этого можно обойтись. То есть для обычных файлов fopen / std::*stream. А вот если хочется странного - работы с блочными устройствами, неблокирующий ввод-вывод и т.д., тогда уже спускаться на уровень операционки. И со строками так же: пока получается обходиться стандартом Си (или С++), лучше так и делать, без всяких strcpy_s и подобных. А когда не получается - оборачивать макросом и описывать явно. Потом, возможно, выносить в слой совместимости. Еще раз предлагаю вывести коды символов, чтобы хоть понятно было кто косячит - компилятор, не записывая что сказано, или просмотровщик, не отображая что записано. Смешивать Си и С++ действительно не стоит. По крайней мере пока не сможете внятно обосновать необходимость этого. Но Алексей1153 ведь и привел только пример, вам ничто не мешает переделать его на fopen / fprintf / fclose. Что до winapi - это ведь не язык как таковой, это набор системных библиотек. Дергать их вы можете из любого языка, хоть из Си, хоть из С++, хоть из Паскаля или Вайтспейса.
0
|
фрилансер
5499 / 5095 / 1047
Регистрация: 11.10.2019
Сообщений: 13,345
|
||||||
23.09.2022, 13:32 | 11 | |||||
Liss29, раздел про C++, при чём тут Си и "смешивать"? Это C++
тогда нужно использовать std::wstring - utf16 Добавлено через 4 минуты только запись будет производиться так
0
|
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,888
|
|
23.09.2022, 14:50 | 12 |
ТС создал тему в подразделе winapi, а не в С++, все правильно. И раз уж начал писать на Си, действительно не стоит смешивать.
Правда, я бы и с нестандартными функциями постарался не смешивать - со всеми этими fopen_s, TCHAR и подобным winapi-шным выносом мозга, когда есть функции из стандарта, которые ничуть не хуже.
1
|
фрилансер
5499 / 5095 / 1047
Регистрация: 11.10.2019
Сообщений: 13,345
|
|
23.09.2022, 15:32 | 13 |
с компилятором для C++ не получится писать на Си Это будет C++, а не Си. Никакого смешивания нету. Берём стандартные классы - и вперёд
моё дело - предложить, а там - ТС пусть сам развлекается и баги в программе городит
1
|
270 / 113 / 18
Регистрация: 26.12.2010
Сообщений: 468
|
|
23.09.2022, 15:43 | 14 |
Писал уже в другой теме, что желательно конкретизировать, A или W функции используете, и будет все хорошо. TCHAR был нужен во времена 98 винды, сейчас то зачем?
Старайтесь всегда использовать юникод, тогда не будет проблем с иероглифами.
1
|
COM‐пропагандист
|
|
23.09.2022, 18:08 | 15 |
Какой‐то бардак из смеси кодировок и функций.
Для начала нужно помнить, что TCHAR и вообще строки существуют только для вызова функций, которые работают со строками. Когда вы записываете данные в файл, про строки следует забыть, потому что в файле хранятся байты. Поэтому чтобы записать байты в файл, вам необходимо все ваши TCHAR и строки преобразовать в массив байт. Обычно для этого используют функцию WideCharToMultiByte. Вы всегда знаете на основании какой кодировки вы преобразуете строку в массив байт. Поэтому первая проблема решена. Когда вы читаете файл, вы не читаете строки, вы читаете массив байт. Теперь вам необходим понять в какой кодировку эти байт. Можно поступить жестоко и считать, что любой такой массив байт — это кодировка UTF-8, 866, 1251, или определить кодировку каким‐либо способом. Затем из эти байты вам необходимо превратить в строку, например, функцией MultiByteToWideChar. Только после этого вы можете работать со строкой. В качестве подсказки иногда текстовые редакторы вставляют байты BOM в начало файла, можете ориентироваться на них. Читаете первые два три байта, если они похожи на одно из представлений BOM, то последующие байты будут в определённой кодировке. И байты BOM не являются валидной строкой, так что их в любом случае придётся пропускать. К кодировке файлов ваших исходных кодов это отношения не имеет.
1
|
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,888
|
|
23.09.2022, 19:43 | 16 |
А кто вам сказал, что у ТСа компилятор плюсов? Я в его коде ничего плюсового не увидел.
Ну и в любом случае "программисты на Фортране могут на любом языке писать на Фортране". Или вообще не заморачиваться с winapi-шными функциями и использовать обычные: char для utf-8. Плюс функции вида mbs*, strcpy, fprintf и т.д. благо большинство ascii-специфичных функций с юникодом работают прекрасно. Да и жесткая юникод-специфика требуется не так уж часто. wchar_t для utf-32 (хотя, кажется, майкрософты это не осилили, у них utf-16), и тогда fwprintf, wcscpy и прочие wcs*. Ну как же не имеет. Попробуйте записать fprintf(file, "Привет мир\n"); из исходника в cp1251, а потом читать как юникод. Это если повезет, и компилятор согласится 1251 собирать.
0
|
фрилансер
5499 / 5095 / 1047
Регистрация: 11.10.2019
Сообщений: 13,345
|
|
23.09.2022, 19:54 | 17 |
0
|
270 / 113 / 18
Регистрация: 26.12.2010
Сообщений: 468
|
|
23.09.2022, 19:59 | 18 |
Это понятно, но что будет с юникодной строкой при вызове lstrcatA ? Зачем вообще усложнять, и потом угадывать , если можно просто юзать юникод? Кому нужен сейчас Анси вариант, мы же не в америке живем, и не в 95 году, чтоб экономить каждый байт..
0
|
223 / 37 / 4
Регистрация: 18.11.2012
Сообщений: 1,502
|
||||||
24.09.2022, 05:55 [ТС] | 19 | |||||
Видишь, как получается, у вас у всех(комментирующих) свои взгляды на каждую тему, на каждый вопрос, а как я могу подстроиться сразу под все ваши взгляды я исхожу из того, что читаю на данный момент, пробую, пробую что-то другое и уже потом стараюсь использовать то или иное. Хотя про UNICODE согласен, тоже самое в своей книге говорит Рихтер.
Т.е. я не правильно использовал функцию, хотя она правильно отработала - это интересно) Я в каком-то примере подсмотрел использование этой функции, потому что не мог понять, зачем этот третий параметр, и в этом примере эта третья переменная тоже не используется. Как это нет, есть, просто его нужно разглядеть) Так то оно так, только, я сейчас WinApi изучаю и там работа, в основном, идёт с функциями WinApi и используются функции Си С++ в книге, которую я сейчас читаю нет, но это и не запрещается. Я же писал, что я использовал std::ifstream С++, но результат был нулевой. В Hiew-е смотрел в Hex режиме в нём тоже показывается бурда, каждый символ занимает один байт так что это ANSI, хотя я об этом говорил, что в Notepad++ установлена кодировка ANSI. Попробовал вывести в файл символы с помощью fputc() получилось следующее: Код
[$8=>35=>2]{C6G8=0}{KAH55}[$8=>35=>2]{C6G8=0}{KAH55}[]{}{} Код
5B42443843D43E43343543D43E4325D7B41C44343644743843D4307D7B41244B4414484354357D Зачем мне переделывать я и так что-то подобное писал изначально. Добавлено через 21 минуту Алексей1153 В настройках же есть опция Компилировать на Си или что-то похожее. А если IsWindowUnicode() использовать для уточнения, нет? Как я понял все эти TCHAR-ы и функции с _t* и вообще подключение заголовочного файла tchat.h это как раз и есть упрощение, нет?! тогда можно писать в начале программы так, как у Рихтера:
Что-то я до конца понять не могу, всё же сейчас лучше с типом char работать или всё писать с типом wchar_t? Добавлено через 14 минут Пробовал, ничего не получилось. Возможно, плохо пробовал.
0
|
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,888
|
|
24.09.2022, 10:54 | 20 |
Не надо подстраиваться. Надо слушать советы и делать выводы. Что-то игнорировать, что-то подсираивать под себя, что-то уточнять.
Да нет, вы угадали с порядком переменных, но NextToken надо бы переименовать. Это если я сам правильно понял, как оно работает. На моноширинном шрифте его трудно не заметить. Плохо помню что такое кодировка ANSI, вроде бы это группа однобайтных кодировок, куда входят и ASCII, и 866, и 1251 и другие. Видимо, я как-то криво скопипастил, поскольку ни во что адекватное оно не расшифровывается: [BD8CФ>C45CФ>C%ЧґD46Dt8CФ0}{A$KDHCT5} Предыдущее ваше "заклинание" я вообще не понял. А зачем? Старые ASCII-функции оставлены только для совместимости с доисторическими системами из прошлого тысячелетия. И не лень столько писать будет? Я не знаю что за книгу вы там читаете (в том смысле, что сам ее не читал), но в Си или С++ так не принято. И даже в winapi с их любовью к длинным именам, я такого не видел. Попробуйте поискать образцы кода, написанные разными людьми. Желательно более-менее свежие. Зависит от того, что вам нужно прямо сейчас. Если просто знакомиться с winapi, то используйте то, что тамошние функции понимают. Если просто ввод-вывод текста без обработки, то utf-8 (char). Ну а если нужна хитрая обработка многоязычных текстов (замена прописных-строчных, проход по буквам, подстроки), то wchar_t. Хотя в винде это не особо поможет, потому что ихний wchar_t вобрал все недостатки utf-8 и utf-32 без видимых преимуществ.
0
|
24.09.2022, 10:54 | |
24.09.2022, 10:54 | |
Помогаю со студенческими работами здесь
20
Не выводится кириллица Не выводится кириллица из БД Не выводится кириллица в консоль Кириллица выводится некорректно Некорректно выводится кириллица Не выводится кириллица в консоль Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |