FileIsLineEnding - баг - нет отработки

 

Всем доброго
Добрался я на днях до работы с csv файлами и наткнулся на то, что функция FileIsLineEnding хоть лопни но не видит конца строки!
Тестовый код:

void CsvArray( string &Line[255][9] )

{
    string nameFile = "Calendar-08-10-2014.csv";
    int CurRow = 0, CurCol, lineSize = 8;
    int handle = FileOpen( nameFile, FILE_CSV | FILE_READ | FILE_ANSI, "," );
    if( handle != INVALID_HANDLE )
    {
      while( !FileIsEnding( handle ) )

      {

         CurCol = 0;

         while( !FileIsEnding( handle ) || !FileIsLineEnding( handle ) )   // Как должно быть - но не работает !
        // while( !FileIsEnding( handle ) || !FileIsLineEnding( handle ) ||  CurCol <= lineSize ) // А вот так отрабатывает, то есть функция !FileIsLineEnding( handle ) не отлавливает конец строки !!!
         {
           Print( "Row = ", CurRow,", Col = ", CurCol );
           Line[ CurRow ][ CurCol ] = FileReadString( handle );
           CurCol++;
         }
         CurRow++;
      }
    FileClose( handle );
    }
    else Alert( "Файл ", nameFile, " не обнаружен, последняя ошибка ", GetLastError() );
}


В роли файла выступил http://www.dailyfx.com/files/Calendar-08-10-2014.csv

Если указать принудительно ограничение в 9 столбцов в цикле чтения данных, то код отрабатывает.

НО даже при этом файл считывается начиная с 112 строчки !!!!!!!!!!:

2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 114, Col = 0 ,Val=Thu Aug 14
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 8 ,Val=0.1%
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 7 ,Val=-0.4%
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 6 ,Val=
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 5 ,Val=Low
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 4 ,Val=USD Import Price Index (MoM)
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 3 ,Val=USD
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 2 ,Val=GMT
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 1 ,Val=12:30
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 113, Col = 0 ,Val=Thu Aug 14
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 112, Col = 8 ,Val=0.9%
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 112, Col = 7 ,Val=
2014.08.11 11:54:59.942    Test EURUSD,H1: Row = 112, Col = 6 ,Val=
2014.08.11 11:53:59.936    Test EURUSD,H1: initialized
2014.08.11 11:53:58.839    Expert Test EURUSD,H1: loaded successfully


Похоже что все что связанно с чтением csv файла ВООБЩЕ, работает через заднее место!

А если сделать как положено, то есть в текущем виде по отработке функции FileIsLineEnding - то проскакивает мимо конца строки и перебирает следующие строки файла.

( MetaTrader4 v4.00 build 670 от 04.07.2014 )

Замена второго цикла на: while( !FileIsLineEnding( handle )  ) вообще не отрабатывает, после такой строчки цикла код в теле цикла вообще не отрабатывает, причем на таком цикле MT4  просто уходит в ступор !

Если циклы привести к такому виду, то считываются первая строчка csv файла и на отработке кода EndOfLine = FileIsLineEnding( handle );  MT4 уходит в даун:


int CurRow = 0, CurCol, lineSize = 8;
      bool EndOfLine = False;
      while( !FileIsEnding( handle ) )
      {
         CurCol = 0;
         while( !EndOfLine )
         {
           Line[ CurRow ][ CurCol ] = FileReadString( handle );
           Print( "Row = ", CurRow,", Col = ", CurCol, " ,Val=", Line[ CurRow ][ CurCol ] );
           CurCol++;
           EndOfLine = FileIsLineEnding( handle );
         }
         CurRow++;

      }


2014.08.11 12:12:58.303    Abnormal termination
2014.08.11 12:12:48.293    Test EURUSD,H1: shutdown by timeout
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 8 ,Val=Previous
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 7 ,Val=Forecast
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 6 ,Val=Actual
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 5 ,Val=Importance
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 4 ,Val=Event
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 3 ,Val=Currency
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 2 ,Val=Time Zone
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 1 ,Val=Time
2014.08.11 12:12:07.997    Test EURUSD,H1: Row = 0, Col = 0 ,Val=Date
2014.08.11 12:12:07.997    Test EURUSD,H1: Start
2014.08.11 12:11:07.992    Test EURUSD,H1: initialized

 
Пожалуйста вставляйте код правильно: Правильно вставляем код на форуме
 

tnx за подсказку, я пытаюсь на ходу методом перебора вариантов найти первоисточник проблемы, что бы все могли сразу увидеть ход моих вариантов.

На текущий момент ожидаю ответа от разработчиков MT4 по зависанию MT4 при отработке EndOfLine = FileIsLineEnding( handle ); в отдельной строке.

Судя по всему функция FileIsLineEnding() на текущий момент не работает.

Так же похоже есть проблемы с другими функциями при работе с csv файлом, по крайней мере в режиме чтения.

Как вариант я могу предположить проблему в разнице символов окончания строк в Unix и Windows системах, но это только мое предположение.

Так что надеюсь увидеть ответ от разработчиков по этому поводу.

Заранее спасибо


Полная версия кода поиска ошибки на текущий момент:

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict

void CsvArray(string nameFile, string &Line[255][9])
{
    int handle = FileOpen( nameFile, FILE_CSV|FILE_READ|FILE_ANSI, "," );
    if( handle != INVALID_HANDLE )
    {
      int CurRow = 0, CurCol, lineSize = 8;
      bool EndOfLine = False;
      while( !FileIsEnding( handle ) )
      {
         CurCol = 0;
         while( !EndOfLine )
         {
           Line[ CurRow ][ CurCol ] = FileReadString( handle );
           Print( "Row = ", CurRow,", Col = ", CurCol, " ,Val=", Line[ CurRow ][ CurCol ] );
           CurCol++;
           EndOfLine = FileIsLineEnding( handle );
         }
         CurRow++;
      }
      FileClose( handle );
    }
    else Alert( "Файл ", nameFile, " не обнаружен, последняя ошибка ", GetLastError() );
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(60);
      
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
    Print( "Start" );
    string NameFile = "Calendar-08-10-2014.csv";
    if( !FileIsExist( NameFile ) ) { Print( "===== Файл календаря не найден ! =====" ); return; }
    string DataCalendar[255][9];
    CsvArray( NameFile, DataCalendar );
    Print( "END" );
   
  }
//+------------------------------------------------------------------+
 

Появилась версия что проблема где то рядом ( c Малдер :) )

"Протерев сутра глаза, засучив рукова, нашлась таки закавырка. Код эксперта правельный, все путем. Просто в текстовом файле все должно быть записано вот так:
EURUSD;1;1.1800;
Ранее было:
EURUSD;1;1.1800
т.е. вся проблема с завитанием тестера была в ";" в конце строки.

Или данное решение является обходным маневром и не есть правельным?"

Отсюда: https://www.mql5.com/ru/forum/53573

Завтра буду копать в эту сторону

PS: Судя по тому что говорит дядя Гугл, эта ошибка FileIsLineEnding()  стара как MT4 ...

Хм, вот Вам и лучшее из лучшего ...


Сегодня раскопал на енг ресурсе более правильное описание этой фунции: она возвращает результат на основании ВЫПОЛНЕНИЯ функции FileReadString().

То есть в условие while ее при всем желании не прикрутишь, сперва должно быть чтение ...

Но есть подозрение что FileReadString тупит и не понимает признак конца строки :)

Короче mql4 походу как 1С создавали не программисты а домохозяйки ...

Надоело мне биться головой об стену, обработаю я этот csv файл своим кодом.

 

Немного исправил функцию CsvArray и всё заработало.

void CsvArray( string nameFile, string& Line[255][9] )
{
   int handle = FileOpen( nameFile, FILE_CSV|FILE_READ|FILE_ANSI, "," );
   if( handle != INVALID_HANDLE )
   {
      int CurRow = 0, CurCol, lineSize = 8;
      while( !FileIsEnding( handle ) )
      {
         CurCol = 0;
         bool EndOfLine = false;
         while( !EndOfLine )
         {
            Line[ CurRow ][ CurCol ] = FileReadString( handle );
            Print( "Row = ", CurRow,", Col = ", CurCol, " ,Val=", Line[ CurRow ][ CurCol ] );
            CurCol++;
            EndOfLine = FileIsLineEnding( handle );
         }
         CurRow++;
      }
      FileClose( handle );
   }
   else Alert( "Файл ", nameFile, " не обнаружен, последняя ошибка ", GetLastError() );
}

 Судя по всему, отладчиком Вы не пользуетесь. А зря.

 

Не добрался еще до него, особо нет смысла, я в лоб разрулил.

И кстати тот код который Вы написали увы но не отрабатывает - CPU грузится под 100% и на этом енд ...

Ступор на строчке кода:

EndOfLine = FileIsLineEnding( handle );
 
vfp7:

Появилась версия что проблема где то рядом ( c Малдер :) )

"Протерев сутра глаза, засучив рукова, нашлась таки закавырка. Код эксперта правельный, все путем. Просто в текстовом файле все должно быть записано вот так:
EURUSD;1;1.1800;
Ранее было:
EURUSD;1;1.1800
т.е. вся проблема с завитанием тестера была в ";" в конце строки.

Или данное решение является обходным маневром и не есть правельным?"

Отсюда: https://www.mql5.com/ru/forum/53573

Завтра буду копать в эту сторону

PS: Судя по тому что говорит дядя Гугл, эта ошибка FileIsLineEnding()  стара как MT4 ...

Хм, вот Вам и лучшее из лучшего ...


Сегодня раскопал на енг ресурсе более правильное описание этой фунции: она возвращает результат на основании ВЫПОЛНЕНИЯ функции FileReadString().

То есть в условие while ее при всем желании не прикрутишь, сперва должно быть чтение ...

Но есть подозрение что FileReadString тупит и не понимает признак конца строки :)

Короче mql4 походу как 1С создавали не программисты а домохозяйки ...

Надоело мне биться головой об стену, обработаю я этот csv файл своим кодом.

Вы, извините, программировать не умеете. И документацию не читаете. И поиском неправильно пользуетесь.

