Logo

Вход

Войти с помощью соц. сетей
X
 
  • Фильтр
  • Время
  • Показать
Очистить всё
новые сообщения
  • #1 Свернуть

    Кто сталкивался помогите со строкой

    Есть строка MQL-Код:
    StringConcatenate(TerminalPath(), "\experts\files\",Filename,".ini")


    Но в соответствии с синтаксисом комбинация \" дает просто кавычку. И дальнейшие операторы рассматриваются как текст.
    Из справки : Если необходимо ввести в строку двойную кавычку ("), то перед ней надо поставить символ обратной косой черты (\).

    Можно между слешем и кавычкой поставить пробел, но будет ли тогда правильно читаться путь? Там ведь добавляется лишний пробел. Полный путь необходим для передачи в Dll. Кто знает помогите пожалуйста.
  • <a href="https://www.instaforex.org/ru/?x=ruforum">InstaForex</a>
  • #2 Свернуть

    Сообщение от Дмитрий@Игоревич Посмотреть сообщение
    Есть строка MQL-Код:
    StringConcatenate(TerminalPath(), "\experts\files\",Filename,".ini")


    Но в соответствии с синтаксисом комбинация \" дает просто кавычку. И дальнейшие операторы рассматриваются как текст.
    Из справки : Если необходимо ввести в строку двойную кавычку ("), то перед ней надо поставить символ обратной косой черты (\).

    Можно между слешем и кавычкой поставить пробел, но будет ли тогда правильно читаться путь? Там ведь добавляется лишний пробел. Полный путь необходим для передачи в Dll. Кто знает помогите пожалуйста.
    Надо перед слеш ставить еще один слеш, т.к. слеш функционален, например "\n" обозначает "возврат каретки" (печать с новой строки) и т.п.
    Т.е. пишем
    "\\experts\\files\\"
    А лучше перевернуть слеши и не мучаться, так работает в винде:
    "/experts/files/"
    Надежно и удобочитаемо

    Комментарий

    • #3 Свернуть

      Сообщение от Дмитрий@Игоревич Посмотреть сообщение
      StringConcatenate(TerminalPath(), "\experts\files\",Filename,".ini")
      Попробуйте так
      MQL код:

      StringConcatenate(TerminalPath(), "\\experts\\files\\",Filename,".ini")
       

      Комментарий

      • #4 Свернуть

        Сообщение от vashtr Посмотреть сообщение
        "\\experts\\files\\"
        Не могу понять почему-то скрин не вставляется, вариант с двойным слешем не помагает.

        Сообщение от vashtr Посмотреть сообщение
        "/experts/files/"
        А здесь получается такой путь : C:\Program Files (x86)\InstaTrader/experts/files/EURUSD.ini
        Может еще есть варианты ? Не помню правильно синтаксиса но во многих языках существует функция CHR(12)(или ей подобная) и возвращает символ возврата каретки(12), или того символа код которого стоит в скобках. Может кто знает в MQL такой ?
         

        Комментарий

        • #5 Свернуть

          Сообщение от Дмитрий@Игоревич Посмотреть сообщение
          Не могу понять почему-то скрин не вставляется, вариант с двойным слешем не помагает.



          А здесь получается такой путь : C:\Program Files (x86)\InstaTrader/experts/files/EURUSD.ini
          Может еще есть варианты ? Не помню правильно синтаксиса но во многих языках существует функция CHR(12)(или ей подобная) и возвращает символ возврата каретки(12), или того символа код которого стоит в скобках. Может кто знает в MQL такой ?
          В MQL коды можно вставлять прямо в текст. Выглядит код как '\xhh' где hh - шестнадцатиричный код. Например чтобы разделить текст символами #13#10 надо написать так

          MQL код:

          string s = "text1 \x0D\x0A text2";

          Символ перевода каретки в ASCII имеет номер 13. А символ с кодом 12 будет соответственно \x0С. Для перевода каретки можно использовать символ '\r' а для переврда строки '\n' и записать ту же самую строку так

          MQL код:

          string s = "text1 \r\n text2";


          Не могу понять почему-то скрин не вставляется, вариант с двойным слешем не помагает.
          Должно работать - можете поконкретнее объяснить в чём проблема ?
             

          Комментарий

          • #6 Свернуть

            Сообщение от Timmen Посмотреть сообщение
            Должно работать - можете поконкретнее объяснить в чём проблема ?
            В окне выбора и загрузки файла в строке с именем файла и его размером стоит восклицательный знак в красном кружочке , пробовал и GIF и JPEG. не получается почему-то. Хотя дней пять назад грузились картинки.


            Сообщение от Timmen Посмотреть сообщение
            В MQL коды можно вставлять прямо в текст. Выглядит код как '\xhh' где hh - шестнадцатиричный код. Например чтобы разделить текст символами #13#10 надо написать так
            За этот совет спасибо, я не знал этого, а проблему решил так : StringConcatenate(TerminalPath(), "\experts\files",CharToStr(92),Symbol(),".ini")
               

            Комментарий

            • #7 Свернуть

              Timmen Может ты и в паскале разбираешся то подскажи ошибку здесь если не затруднит:

              procedure TForm1.WriteIni();
              var
              myFile : TextFile;
              begin

              AssignFile(myFile,TerminalPath);
              ReWrite(myFile);

              WriteLn(myFile, 'Hello');
              WriteLn(myFile, 'World');

              CloseFile(myFile);
              end;


              Сюда передается путь разбираемый выше в переменную TerminalPath. При исполнении этого кода терминал завершает работу ...???
                 

              Комментарий

              • #8 Свернуть

                Сообщение от Дмитрий@Игоревич Посмотреть сообщение
                Timmen Может ты и в паскале разбираешся то подскажи ошибку здесь если не затруднит:

                procedure TForm1.WriteIni();
                var
                myFile : TextFile;
                begin

                AssignFile(myFile,TerminalPath);
                ReWrite(myFile);

                WriteLn(myFile, 'Hello');
                WriteLn(myFile, 'World');

                CloseFile(myFile);
                end;


                Сюда передается путь разбираемый выше в переменную TerminalPath. При исполнении этого кода терминал завершает работу ...???
                Значит какая-то критическая ошибка возникает - надо попытаться её выловить, например так

                Код:
                procedure TForm1.WriteIni();
                var
                 myFile : TextFile;
                begin
                 try
                   AssignFile(myFile,TerminalPath);
                
                   ReWrite(myFile);
                
                   WriteLn(myFile, 'Hello');
                   WriteLn(myFile, 'World');
                   CloseFile(myFile);
                 except on e:Exception do
                  ShowMessage(e.Message);
                 end;
                end;
                Вариант #2 - попробовать использовать для работы с файлом более цивилизованный подход - потоки. Пример :
                Код:
                procedure WriteIniFile(fileName:string);
                var
                  fileStream:TFileStream;
                  value : string;
                begin
                  fileStream := TFileStream.Create(fileName, fmCreate, fmShareCompat);
                  value := 'Hello' + #13#10 + 'World';
                  fileStream.Write(Pointer(value)^, Length(value));
                  fileStream.Free();
                end;
                   
                Последний раз редактировалось Timmen; 25.10.2012, 22:19.

                Комментарий

                • #9 Свернуть

                  Вариант 2 пошел спасибо... Только с таким вариантом я еще ни разу не работал. Если что проверяй ветку буду задавать вопросы. И первый из них - что означает fmShareCompat ? Пишу в Delphi чтобы управлять параметрами советника из формы через INI файл. Хотя, вопрос второй, при тестировании даже если советник будет открывать и закрывать файл на каждой свечке не заглючит ли комп, может лучше передавать параметры через какую-то функцию ?
                     

                  Комментарий

                  • #10 Свернуть

                    Сообщение от Timmen Посмотреть сообщение
                    Вариант #2
                    Как записать по второму методу переменные A,B,C , а потом считать их снова в эти-же переменные.
                       

                    Комментарий

                    • #11 Свернуть

                      Сообщение от Дмитрий@Игоревич Посмотреть сообщение
                      Вариант 2 пошел спасибо... Только с таким вариантом я еще ни разу не работал. Если что проверяй ветку буду задавать вопросы. И первый из них - что означает fmShareCompat ?
                      В конструкторе у TFileStream три патаметра, обязательными являются первые два. С первым всё ясно - это полный путь к файлу. Второй параметр - режим открытия. Может быть fmOpenReadWrite, fmCreate и прочее - легко найти все в интернете. Третий параметр - права доступа к файлу. Файл может быть открыт таким способом, что пока мы не закончим с ним работу и не закроем поток вызовом его метода Free() к этому файлу не сможет обратиться другая программа. Задав параметр fmShareCompat мы открываем файл в режиме совместного доступа(с файлом могут одновременно работать несколько приложений). Можно попробовать использовать fmShareDenyNone который также позволяет другим приложениям и читать и писать в файл пока мы с ним работаем, fmShareCompat прсто первым пришёл мне в голову, он вроде считается устаревшим. Указал я его на тот случай если проблема как раз в совместном доступе к файлу. Можно поэкспериментировать с этими флагами, попытаться использовать режим доступа по-умолчанию(убрать третий параметр вовсе).

                      Сообщение от Дмитрий@Игоревич Посмотреть сообщение
                      Пишу в Delphi чтобы управлять параметрами советника из формы через INI файл. Хотя, вопрос второй, при тестировании даже если советник будет открывать и закрывать файл на каждой свечке не заглючит ли комп, может лучше передавать параметры через какую-то функцию ?
                      Можно хранить настройки в самой DLL-ке.

                      Код:
                      library TestLib;
                      
                      uses  SysUtils, Classes, Dialogs;
                      
                      var
                        variable:Integer;
                      {$R *.res}
                      
                      function GetVariable():integer; stdcall;
                      begin
                        Result := variable;
                      end;
                      
                      procedure SetVariable(value:integer); stdcall;
                      begin
                        variable := value;
                      end;
                      
                      exports GetVariable;
                      exports SetVariable;
                      
                      begin
                      end.
                      И затем проверить скриптом

                      MQL код:

                      #import "TestLib.dll"
                      int GetVariable();
                      void SetVariable(int value);
                      #import

                      int start()
                      {
                      SetVariable(391);
                      Alert(GetVariable());
                      return(0);
                      }


                      Иметь функции для доступа к каждой настройке отдельно, менять значения переменных при помощи формы, а экспертом на каждой свече получать значения вызовом соответствующих функций. Теоретически всё должно рботать. Как поведёт себя эксперт при таком подходе в тестере стратегий можно узнать только попробовав.
                         

                      Комментарий

                      • #12 Свернуть

                        Сообщение от Timmen Посмотреть сообщение
                        Можно хранить настройки в самой DLL-ке.
                        Можно, вы правы, но INI тоже необходим , для сохранения настроек на форме при выключении, при повторном включении сделаю восстановление параметров из INI файла. Но все-же еще немного помучаю вас. Как записать переменные A,B,C , а потом считать их снова в эти-же переменные последним способом ?
                           

                        Комментарий

                        • #13 Свернуть

                          Сообщение от Дмитрий@Игоревич Посмотреть сообщение
                          Как записать по второму методу переменные A,B,C , а потом считать их снова в эти-же переменные.
                          Файловому потоку безрзлично какие занные через него записывают - его метод Write принимает первым параметром объект, который надо записать в файл, второй параметр - размер данных(обычно надо указывать размер объекта).

                          Накидал пример

                          Код:
                          procedure Test();
                          var
                            fileStream:TFileStream;
                            A:double;
                            B:integer;
                            C:string;
                            D: array of byte;
                            fileName : string;
                          begin
                            fileName := 'test.dat';
                          
                            fileStream := TFileStream.Create(fileName, fmCreate, fmShareCompat);
                          
                            A := 0.345;
                            C := 'My string';
                            B := Length(C); // запишем в файл длину строки - пригодится
                          
                            SetLength(D, 3); // заполним массив данными
                            D[0] := 100;
                            D[1] := 150;
                            D[3] := 200;
                          
                            // записываем всё в файл
                            fileStream.Write(A, SizeOf(A));
                            fileStream.Write(B, SizeOf(B));
                          
                            // строки и массивы нельзя передавать просто так - нужно передавать указатели на них
                            //  и указывать правильные размеры данных
                            // в sizeof можно передавать как непосредственно объект так и имя простого типа
                            // а вернёт она количество байт занимаемое объектом или типом
                            fileStream.Write(Pointer(C)^, Length(C)*sizeof(char));
                            fileStream.Write(Pointer(D)^, Length(D)*sizeof(byte));
                          
                            // освобождаем поток - в этот момент гарантированно данные запишутся в файл
                            fileStream.Free();
                          
                            // теперь прочитаем всё что записали. Сперва обнулим все переменные
                            fileStream := TFileStream.Create(fileName, fmOpenRead, fmShareCompat);
                            A:=0.0;
                            B:=0;
                            C:='';
                            ZeroMemory(Pointer(D), 3);
                          
                            fileStream.Read(A, SizeOf(A));
                            fileStream.Read(B, SizeOf(B));
                          
                            // вот тут момент - мы писали строку, но теперь чтобы её прочитать нам надо знать какой она была длины
                            // но строка может быть любой длины - для того чтобы знать сколько нам читать мы и сохранили длину строки в переменной B
                            SetLength(C, B); // установили длину строки такой какая она была до записи в файл
                            fileStream.Read(Pointer(C)^, Length(C)*sizeof(char));
                          
                            // предположим что массив у нас всегда длиной 3 и проделывать то же что и со строкой нам не надо
                            fileStream.Read(Pointer(D)^, 3*sizeof(byte));
                          
                            // выводим результат
                            Showmessage(FloatToStr(A));
                            Showmessage(IntToStr(B));
                            Showmessage(C);
                            Showmessage(IntToStr(D[0]) + ' ; ' + IntToStr(D[1]) + ' ; ' + IntToStr(D[2]));
                            fileStream.Free();
                          end;
                          При чтении данных из файла естестенно надо соблюдать тот же порядок что был при записи в файл. При записи данных, которые могут иметь переменную длину, надо всегада делать так как со строкой - предварительно записать длину, затем объект. При чтении извлекается длина объекта, он инициализируется этой длиной и в него считываются данные.
                             

                          Комментарий

                          • #14 Свернуть

                            Спасибо Timmen за доскональное описание думаю теперь все получится. Извини за тупые вопросы конечно , просто есть несколько лет пробелов от паскаля к делфи.
                               

                            Комментарий

                            • <a href="https://www.instaforex.org/ru/?x=ruforum">InstaForex</a>
                            • #15 Свернуть

                              Сообщение от Timmen Посмотреть сообщение
                              fileStream.Write(A, SizeOf(A));
                              Могу я в этом случае вместо А поставить содержимое RadioButton вот так :
                              Код:
                              fileStream.Write(rg1.ItemIndex,SizeOf(rg1.ItemsIndex));
                                 

                              Комментарий

                              Сейчас онлайн

                              working...
                              X