MQL5 – Работа со строками

Всем привет! Мы продолжаем изучать mql5 с нуля и сегодня будем говорить о строках и строковых функциях. Напоминаю, что уроки нацелены на людей, незнакомых с программированием на mql5 и с программированием вообще, и поэтому мы, начав с основ, постепенно наращиваем сложность излагаемого материала.


Предыдущие уроки


MQL5 программирование: Работа со строками

Как вы помните, для хранения текстовых строк в mql5 используется тип string. Строковая константа представляет собой последовательность символов Unicode, заключенную в двойные кавычки.

Язык MQL5 имеет очень широкий и удобный функционал для работы со строками. Чаще всего при программировании советников и индикаторов строки используются для формирования информационных сообщений о выполнении каких-либо условий, о торговых операциях и так далее.

Кроме того, запись и чтение файлов производится строковыми переменными. Конечно, есть и другой способ работы с файлами – бинарный, который обеспечивает чтение и запись числовых переменных и массивов. Но если объемы данных небольшие, лучше использовать текстовые файлы и строки. В этом случае упрощается процесс разработки программы, поскольку обеспечивается непосредственный контроль данных. В текстовых файлах данные выглядят точно так же, как и внутри программы.

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

input string Lots="0.1; 0.2; 0.3; 0.5";

Затем при инициализации эксперта строка легко разбивается, и заполняется массив числовых значений при помощи одной из встроенных в mql5 функций для работы со строками. Тут, конечно, есть минус – такие строковые параметры невозможно перебирать при оптимизации. Но наверняка могут быть и другие случаи, когда оптимизация параметра гарантированно не потребуется – например, перечисление валютных пар, на которых будет работать эксперт, особенно если он мультивалютный (например, торгует корзиной валют).

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

Объявление строковой переменной

Как и все другие типы переменных, строковые переменные могут не только объявляться:

string str;

но могут объявляться сразу же с присвоением значения (инициализироваться значением):

string str="Любой текст";

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

string str= "Длинная строка может "
            "быть записана в нескольких "
            "строчках";

При такой инициализации в переменной str будет находиться строка «Длинная строка может быть записана в нескольких строчках».

Здесь, немного забегая вперед, следует отметить, что значение строковой переменной, объявленной без параметров, не идентично пустой строке:

string str="";

В этом можно убедиться:

string str1;
string str2="";
Print(str1==str2);

При выполнении этого кода откроется окно с сообщением «false». Неинициализированная строковая переменная имеет значение NULL, и оно отличается от пустой строки «». Об этом следует помнить! При работе со строками очень часто приходится выполнять проверку, не является ли строка пустой. Поэтому следует или придерживаться правила инициализации всех строк пустой строкой «», или же выполнять две проверки: на неравенство «» и на неравенство NULL:

if(str!="" && str!=NULL)
  {
   //--- что-то делаем со строкой
  }

Первый способ предпочтительней, поскольку он упрощает условие проверки. 

Аналогичную проверку можно сделать, проверяя размер переменной. Для определения размера используется функция StringLen():

if(StringLen(str)!=0)
  { 
   //--- что-то делаем со строкой
  }

Сложение строк

Основное действие, которое чаще всего приходится выполнять со строками – их сложение, то есть составление фраз из слов. Сложение выполняется знаком «+»:

string str1,str2,str3,str4,str5;
//--- присвоение значений
str1="Программирование";
str2="на MQL5";
str3="для MetaTrader 5";
//--- сложение строк
str4=str1+" "+str2;
str5=str1+" "+str3;
//--- вывод результатов
Alert(str4);
Alert(str5);

После выполнения этого кода в переменной str4 будет фраза «Программирование на MQL5», а в переменной str5 фраза «Программирование для MetaTrader 5». В этом примере выполнялось сложение двух строк и присвоение полученной строки другой переменной.

Очень часто выполняется добавление дополнительной строки к основной строке: 

string str1,str2,str3;
//--- присвоение значений
str1="Программирование";
str2="на MQL5";
str3="для MetaTrader 5";
//--- сложение строк с добавлением к основной строке
str1=str1+" "+str2;
str1=str1+" "+str3;
//--- вывод результата
Alert(str1);