Вот Вам простейший пример для иллюстрации, что всё работает так, как заявлено. Даже с учётом завершающей ';'

void OnStart()
  {
   string file_name="testscript\\test.csv";
   int handle=FileOpen(file_name,FILE_WRITE|FILE_CSV);
   if(handle!=INVALID_HANDLE)
     {
      FileWrite(handle,"text 1",1234,0.1234,true,"");
      FileWrite(handle,"text 2",2345,0.2345,false,"");
      FileWrite(handle,"text 3",3456,0.3456,true,"");
      FileWrite(handle,"text 4",4567,0.4567,false,"");
      FileClose(handle);
      //---
      string line="";
      handle=FileOpen(file_name,FILE_READ|FILE_CSV);
      while(!FileIsEnding(handle) && !IsStopped())
        {
         line=FileReadString(handle);
         while(!FileIsLineEnding(handle))
           {
            string col=FileReadString(handle);
            line+=";";
            line+=col;
           }
         Print(line);
         line="";
        }
      Print(line);
      FileClose(handle);
     }
  }
 

Точно точно, не могу кодировать :)

И другие люди которые уже достаточно давно пишут про этот баг они тоже не могут кодировать и пользоваться поиском :)

Вроде по Русски написал - при отработке строки с кодом "EndOfLine = FileIsLineEnding( handle );" загрузка CPU взлетает под 100% и обработка кода останавливается ( следующие строки кода НЕ выполняются ).

Если бы хотели найти причину, то для начала хотя бы спросили версию Windows, железо и т.д., а так это все пустобрехство.

Ничего личного, но я как писал выше обошел этот баг своей обработкой файла, то есть я заменил багнутую функцию MT4 своей, и меня теперь эта проблема мало интересует.

Еще подскажу, что я и другие люди с кривыми руками не можем запустить EventSetTimer()  в тестере стратегий.

К примеру: https://www.mql5.com/ru/forum/149655/page4

Может и он у Вас будет работать :)


MetaTrader 4 Client Terminal build 610 - MQL4 форум
  • www.mql5.com
MetaTrader 4 Client Terminal build 610 - MQL4 форум
 
vfp7:

Точно точно, не могу кодировать :)


Давайте обсудим этот цикл

         while( !FileIsEnding( handle ) || !FileIsLineEnding( handle ) )   // Как должно быть - но не работает !
        // while( !FileIsEnding( handle ) || !FileIsLineEnding( handle ) ||  CurCol <= lineSize ) // А вот так отрабатывает, то есть функция !FileIsLineEnding( handle ) не отлавливает конец строки !!!
         {
           Print( "Row = ", CurRow,", Col = ", CurCol );
           Line[ CurRow ][ CurCol ] = FileReadString( handle );
           CurCol++;
         }

Он будет крутиться дольше, чем Вы хотите.

Дошли до конца файла? Нет, не дошли. Срабатывает укороченная оценка условия по ИЛИ. Наплевать на то, дошли мы до конца строки или нет - в тело цикла мы всё равно попадаем.

А Вам надо бы проверить оба условия. То есть так:

         while( !FileIsEnding( handle ) && !FileIsLineEnding( handle ) )

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

 

Извиняюсь за опечатку в том коде, это не рабочий код, я перенес вручную алгоритм того что происходило в теле моего советника.

В рабочем коде советника проходят дополнительные обработки, я сгруппировал тот код и вручную переносил.

Смысл в том, что когда у меня начинала обрабатываться функция FileIsLineEnding() мой компьютер вступоривался на этой строке.

Я разместил Print("!!! Нет ступора !!!"); следующей строкой - он не отработал ...

CPU грузится при этом почти на 100%, волнами. Приложение - MT4.

Могу выдвинуть версию про x64 бита, запуск под административными правами, но пока у меня не дошли руки выяснить в чем именно загвоздка.

Больше всего я склоняюсь к версии что эта функция пытается найти в конце строки символы разделителя, то есть ждет строку вида "text1,text2,text3," - на енг ресурсах я видел что таким вариантом эта функция отрабатывала.

Причем речь идет именно про "чужие" файлы csv, а не полученные из обработки в MT4.

Перелопатив инет я заметил что кодеры работающие с csv файлом на чтение, используют свои ухищрения, но при этом никто не применяет "правильный" алгоритм чтения из файла

https://www.mql5.com/ru/forum/141132

Видимо нет дыма без огня ...

Еще раз повторюсь, я просто написал свою обработку читаемой строки csv файла, то есть подменил функции MT4.

Когда завершу работу с советником, то вернусь к этой проблеме, для поиска первопричины.

Как научить индикатор читать данные из csv файла? - MQL4 форум
  • www.mql5.com
Как научить индикатор читать данные из csv файла? - MQL4 форум
 
stringo:

Вы, извините, программировать не умеете. И документацию не читаете. И поиском неправильно пользуетесь.

Ну это как посмотреть. Сколько я программирую под ваши терминалы, с небинарными файлами и строками у вас перманентная жопа и частенько как только требуется что-то чуть более сложное чем элементарное, приходится лепить костыли чтобы ваши косяки как-то обходить.
Причина обращения: