<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3860570</guid>
        <pubDate>Sun, 06 Mar 2022 13:52:58 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3860570</link>
        <description><![CDATA[Qraizer: memset() после calloc() не нужен.]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3860501</guid>
        <pubDate>Sun, 06 Mar 2022 04:24:30 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3860501</link>
        <description><![CDATA[mkudritsky: Нашел ошибку в приведенных мной примерах функций Utf8ToWin, PrintCons и PrintFile.<br>
Просто мое (полу)хобби - решение комбинаторных задач типа Задачи Коммивояжера.<br>
А ряд этих задач влегкую &quot;съедает&quot; и 8Гб, и 16Гб, и 64Гб, и 128Гб... оперативной памяти.<br>
<br>
То есть для вывода сообщений мне в программах попросту не хватило свободной RAM&#33; :D<br>
Итак, скорректированный код:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// clang -m32 -O3 -lm main.c</div><div class="code_line">// Компиляция: x86_64-w64-mingw32-gcc.exe -m32 -std=c11 -O3 c:\Temp\main.c</div><div class="code_line">// Автономным компилятором в две строки:</div><div class="code_line">// gcc.exe -c -pipe -fno-keep-inline-dllexport -m32 -std=c11 -O3 -Wall -Wextra -DUNICODE -DWINVER -D_USE_MATH_DEFINES c:\Temp\main.c</div><div class="code_line">// gcc.exe -Wl,-s -Wl,-subsystem,console -mthreads main.o -liconv</div><div class="code_line">&nbsp;</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">char *Utf8ToWin(const char *cIn) {</div><div class="code_line">// Преобразование строки cIn из кодировки utf-8 в кодировку cp1251</div><div class="code_line">// При преобразовании длина строки cp1251 не больше исходной длины строки utf-8</div><div class="code_line">// После использования выходной строки ее надо освободить функцией free()</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Длина входной строки (без {text})</div><div class="code_line">&nbsp;&nbsp; &nbsp;size_t iIn = strlen(cIn);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Работа со строками ненулевой длины</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (!iIn)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Открытие преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;iconv_t cd_code = iconv_open(&quot;cp1251&quot;, &quot;utf-8&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Длина выходной строки и статус преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;size_t iOut = iIn, iConv;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Выходная строка, указатель на элементы скрок при преобразовании (входной и выходной)</div><div class="code_line">&nbsp;&nbsp; &nbsp;char* cOut = NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;cOut = (char *)calloc(iOut + 1, sizeof(char));</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (!cOut) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;char *cIn1 = (char *)cIn, *cOut1 = cOut;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Заполнение выходной строки символами конца строки /0</div><div class="code_line">&nbsp;&nbsp; &nbsp;memset(cOut, 0, iOut * sizeof(char));</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Преобразование строки из utf-8 в cp1251</div><div class="code_line">&nbsp;&nbsp; &nbsp;iConv = iconv(cd_code, &amp;cIn1, &amp;iIn, &amp;cOut1, &amp;iOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Закрытие преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;iconv_close(cd_code);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (iConv) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (cOut) free(cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL; // Если было хотя бы одно неудачное преобразование</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Вывод результата</div><div class="code_line">&nbsp;&nbsp; &nbsp;return cOut;</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">// Вывод содержимого строки sOut на консоль вне зависимости от OS</div><div class="code_line">void PrintCons(const char* cIn) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;char* cOut = NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cSl == &#39;/&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cOut = (char *)cIn; &nbsp; &nbsp;// Linux</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cOut = Utf8ToWin(cIn); // Windows</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cOut) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;printf(&quot;%s&quot;, cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (cSl != &#39;/&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;free(cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;} else {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;printf(&quot;PrintCons: error convert string!\n&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;return;</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">// Вывод содержимого строки cIn в файл в кодировке cp1251</div><div class="code_line">void PrintFile(FILE *fOut, const char* cIn) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;char* cOut = NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;cOut = Utf8ToWin(cIn);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cOut) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fprintf(fOut, &quot;%s&quot;, cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;free(cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;return;</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script>]]></description>
        <author>mkudritsky</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3859037</guid>
        <pubDate>Sat, 12 Feb 2022 04:40:37 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3859037</link>
        <description><![CDATA[mkudritsky: Народ, добрый день&#33;<br>
Наконец-то я победил этот злосчастный модуль iconv<br>
Теперь можно писать универсальные программы в кодировке UTF8, а вывод (консоль, файл) осуществлять либо в CP1251 (Windows), либо в UTF8 (Linux).<br>
Управление при компиляции - макрос WINVER (ключ компилятора -DWINVER).<br>
<br>
Корень проблемы - ошибки в компиляторе mingw64, которые, увы, все еще не исправлены.<br>
Как надо правильно компилировать - подсмотрел в консоли сборки Qt (где все нормально собирается с модулем iconv).<br>
Собирать все можно и в Си, и в C++.<br>
<br>
Итак, вот мой пример программы &quot;Hello world&quot; где есть все нужные функции (даже лишние):<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Компиляция:</div><div class="code_line">// x86_64-w64-mingw32-gcc.exe -m64 -std=c11 -O3 -DWINVER c:\Tmp\main.c</div><div class="code_line">// clang -m64 -std=c11 -O3 main.c</div><div class="code_line">// С модулем iconv</div><div class="code_line">// x86_64-w64-mingw32-gcc.exe -c -pipe -fno-keep-inline-dllexport -D_USE_MATH_DEFINES -m64 -std=c11 -O3 -Wall -Wextra -DUNICODE -DWINVER c:\Tmp\main.c</div><div class="code_line">// x86_64-w64-mingw32-gcc.exe -Wl,-s -Wl,-subsystem,console -mthreads main.o -liconv</div><div class="code_line">#include &#60;stdio.h&#62;</div><div class="code_line">#include &#60;stdlib.h&#62;</div><div class="code_line">#include &#60;time.h&#62;</div><div class="code_line">#include &#60;locale.h&#62;</div><div class="code_line">#include &#60;math.h&#62;</div><div class="code_line">#include &#60;string.h&#62;</div><div class="code_line">#include &#60;iconv.h&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">#ifndef WINVER</div><div class="code_line">char cSl = &#39;/&#39;;</div><div class="code_line">#else</div><div class="code_line">char cSl = &#39;\&#39;;</div><div class="code_line">#endif</div><div class="code_line">&nbsp;</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">int iRand() {</div><div class="code_line">// Аналог rand() для юродиевых версий &quot;любимой&quot; Windows, где RAND_MAX=32767</div><div class="code_line">&nbsp;&nbsp; int iR = rand();</div><div class="code_line">&nbsp;&nbsp; if ( RAND_MAX == 32767 ) { // 32767=2**15-1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;iR &#60;&#60;= 15; // iR = iR*32768 (32768=2**15)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;int iL = rand();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;iR |= iL; // iR = rand()*(2**15)+rand;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp; return iR;</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">int iRandom(int iMin, int iMax) {</div><div class="code_line">// Возвращает случайное целое число между iMin и iMax. Границы могут генерироваться</div><div class="code_line">&nbsp;&nbsp; if (iMin &#60; iMax)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return iMin + iRand() % (iMax - iMin + 1);</div><div class="code_line">&nbsp;&nbsp; else if ( iMin == iMax )</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return iMin;</div><div class="code_line">&nbsp;&nbsp; else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return iMin - 1; // Если границы заданы неверно, то возвращается такое число</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">double dbRandom(double dbMin, double dbMax) {</div><div class="code_line">// Возвращает случайное вещественное число между dbMin и dbMax. Границы могут генерироваться</div><div class="code_line">&nbsp;&nbsp; if (dbMin &#60; dbMax) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if (RAND_MAX == 32767)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; return dbMin + ((dbMax - dbMin) * (double)iRand()) / 1073741823.0; // = double(2**30-1)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; return dbMin + ((dbMax - dbMin) * (double)iRand()) / (double)RAND_MAX;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp; else if (dbMin == dbMax)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return dbMin;</div><div class="code_line">&nbsp;&nbsp; else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return dbMin - 1.0;</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">char *Utf8ToWin(const char *cIn) {</div><div class="code_line">// Преобразование строки cIn из кодировки utf-8 в кодировку cp1251</div><div class="code_line">// При преобразовании длина строки cp1251 не больше исходной длины строки utf-8</div><div class="code_line">// После использования выходной строки ее надо освободить функцией free()</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Длина входной строки (без {text})</div><div class="code_line">&nbsp;&nbsp; &nbsp;size_t iIn = strlen(cIn);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Работа со строками ненулевой длины</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (!iIn)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Открытие преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;iconv_t cd_code = iconv_open(&quot;cp1251&quot;, &quot;utf-8&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Длина выходной строки и статус преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;size_t iOut = iIn, iConv;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Выходная строка, указатель на элементы скрок при преобразовании (входной и выходной)</div><div class="code_line">&nbsp;&nbsp; &nbsp;char *cOut = (char *)calloc(iOut + 1, sizeof(char)), *cIn1 = (char *)cIn, *cOut1 = cOut;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Заполнение выходной строки символами конца строки /0</div><div class="code_line">&nbsp;&nbsp; &nbsp;memset(cOut, 0, iOut * sizeof(char));</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Преобразование строки из utf-8 в cp1251</div><div class="code_line">&nbsp;&nbsp; &nbsp;iConv = iconv(cd_code, &amp;cIn1, &amp;iIn, &amp;cOut1, &amp;iOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Закрытие преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;iconv_close(cd_code);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (iConv) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (cOut) free(cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL; // Если было хотя бы одно неудачное преобразование</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Вывод результата</div><div class="code_line">&nbsp;&nbsp; &nbsp;return cOut;</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">// Вывод содержимого строки sOut на консоль вне зависимости от OS</div><div class="code_line">void PrintCons(const char* cIn) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;char* cOut;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cSl == &#39;/&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cOut = (char *)cIn; &nbsp; &nbsp;// Linux</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cOut = Utf8ToWin(cIn); // Windows</div><div class="code_line">&nbsp;&nbsp; &nbsp;printf(&quot;%s&quot;, cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cOut &amp;&amp; (cSl != &#39;/&#39;))</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;free(cOut);</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">// Вывод содержимого строки cIn в файл в кодировке cp1251</div><div class="code_line">void PrintFile(FILE *fOut, const char* cIn) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;char* cOut;</div><div class="code_line">&nbsp;&nbsp; &nbsp;cOut = Utf8ToWin(cIn);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cOut) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fprintf(fOut, &quot;%s&quot;, cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;free(cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">int main(int argc, char *argv[]) {</div><div class="code_line">&nbsp;&nbsp; // Файл для вывода сообщения в CP1251</div><div class="code_line">&nbsp;&nbsp; FILE *Fdat;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // Переключение локали для вывода кирилицы в терминальном окне</div><div class="code_line">&nbsp;&nbsp; setlocale(LC_CTYPE, &quot;&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // Открытие файла или создание нового файла</div><div class="code_line">&nbsp;&nbsp; if ((Fdat = fopen(&quot;test.txt&quot;, &quot;wt&quot;)) == NULL) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; PrintCons(&quot;Файл не удается открыть\n&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; return -1;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // Начало работы программы. Вывод начального сообщения</div><div class="code_line">&nbsp;&nbsp; PrintCons(&quot;Приветствие! Запись сообщения в файл test.txt\n&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // Запись сообщения в файл в кодировке CP1251</div><div class="code_line">&nbsp;&nbsp; PrintFile(Fdat, &quot;Приветствие! Запись сообщения в файл test.txt\n&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // Закрытие файла</div><div class="code_line">&nbsp;&nbsp; fclose(Fdat);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // Окончание работы программы</div><div class="code_line">&nbsp;&nbsp; PrintCons(&quot;Программа завершена!\n&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; return 0;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Увы, в Windows компиляция получилась &quot;двухэтажной&quot;. Одной строкой exe-шник мне собрать не удалось.<br>
Ну а в Linux все гораздо проще - все собирается без танцев с бубном либо в gcc, либо в clang одной строкой.<br>
<br>
P.S. Я не шибко искушен в C/C++ и посему почти уверен - из строк компиляции можно выкинуть половину ключей, а то и объединить две строки в одну.<br>
Может даже получится убрать статическую библиотеку и заменить ее на динамическую.<br>
Также просьба посмотреть на функции Utf8ToWin, PrintCons, PrintFile - может грубые ошибки есть?]]></description>
        <author>mkudritsky</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3851333</guid>
        <pubDate>Thu, 26 Aug 2021 12:32:10 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3851333</link>
        <description><![CDATA[ЫукпШ: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=422452&view=findpost&p=3850916'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>mkudritsky &#064; <time class="tag-quote__quoted-time" datetime="2021-08-14T12:53:59+00:00">14.08.21, 12:53</time></span><div class='quote '>Проблема состоит в том, что 64bit компилятор TDM-GCC-64 не понимает, что такое модуль iconv.h, несмотря на присутствие библиотеки libiconv-2.dll<br>
Найденных в сети советов немного и они не работают.</div></div><br>
у тебя преобразователь для вывода в консоль не работает и всё ?<br>
Если так, можно попробовать сделать условную компиляцию <br>
и преобразовать строки по-разному для Виндус и Linux.<br>
У Виндуса есть функции:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;::WideCharToMultiByte(...); </div><div class="code_line">&nbsp;::MultiByteToWideChar(...);</div></ol></div></div></div></div><br>
И ещё есть:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">::OemToCharBuff(...);</div><div class="code_line">::CharToOemBuff(...);</div></ol></div></div></div></div><br>
<br>
Используя эти функции можно делать необходимые преобразования<br>
кодировок UTF-8, CP1251, OEM, UTF-16.<br>
---<br>
Основная твоя система, как я понял, Linux.<br>
Пусть все строки будут в UTF-8.<br>
Т.е. для вывода в консоль Виндуса надо сделать дополнительный<br>
преобразователь UTF-8 -&gt; OEM.<br>
И всё.]]></description>
        <author>ЫукпШ</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3851248</guid>
        <pubDate>Tue, 24 Aug 2021 03:56:41 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3851248</link>
        <description><![CDATA[mkudritsky: Еще немного поковырялся со всем этим хозяйством.<br>
У меня сложилось мнение, что компилятор tdm64-gcc-10.3.0.exe является выжимкой от проекта:<br>
<a class='tag-url' href='http://mingw-w64.org' target='_blank'>http://mingw-w64.org</a><br>
или сразу в загрузки<br>
<a class='tag-url' href='https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/' target='_blank'>https://sourceforge.net/projects/mingw-w64/...gw-w64-release/</a><br>
<br>
Короче: снес я TDM64 и установил mingw-w64.<br>
(Кстати, они конфликтуют друг с другом и мне удалось поставить только по принципу &quot;или или&quot;).<br>
В mingw-w64 изначально модуль iconv есть.<br>
Правда, это не спасает ситуацию:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">c:\Temp&#62;gcc.exe -D_USE_MATH_DEFINES -m64 -std=c11 -O3 -liconv main.c</div><div class="code_line">c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw3</div><div class="code_line">2/lib/../lib/libiconv.a(localcharset.o):localcharset.c:(.text+0x63): undefined </div><div class="code_line">reference to `__imp_GetACP&#39;</div><div class="code_line">collect2.exe: error: ld returned 1 exit status</div></ol></div></div></div></div><br>
Проблема давнишняя, как я понял из поиска в Интернете, и решения пока не имеет.<br>
<br>
Попутно замечу, что помимо нерабочего iconv тут еще и не все макросы работают.<br>
Например, для M_PI и M_PI_2 пришлось при компиляции использовать -D_USE_MATH_DEFINES<br>
Что крайне удивительно: в Qt используется тот же самый mingw и нет никаких проблем ни с iconv, ни с M_PI<br>
<br>
В общем, всем спасибо за советы.<br>
Но пока, видимо, придется компилировать по-старинке, меняя кодировку программ из utf-8 в cp1251 и обратно.<br>
Или использовать code page 65001.]]></description>
        <author>mkudritsky</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850956</guid>
        <pubDate>Sun, 15 Aug 2021 16:38:29 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850956</link>
        <description><![CDATA[amk: Юникод в консоли поддерживает уже XP. Но только UCS-2.]]></description>
        <author>amk</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850939</guid>
        <pubDate>Sun, 15 Aug 2021 09:20:27 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850939</link>
        <description><![CDATA[Qraizer: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=422452&view=findpost&p=3850928'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>korvin &#064; <time class="tag-quote__quoted-time" datetime="2021-08-14T17:41:16+00:00">14.08.21, 17:41</time></span><div class='quote '>Разве? Вроде ещё в WinXP можно было, нужно было только шрифт сменить с дефолтного на Lucida.</div></div>Шрифт не проблема, проблема – UTF-8 страница. Не уверен, но вроде бы даже 7-ка не поддерживала юникод в консоли. <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2021-08-15T09:30:31+00:00">15.08.21, 09:30</time></span></span><br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=422452&view=findpost&p=3850934'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>mkudritsky &#064; <time class="tag-quote__quoted-time" datetime="2021-08-15T03:23:35+00:00">15.08.21, 03:23</time></span><div class='quote '>А может помимо<br>
tdm64-gcc-10.3.0.exe<br>
есть еще какие-нибудь 64bit компиляторы C/C++ для Windows?</div></div>Если тебе Qt, то вариантов в общем-то и нет. В целом же компиляторов вагон, та же Visual Studio без проблем компилит, причём не знаю как сейчас, но ещё недавно это был единственный компилятор, полностью поддерживающий C++20 на уровне языка и библиотеки.<br>
Что да iconv, то его базовый функционал покрывается стандартными средствами C++. Но нельзя отрицать, что пользоваться iconv несколько удобнее, и возможностей там поболе. + поддержка чистого C. Впрочем, для Qt по любому C++ потребуется.]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850934</guid>
        <pubDate>Sun, 15 Aug 2021 03:23:35 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850934</link>
        <description><![CDATA[mkudritsky: Господа, спасибо за советы&#33;<br>
Надо бы разобраться в кодовой странице 65001 и как ее использовать в программе C/C++.<br>
Займусь этим&#33;<br>
<br>
Но вопрос про терминал я задал просто для сокращения своего поста.<br>
Тут на самом деле в ряде консольных программ помимо терминала еще есть требование выводить результаты в текстовые файлы в кодировке только CP1251 и в Linux, и в Windows.<br>
И использование iconv.h мне показалось самым элегантным. <br>
<br>
А может помимо<br>
tdm64-gcc-10.3.0.exe<br>
есть еще какие-нибудь 64bit компиляторы C/C++ для Windows?<br>
Может в этих альтернативных компиляторах есть нормальный модуль iconv.h?<br>
Кстати, мне еще не понравилось, что tdm64 не знает макроса WINVER, а я его использую для выяснения среды исполнения программы (Linux или Windows) и приходится использовать:<br>
-DWINVER<br>
<br>
P.S. На всякий случай приведу код, который использую для вывода в консоль кирилицы (для вывода в txt-файлы кириллицы в CP1251 позже приведу):<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#include &#60;string.h&#62;</div><div class="code_line">#ifndef WINVER</div><div class="code_line">#include &#60;sys/sysinfo.h&#62;</div><div class="code_line">#else</div><div class="code_line">#include &#60;sysinfoapi.h&#62;</div><div class="code_line">#endif</div><div class="code_line">#include &#60;locale.h&#62;</div><div class="code_line">#include &#60;iconv.h&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">// Информация об основных параметрах ОС (главным образом - RAM)</div><div class="code_line">#ifndef WINVER</div><div class="code_line">struct sysinfo osInfo;</div><div class="code_line">char cSl = &#39;/&#39;;</div><div class="code_line">#else</div><div class="code_line">MEMORYSTATUSEX osInfo;</div><div class="code_line">char cSl = &#39;\&#39;;</div><div class="code_line">#endif</div><div class="code_line">&nbsp;</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">char *Utf8ToWin(const char *cIn) {</div><div class="code_line">// Преобразование строки cIn из кодировки utf-8 в кодировку cp1251</div><div class="code_line">// При преобразовании длина строки cp1251 не больше исходной длины строки utf-8</div><div class="code_line">// После использования выходной строки ее надо освободить функцией free()</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Длина входной строки (без {text})</div><div class="code_line">&nbsp;&nbsp; &nbsp;size_t iIn = strlen(cIn);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Работа со строками ненулевой длины</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (!iIn)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Открытие преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;iconv_t cd_code = iconv_open(&quot;cp1251&quot;, &quot;utf-8&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Длина выходной строки и статус преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;size_t iOut = iIn, iConv;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Выходная строка, указатель на элементы скрок при преобразовании (входной и выходной)</div><div class="code_line">&nbsp;&nbsp; &nbsp;char *cOut = (char *)calloc(iOut + 1, sizeof(char)), *cIn1 = (char *)cIn, *cOut1 = cOut;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Заполнение выходной строки символами конца строки /0</div><div class="code_line">&nbsp;&nbsp; &nbsp;memset(cOut, 0, iOut * sizeof(char));</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Преобразование строки из utf-8 в cp1251</div><div class="code_line">&nbsp;&nbsp; &nbsp;iConv = iconv(cd_code, &amp;cIn1, &amp;iIn, &amp;cOut1, &amp;iOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Закрытие преобразования</div><div class="code_line">&nbsp;&nbsp; &nbsp;iconv_close(cd_code);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (iConv) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (cOut) free(cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return NULL; // Если было хотя бы одно неудачное преобразование</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Вывод результата</div><div class="code_line">&nbsp;&nbsp; &nbsp;return cOut;</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">// Вывод содержимого строки sOut на консоль вне зависимости от OS</div><div class="code_line">void PrintCons(const char* cIn) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;char* cOut;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cSl == &#39;/&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cOut = (char *)cIn; &nbsp; &nbsp;// Linux</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cOut = Utf8ToWin(cIn); // Windows</div><div class="code_line">&nbsp;&nbsp; &nbsp;printf(&quot;%s&quot;, cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cOut &amp;&amp; (cSl != &#39;/&#39;))</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;free(cOut);</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">// Вывод содержимого строки cIn в файл в кодировке cp1251</div><div class="code_line">void PrintFile(FILE *fOut, const char* cIn) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;char* cOut;</div><div class="code_line">&nbsp;&nbsp; &nbsp;cOut = Utf8ToWin(cIn);</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (cOut) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fprintf(fOut, &quot;%s&quot;, cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;free(cOut);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">//---------------------------------------------------------------------------</div></ol></div></div></div></div>]]></description>
        <author>mkudritsky</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850928</guid>
        <pubDate>Sat, 14 Aug 2021 17:41:16 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850928</link>
        <description><![CDATA[korvin: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=422452&view=findpost&p=3850925'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Qraizer &#064; <time class="tag-quote__quoted-time" datetime="2021-08-14T15:15:52+00:00">14.08.21, 15:15</time></span><div class='quote '>Не проще ль в консоли поставить 65001 кодовую страницу? Работать будет только с 10-ки, правда.</div></div><br>
Разве? Вроде ещё в WinXP можно было, нужно было только шрифт сменить с дефолтного на Lucida.]]></description>
        <author>korvin</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850925</guid>
        <pubDate>Sat, 14 Aug 2021 15:15:52 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850925</link>
        <description><![CDATA[Qraizer: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=422452&view=findpost&p=3850916'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>mkudritsky &#064; <time class="tag-quote__quoted-time" datetime="2021-08-14T12:53:59+00:00">14.08.21, 12:53</time></span><div class='quote '>Устав пересохранять код программ то в UTF-8, то в CP1251, решил сделать универсальный код с использованием модуля iconv.h</div></div>Не проще ль в консоли поставить 65001 кодовую страницу? Работать будет только с 10-ки, правда. И консольного шрифта с полной поддержкой юникода, насколько мне известно, не существует, но для подмножества символов из общего набора в UTF-8 и ANSI-1251 это не проблема. <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2021-08-14T15:19:24+00:00">14.08.21, 15:19</time></span></span><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">std::cout &#60;&#60; u8&quot;Это строка в UTF8&quot;;</div></ol></div></div></div></div><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">D:\Work\DelMe&#62;chcp 65001</div><div class="code_line">Active code page: 65001</div><div class="code_line">&nbsp;</div><div class="code_line">D:\Work\DelMe&#62;a</div><div class="code_line">Это строка в UTF8</div><div class="code_line">D:\Work\DelMe&#62;</div></ol></div></div></div></div>]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850916</guid>
        <pubDate>Sat, 14 Aug 2021 12:53:59 +0000</pubDate>
        <title>TDM-GCC-64 и iconv в Windows</title>
        <link>https://forum.sources.ru/index.php?showtopic=422452&amp;view=findpost&amp;p=3850916</link>
        <description><![CDATA[mkudritsky: Создаю консольные прикладные программы в Linux и в Windows (32bit, 64bit).<br>
Основная рабочая среда - Qt и Linux (32bit, 64bit). Соответственно кириллица набирается и выводится в UTF-8.<br>
<br>
Проблема состоит в том, что часто созданные программы приходится использовать и в Windows (32bit, 64bit).<br>
Устав пересохранять код программ то в UTF-8, то в CP1251, решил сделать универсальный код с использованием модуля iconv.h<br>
<br>
Проблема решилась но только для Windows 32bit.<br>
Для Windows 64bit к моему большому удивлению нет готового дистрибутива Qt со всеми необходимыми программами - надо чуть ли не руками все до копейки собирать.<br>
Моей квалификации здесь не хватает, а 64bit программы нужны, т.к. могут использовать в работе RAM и 8Гб, и 16Гб, и 32Гб (комбинаторные задачи).<br>
<br>
Тактику выбрал такую: отлаживаю код в Windows Qt 32bit и потом уже отлаженный код компилирую и собираю в<br>
tdm64-gcc-10.3.0.exe<br>
Команда для сборки в консоли такая:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">c:\TDM-GCC-64\bin\x86_64-w64-mingw32-gcc.exe -m64 -std=c11 -O3 c:\Proj\Task\main.c</div></ol></div></div></div></div><br>
<br>
Проблема состоит в том, что 64bit компилятор TDM-GCC-64 не понимает, что такое модуль iconv.h, несмотря на присутствие библиотеки libiconv-2.dll<br>
Найденных в сети советов немного и они не работают.<br>
Может кто сталкивался и знает решение проблемы?<br>
<br>
P.S. В Linux нет никаких проблем и с командной строкой. Все отлично компилируется командой<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">clang -m64 -std=c11 -O3 /home/user/Proj/Task/main.c</div></ol></div></div></div></div>]]></description>
        <author>mkudritsky</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	