Ошибки, баги, вопросы - страница 3416

 
Yuriy Vasilyev #:


Проблема может быть связана с тем, что в MetaEditor (который, вероятно, используется для написания торговых советников на платформе MetaTrader) функция FileWriteString с параметром FILE_WRITE|FILE_UNICODE|FILE_TXT использует UTF-16 кодировку, как вы правильно заметили.

Если вы хотите записать файл в формате UTF-8, вам следует использовать параметры FILE_WRITE|FILE_ANSI|FILE_TXT и просто убедиться, что ваш текст предварительно преобразован в UTF-8. В вашем первом примере кода, убедитесь, что ваш текст сохранен в кодировке UTF-8. Вот исправленный фрагмент кода:

c Copy code
void OnStart() { int file = FileOpen("1_testfile_rus.txt", FILE_WRITE|FILE_ANSI|FILE_TXT, "", CP_UTF8); if(file != INVALID_HANDLE) { ResetLastError(); Print(FileWriteString(file, "Русский текст!")," ", GetLastError()); // 0 0 FileClose(file); } }

Убедитесь, что ваш редактор текста сохраняет файл в UTF-8 перед его запуском.

Файл сохранён в UTF-8.

Независимо от того, запускаю я ME5 и MT5 в локали ru_RU.CP1251 или ru_RU.UTF-8,

Print(IntegerToString(TerminalInfoInteger(TERMINAL_CODEPAGE)));

пишет 1251 и в файл пишет в CP1251, если указать только FILE_ANSI и не указывать CP_UTF8.

Если указать и FILE_ANSI, и CP_UTF8, получаем файл нулевой длины и не получаем кода ошибки.

2023.11.13 15:28:57.707 Terminal        MetaTrader 5 x64 build 4052 started for MetaQuotes Software Corp.
2023.11.13 15:28:57.707 Terminal        Windows 11 build 22000 on Wine 8.19 Linux 6.1.0-13-amd64, 1 x Intel Xeon E312xx (Sandy Bridge), AVX, 1 / 1 Gb memory, 34 / 39 Gb disk, GMT+3

и для

2023.11.07 13:26:45.103 Terminal        Открытие Брокер x64 build 3802 started for АО ''Открытие Брокер''
2023.11.07 13:26:45.104 Terminal        Windows 10 build 18362 on Wine 8.5 Linux 5.4.0-109-generic, 3 x Intel Xeon E312xx (Sandy Bridge), AVX, 4 / 5 Gb memory, 0 / 29 Gb disk, GMT+3

поведение такое же.

 
JRandomTrader #:

Под Wine файлы в UTF-8 не пишутся. Файл нулевой длины, и ошибки тоже нет.

Если сделать так

пишется в UTF-16

это copy-paste исходника или вы по памяти перепечатали ?

просто там ошибки

 
Maxim Kuznetsov #:

это copy-paste исходника или вы по памяти перепечатали ?

просто там ошибки

Это демонстрационный пример, только закомментированные строки выкинул.

Какие ошибки?

 
JRandomTrader #:

Это демонстрационный пример, только закомментированные строки выкинул.

Какие ошибки?

FileOpen("1_testfile_rus.txt", FILE_WRITE|FILE_UNICODE|FILE_TXT, "", CP_UTF8);

компилятор вам про это наверняка сказал - там не строка передаётся а 1 символ

должно быть :

FileOpen("1_testfile_rus.txt", FILE_WRITE|FILE_UNICODE|FILE_TXT, 
',' , CP_UTF8);

какой именно символ всё равно пока нет флага FILE_CSV

PS/ вы на С/C++ не писали очевидно ? это вредные ошибки, размерность съехала

 
Maxim Kuznetsov #:

компилятор вам про это наверняка сказал - там не строка передаётся а 1 символ

должно быть :

какой именно символ всё равно пока нет флага FILE_CSV

PS/ вы на С/C++ не писали очевидно ? это вредные ошибки, размерность съехала

Да, спасибо, не заметил. Даже в тех закомментированных строчках '\t' было.

Компилятор не ругался, странно.

Но на результат не влияет, UTF-8 всё равно не пишется, только или UTF-16, или CP-1251. И ошибку не выдаёт, просто 0 символов записано.

На С/C++ - мало и давно, ещё под MS-DOS.

 
JRandomTrader #:

Да, спасибо, не заметил. Даже в тех закомментированных строчках '\t' было.

Компилятор не ругался, странно.

Но на результат не влияет, UTF-8 всё равно не пишется, только или UTF-16, или CP-1251. И ошибку не выдаёт, просто 0 символов записано.

На С/C++ - мало и давно, ещё под MS-DOS.

и ещё флаг FILE_ANSI нужен, а FILE_UNICODE нет :-)

цитирую доки

FILE_UNICODE

64

Strings of UNICODE type (two byte symbols).


а UTF-8 - однобайтная кодировка :-)

 
Maxim Kuznetsov #:

и ещё флаг FILE_ANSI нужен, а FILE_UNICODE нет :-)

цитирую доки

FILE_UNICODE

64

Strings of UNICODE type (two byte symbols).


а UTF-8 - однобайтная кодировка :-)

Что FILE_UNICODE не нужен - это понятно, просто показвыаю, что и с ним не работает.

Насчёт однобайтной - очень и очень спорно )

Да и насчёт двухбайтной - как бы тоже )

 
JRandomTrader #:

Что FILE_UNICODE не нужен - это понятно, просто показвыаю, что и с ним не работает.

Насчёт однобайтной - очень и очень спорно )

Да и насчёт двухбайтной - как бы тоже )

вот магическое сочетание флагов, которые я использую :

int f=FileOpen(fileName,FILE_WRITE|FILE_SHARE_READ|FILE_TXT|FILE_ANSI,',',CP_UTF8);      

FILE_TXT - говорит что это текст, FILE_ANSI - что однобайт, CP_UTF8 - предпочитаемая мной кодировка.

 
Maxim Kuznetsov #:

вот магическое сочетание флагов, которые я использую :

int f=FileOpen(fileName,FILE_WRITE|FILE_SHARE_READ|FILE_TXT|FILE_ANSI,',',CP_UTF8);      

FILE_TXT - говорит что это текст, FILE_ANSI - что однобайт, CP_UTF8 - предпочитаемая мной кодировка.

Это всё понятно. Но! Это под виндой или под Wine? Что оно под виндой работает, я верю. А вот под Линуксом - не удалось заставить.

Возможно, какого-то пакета не хватает, у меня всё по минимуму стоит.
 
JRandomTrader #:

под Линуксом - не удалось заставить.

MT4 и MT5 не работают одинаково с FileWriteString. Как пример, пришлось такой способ конвертации MT4->MT5 использовать, чтобы MT5 выдавал тот же результат, что и MT4.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Скрипты: StatsHTML

fxsaber, 2023.11.02 09:35

int FileOpen2( const string FileName, const int Flags )
{
  return(FileOpen(FileName, Flags | (!(Flags & FILE_BIN) ? FILE_ANSI : 0)));
}

#define FileOpen FileOpen2

Однако, мне сразу стало понятно, в чем проблема, и быстро написал это. В ином же случае можно просто перебрать все возможные комбинации флагов. По комбинаторике их немного.

Возможно, имеет смысл проверить на линуксе MT4, а потом уже искать решение под MT5.