После выполнения этого кода в строке str1 будет фраза «Программирование на MQL5 для MetaTrader 5». В этом примере выполнялось добавление к основной строке str1 и присвоение полученного результата ей же. Такие действия можно записать немного проще:

str1+=str2;
str1+=str3;
Или так:
str1+=str2+str3;

Знак «+» слева от знака «=» означает, что к переменной str1 выполняется добавление выражения, записанного правее знака «=».

Также можно выполнить добавление строки в начало основной строки, это выполняется подобно предпоследнему примеру: к добавляемой строке прибавляется основная строка и полученная строка присваивается основной переменной:

string str1,str2,str3;
//--- присвоение значений
str1="Программирование";
str2="на MQL5";
str3="для MetaTrader 5";
//--- сложение строк с добавлением строки в начало
str3=str2+" "+str3;
str3=str1+" "+str3;
//--- вывод результата
Alert(str3);

Только теперь фраза «Программирование на MQL5 для MetaTrader 5» будет в переменной str3. То же самое можно выполнить в одну строчку: 

str3=str1+" "+str2+" "+str3;

В некоторых случаях можно произвести сложение при помощи знака «,» (запятая). Это происходит при вызове функций Alert(), Print(), Comment():

Print(str1," ",str2," ",str3);

Конечные результаты при использовании такой записи будут идентичны использованию знака «+»:

Print(str1+" "+str2+" "+str3);

На самом деле знак «,» не выполняет сложение строк, во всех функциях запятая является разделителем параметров. Так же и с функциями Alert(), Print(), Comment(). Эти функции имеют один обязательный параметр и большое количество необязательных. По сути, выполняется передача в функцию нескольких параметров, которые внутри функции соединяются вместе. Максимальное количество параметров – 64 шт.

Кроме использования знака «+» в языке MQL5 существуют специализированные функции для сложения строк: StringAdd() и StringConcatenate(). По описанию этих функций в справочном руководстве, они позволяют производить соединение строк более экономично в плане занимаемой оперативной памяти и более быстро.

StringAdd присоединяет к концу строки по месту указанную подстроку.

bool StringAdd(
string& string_var, // строка, к которой добавляем
string add_substring // добавляемая строка
);

В случае успешного выполнения функция возвращает true, иначе false. Для получения кода ошибки нужно вызвать функцию GetLastError().

Пример:

void OnStart()
{
long length=1000000;
string a="a",b="b",c;

//--- первый способ
uint start=GetTickCount(),stop;
long i;

for(i=0;i<length;i++)
{
c=a+b;
}

stop=GetTickCount();
Print("time for 'c = a + b' = ",(stop-start)," milliseconds, i = ",i);

//--- второй способ
start=GetTickCount();
for(i=0;i<length;i++)
{
StringAdd(a,b);
}

stop=GetTickCount();
Print("time for 'StringAdd(a,b)' = ",(stop-start)," milliseconds, i = ",i);

//--- третий способ
start=GetTickCount();

a="a"; // заново инициализируем переменную a
for(i=0;i<length;i++)
{
StringConcatenate(c,a,b);
}

stop=GetTickCount();
Print("time for 'StringConcatenate(c,a,b)' = ",(stop-start)," milliseconds, i = ",i);
}

StringConcatenate формирует строку из переданных параметров и возвращает размер сформированной строки. Параметры могут иметь любой тип. Количество параметров не может быть меньше 2 и не может превышать 64.

int StringConcatenate(
string& string_var, // строка для формирования
void argument1 // первый параметр любого простого типа 
void argument2 // второй параметр любого простого типа
... // следующий параметр любого простого типа
);

Возвращает длину строки, сформированной путем конкатенации преобразованных в тип string параметров. Параметры преобразуются в строки по тем же правилам, что и в функциях Print() и Comment().

Преобразование различных переменных в строку

При формировании строки сообщения очень часто возникает необходимость добавить в нее значения числовых переменных. Для преобразования значений целочисленных переменных (char, uchar, bool, short, ushort, int, uint, color, long, ulong, datetime) в строку используется функция IntegerToString():

int x=1;
string str="x = "+IntegerToString(x);

Если преобразовывать переменную типа bool, будет возвращаться строка «0» (false) или «1» (true), при преобразовании переменных типа color или datetime – строка с числовым выражением цвета или даты (например, «65535» для желтого цвета clrYellow или «1325376000» для даты 2012.01.01 00:00).

Для преобразования переменных вещественного типа (double, float) в строку используется функция DoubleToString(). Второй параметр этой функции определяет точность (количество знаков после запятой):

double x=1.23456;
string str1="x = "+DoubleToString(x,2);
string str2="x = "+DoubleToString(x,3);

После выполнения этого кода в переменной str1 будет находиться строка «1.23», а в переменной str2 строка «1.235». Обрезание до указанного количества знаков работает по принципу математического округления.

Для преобразования даты и времени в строку стандартного формата (понятного человеку) используется функция TimeToString():

datetime tm=TimeCurrent(); // Текущее время 
string str1=IntegerToString(tm);
string str2=TimeToString(tm);

После выполнения этого кода в переменной str1 будет находиться строка с числовым выражением времени (количество секунд от 1 января 1970 года), а в переменной str2 – отформатированное время, например, «2012.11.02 22:00» (год, месяц, число, часы, минуты).

При вызове функции TimeToString() имеется возможность указать формат отображения даты и времени. Возможны следующие варианты:

string str1="Дата и время с минутами: "+TimeToString(tm);
string str2="Только дата: "+TimeToString(tm,TIME_DATE);
string str3="Только время с минутами: "+TimeToString(tm,TIME_MINUTES);
string str4="Только время с секундами: "+TimeToString(tm,TIME_SECONDS);
string str5="Дата и время с секундами: "+TimeToString(tm,TIME_DATE|TIME_SECONDS);

В MQL5 имеется очень удобная функциональная возможность – создание перечислений, которые в окне свойств программы отображаются в виде выпадающих списков с набором вариантов. Значения таких переменных тоже можно преобразовывать в строку, для этого используется функция EnumToString(). Ниже расположен код скрипта с демонстрацией работы этой функции:

//+------------------------------------------------------------------+
//| Создание перечисления                                            |
//+------------------------------------------------------------------+
enum EMode
  {
   OFF=0,
   Mode1 = 1,
   Mode2 = 2,
   Mode3 = 3 
  };
//+------------------------------------------------------------------+
//| Запуск скрипта                                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
   EMode Value=1;
   //--- соединение строк
   string str="Значению "+IntegerToString(Value)+" соответствует пункт "+EnumToString(Value)+" перечисления EMode";
   //--- вывод результата
   Alert(str);
  } 

Подобная возможность имеется и для преобразования переменных цвета. Можно преобразовать значение цвета в его имя, для чего используется функция ColorToString():

color ColorValue=clrRed;
string str=ColorToString(ColorValue,true);

После выполнения этого кода в переменной str сохранится строка «clrRed». Если второму параметру установить значение false, то функция будет возвращать строку со значениями компонентов RGB (красного, зеленого, синего):

color ColorValue=clrRed;
string str=ColorToString(ColorValue,false);

В этом случае в переменной str сохранится строка «255,0,0». Если цвет не является стандартным (не входит в набор веб-цветов и, соответственно, не имеет имени), то функция ColorToString() возвращает строку со значениями компонентов, независимо от значения второго параметра.

Существует еще один способ преобразования переменных – через приведение типов:

int x=123;
string str=(string)x;

При преобразовании таким способом переменной типа bool строка будет иметь значение » true» или «false»: 

bool x=true;
string str=(string)x;

Преобразование переменных типа double и float выполняется с максимальной точностью, происходит только отбрасывание нулей в дробной части: 

double x1=0.1;
double x2=0.123; 
string str1=(string)x1;
string str2=(string)x2;

После выполнения этого кода в переменой str1 сохранится строка «0.1», а в переменной str2 строка «0.123».

Вывод специальных символов

При инициализации строковой переменной значением присваиваемая строка помещается в двойные кавычки, чтобы компилятор мог отличить строку от программного кода. Для того, чтобы поместить кавычки внутрь строки, нужно указать, что в данном случае знак используется не по его прямому назначению (как знак, отделяющий строку от кода), а как часть строки. Для этого перед знаком кавычек необходимо поставить обратную черту «\»:

string str1="Просто текст";
string str2="\"Текст в кавычках\"";
//--- вывод результатов
Print(str1);
Print(str2);

Поскольку обратная черта тоже является специальным символом, то для ее вывода в строку необходимо поставить перед ней еще одну обратную черту:

string str="\\";
Print(str);

После выполнения этого кода в строке будет один символ «\».

Еще строка может содержать знак горизонтальной табуляции, который указывается знаками «\t»:

string str="Колонка-1\tКолонка-2\tКолонка-3";
Print(str);

В этом случае в переменной str сохранится строка «Колонка-1        Колонка-2        Колонка-3».

При помощи знаков «\n» текст может выводиться с переносами, в несколько строк:

string str="Строка-1\nСтрока-2\nСтрока-3";
Print(str);

В данном случае результатом выполнения функции Print() будут три строки текста.

При выводе с использованием функций Alert() и MessageBox(), а также при записи в файл действуют оба символа: «\t» и «\n». Однако при выводе в комментарий графика (функция Comment()) действует только знак перехода на новую строку «\n», знак табуляции «\t» игнорируется. При выводе с использованием функции Print() знак «\n» тоже действует (каждая часть строки выводится в отдельную строку журнала), а знак «\t» заменяется на пробел. В лог файле, в котором сохраняются все сообщения, выводимые функцией Print(), знак «\t» заменяется на пробел.

Форматирование строк по шаблону

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

//--- инициализация переменных
int Variable1=1;
int Variable2=2;
int Variable3=3;
//--- длинное соединение строк
string str="Variable1 = "+IntegerToString(Variable1)+", Variable2 = "+IntegerToString(Variable2)+", Variable3 = "+IntegerToString(Variable2);
Print(str);

Эту задачу можно решить значительно проще при помощи функции StringFormat(). Первым параметром в эту функцию передается шаблон сообщения, в котором указаны места вставки переменных и определен формат их вывода. Далее перечисляются все переменные в том порядке, в каком они встречаются в шаблоне: 

//--- инициализация переменных
int Variable1=1;
int Variable2=2;
int Variable3=3;
//--- более простое соединение строк
string str=StringFormat("Variable1 = %i, Variable2 = %i, Variable3 = %i",Variable1,Variable2,Variable3);
Print(str);

Места вставки переменных обозначаются знаком «%», следующий за ними символ «i» в показанном примере означает, что переменные должны выводиться как целочисленные. Точнее, «i» означает целочисленные знаковые переменные (char, short, int, color), а для целочисленных беззнаковых (uchar, bool, ushort, uint) используется «u». С переменными типа long, ulong, datetime следует дополнительно указывать разрядность переменной, указав перед типом «I64»:

string LongMin=StringFormat("%I64i",LONG_MIN);
string LongMax=StringFormat("%I64i",LONG_MAX);
string ULongMax=StringFormat("%I64u",ULONG_MAX);
string DateTimeMax=StringFormat("%I64u",DateMax);

В результате работы этого кода откроется окно сообщения со значениями переменных.

Формат вещественных чисел обозначается символом «f»:

double Percents=5.5;
//--- вещественное число в виде строки
string str=StringFormat("Percents = %f",Percents);
Print(str);

После выполнения этого кода в переменной str сохранится строка «Percents = 5.500000», по умолчанию выводится шесть знаков после запятой. Можно указать требуемое количество знаков:

string str=StringFormat("Percents = %.2f",Percents);

Для этого ставится точка, означающая десятичный разделитель, и число знаков после него, в данном примере 2 знака. В этом случае в переменной str сохранится строка «Percents = 5.50». Такой вариант форматирования в точности заменяет функцию DoubleToString().

Можно указать общую длину числа – для этого сразу же после знака «%» ставится «0» и число, определяющее длину числа, затем указывается количество знаков после запятой (если нужно):

string str=StringFormat("Percents = %06.2f",Percents);

Указана общая длина в 6 знаков, из которых один знак будет занят десятичным разделителем и еще два – знаками после запятой. Поэтому в переменной str сохранится строка «Percents = 005.50».

Если в сообщении надо выводить знак процента «%», а он используется для указания мест вставки значений, необходимо вписать его два раза подряд «%%»:

string str=StringFormat("Percents = %06.2f%%",Percents);

В этом случае в переменной str будет строка «Percents = 005.50%».

Можно определить длину числа и при выводе целочисленных переменных:

int Variable=123;
//--- целое число в виде строки с заданной длиной вывода
string str=StringFormat("Variable = %05i",Variable);
Print(str);

После выполнения этого кода в переменной str сохранится строка «Variable = 00123».

Если указано меньшее количество знаков, чем составляет число, то оно все равно будет выведено правильно:

string str=StringFormat("Variable = %02i",Variable); 

В этом случае в переменной str будет строка «Variable = 123», то есть выведено число из 3-х знаков, несмотря на то, что указана длина 2.

Вещественные числа можно выводить в научном формате (мантисса с шестью знаками после десятичного разделителя и степень), для этого используется символ «e»:

double Variable=123.456;
//--- вещественное число в виде строки в научной форме
string str=StringFormat("Variable = %e",Variable);
Print(str);

После выполнения этого кода в переменной str сохранится строка «1.234560e+002». Можно использовать заглавную «E» – ее действие аналогично строчной «e», только в отформатированной строке вместо строчной «e» будет заглавная «E».

Существует еще один вариант форматирования вещественных чисел – «g», при этом выводится всего шесть знаков (без учета десятичного разделителя). Если длина целой части числа превышает шесть знаков, число выводится в научной форме:

double Variable1=12.3456789;
double Variable2=1234567.89;
//--- получение вещественных чисел в виде строк с использованием "g"
string str1=StringFormat("Variable = %g",Variable1);
string str2=StringFormat("Variable = %g",Variable2);
Print(str1+" "+str2);

В этом примере в переменной str1 сохранится строка » 12.3457″, а в переменной str2 строка «1.23457e+006». При использовании заглавной «G» все будет работать точно так же, только вместо строчной «e» будет выводиться заглавная «E».

Сообщения на разных языках

Функция StringFormat() позволяет наделить программу очень полезной возможностью – обеспечить вывод сообщений на разных языках в зависимости от установленного в терминале языка интерфейса.

Какой выбран язык для интерфейса, можно узнать, вызвав функцию TerminalInfoString() с идентификатором TERMINAL_LANGUAGE. При запуске программы готовим форматирующую строку в зависимости от языка интерфейса и затем используем ее в программе. Ниже показан шаблон эксперта с такой возможностью:

//--- переменная для форматирующей строки
string FormatString;
//+------------------------------------------------------------------+
//| Обработка события Init                                           |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- получение форматирующей строки
   FormatString=GetFormatString();
//--- дополнительный вызов, на случай, чтобы в выходные эксперт отработал хотя бы один раз
   OnTick();
   return(0);
  }
//+------------------------------------------------------------------+
//| Обработка события Tick                                           |
//+------------------------------------------------------------------+
void OnTick()
  {
   int Variable1,Variable2,Variable3;
   Variable1=MathRand()%10;        // Случайное число от 0 до 10
   Variable2=MathRand()%10;        // Еще одно случайное число
   Variable3=Variable1+Variable2; // Сумма чисел
//--- вывод результата
   Alert(StringFormat(FormatString,Variable1,Variable2,Variable3));
  }
//+------------------------------------------------------------------+
//| Определение форматирующей строки                                 |
//+------------------------------------------------------------------+
string GetFormatString(void)
  {
   string Language=TerminalInfoString(TERMINAL_LANGUAGE);
//--- проверка языков
   if(Language=="Russian") return("%i плюс %i равно %i");     // русский
   if(Language=="Spanish") return("%i más %i es igual a %i"); // испанский
//--- Для всех остальных случаев - английский
   return("%i plus %i equals %i");
  }

Эксперт суммирует два случайных числа и выводит текстовое сообщение о своих действиях, например, «1 плюс 2 равно 3».

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

Основные функции работы со строками

Если строка вводится через окно свойств программы или читается из файла, то в ней могут присутствовать лишние пробелы, они могут появиться или от случайной неаккуратности пользователя, или, может быть, ему было так удобней. Прежде чем выполнять над строкой какие-нибудь действия, желательно удалить пробелы с краев. Для этого в языке MQL5 существуют функции StringTrimLeft() (удаляет пробелы слева) и StringTrimRight() (удаляет пробелы справа). Эти функции удаляют не только пробелы, но и символы табуляции и новой строки. При работе со строками приходится часто выполнять удаление пробелов сразу с обеих сторон, поэтому будет полезно написать функцию, выполняющую это:

string Trim(string Str)
  {
   StringTrimLeft(Str);
   StringTrimRight(Str);
   return(Str);
  } 

StringTrimLeft удаляет символы перевода каретки, пробелы и символы табуляции с начала строки до первого значимого символа. Строка модифицируется по месту. StringTrimRight удаляет символы перевода каретки, пробелы и символы табуляции от последнего значимого символа до конца строки. StringReplace заменяет в строке все найденные подстроки на заданную последовательность символов.

Функция StringFind() используется для поиска подстроки и возвращает индекс первого вхождения подстроки в строку. Первым параметром в функцию передается строка, в которой выполняется поиск, второй параметр определяет искомую подстроку, а третий (не обязательный) может определять позицию, с которой начинается поиск. Если третий параметр не указан, то функция работает так, как будто его значение равно 0, то есть поиск выполняется с самого начала строки. Найдем позицию подстроки «5» в строке «Программирование для MQL5 для MetaTrader 5»:

string str="Программирование на MQL5 для MetaTrader 5";
//--- получение позиции символа
int Pos=StringFind(str,"5");
//--- вывод результата
Print(IntegerToString(Pos));

После выполнения этого кода в переменной Pos сохранится значение 23. Всего подстрока «5» встречается два раза, но функция вернула только позицию первого вхождения. Если отсчитать позицию, просто глядя на строку, получается 24. Дело в том, что функция выполняет отсчет, начиная с нуля, а не с единицы. Если искомая подстрока отсутствует в строке, функция возвращает -1.

Функция StringSubstr() применяется для извлечения подстроки с заданной позиции и заданной длины. Извлечем подстроку с позиции 23 длиной 1:

string str="Программирование на MQL5 для MetaTrader 5";
//--- получение подстроки с указанной позиции и длиной
string str2=StringSubstr(str,23,1);
Print(str2);

Теперь, разобравшись с основными функциями, используем их для написания полезной функции для удаления из строки заданного списка символов. В функцию передается исходная строка и строка, представляющая собой список символов, которые необходимо удалить из исходной.

string TrimL(string Str,string List="\t\n ;")
  {
//--- переменная для одной буквы строки Str
   string ch;
   int Len=StringLen(Str);
   int i=0;
//--- цикл по всем буквам строки Str
   for(;i<Len;i++)
     {
      //--- очередная буква строки Str
      ch=StringSubstr(Str,i,1);
      //--- если этой буквы нет в списке List, значит строка должна начинаться с этой позиции 
      if(StringFind(List,ch,0)==-1)
        {
         break; // завершаем работу цикла
        }
     }
//--- извлекаем подстроку и возвращаем ее
   return(StringSubstr(Str,i));
  }

Заглавная и строчная буква, например, «А» и «а» для человека не являются различными по своему смыслу, однако для компьютера это два совершенно разных символа. Если при запросе рыночных данных, используя функцию SymbolInfoDouble(), вместо, например, «EURUSD» указать символ «eurusd», то функция не вернет нужного нам значения. При вводе символа через окно свойств очень вероятна такая ошибка. Для изменения регистра в языке MQL5 существуют функции StringToLower() (перевод к нижнему регистру) и StringToUpper() (перевод к верхнему регистру).

StringToLower преобразует все символы указанной строки в строчные (маленькие) по месту:

bool StringToLower(
string& string_var // строка для обработки
);

StringToUpper преобразует все символы указанной строки в прописные (большие) по месту:

bool StringToUpper(
string& string_var // строка для обработки
);

На этом все, всем пока!

Тема на форуме

С уважением, Дмитрий аkа Silentspec
Tlap.com

Новости, Уроки по MQL5 , ,