![MQL5 Programming Basics: Strings](https://c.mql5.com/i/articles/overlay.png)
MQL5 Programming Basics: Strings
Introduction
Strings, or rather string variables, are used to store character data, i.e. text:
string str="Any text";
The MQL5 language offers a broad range of user-friendly functionality for working with strings. In programming Expert Advisors and indicators, strings are mostly used to generate information messages. In indicators, these may be messages regarding the fulfillment of certain conditions (e.g. trading signals), while in Expert Advisors they may report trading activity results. When run, an Expert Advisor, script or indicator may check parameters set by the user and print a notification in case the parameters set are invalid. In addition to notifications, you may sometimes see prompting messages that give recommendations regarding parameter settings. Broadly speaking, when programming in MQL5, strings above all else offer user friendliness.
Further, strings are essential when working with files. Writing and reading data from files is performed using string variables. Clearly, one can opt for another way of working with files, a binary method that provides for reading and writing numerical variables and arrays. However if the amount of data is not too large, it is better to use text files and strings. In this case, the program operation is more clear to the user and the process of program development is simpler, providing an immediate data control. Text file data looks the same as data inside the program.
Use of strings can significantly broaden the program features associated with data (parameter) input in cases where the required number of parameters is not known in advance (e.g. lot sizes for averaging build-ups). In such a case, values can be written in a single string separated by a separator, such as semicolon:
input string Lots="0.1; 0.2; 0.3; 0.5";
Then, when initializing the Expert Advisor the string is split and an array of numerical values is filled. Unfortunately, it is impossible to go over such string parameters in optimization, i.e. to set the initial and final value along with the step value. In some cases, it might perhaps be more preferable to use a large number of numerical variables in the properties window. But since they can virtually be unlimited in number, we may face an issue of convenience and purpose (whether the possibility of optimization is required).
There may well be other cases where the optimization of a parameter is known not to be required, e.g. enabling notifications. MQL5 supports various user notification methods: sound notifications, pop-up notifications, e-mail notifications and push notifications. You can create a bool-type switch for each of these notifications in the properties window (it will require at least four variables) or reduce the number of variables to one string variable.
If you need to enable sound notifications, you write "s" (sound). If you also need to have e-mail notifications, you add "e". Thus, you can enable any combination of notifications using just one variable. For an Expert Advisor, the number of external parameters is of little importance. It is just a matter of user-friendliness.
On the other hand, when developing indicators you should seek to reduce the number of external parameters. It is very likely that the indicator will be called from an Expert Advisor or another indicator using the iCustom() or IndicatorCreate() functions whose number of parameters is limited (iCustom() only has 64 parameters and the parameter array size of the IndicatorCreate() function is 64 elements). Use of strings may therefore be of great practical value.
This article will review all standard MQL5 functions for working with strings and we will also create a few useful custom functions.
Declaring a String Variable
Like any other type of variables, string variables can be declared:
string str;
or assigned a value upon being declared (initialized to a value):
string str="Any text";
There are no restrictions as to the length of the string. A long string can for the sake of convenience be split into several substrings:
string str= "A long string can be " "split into several " "substrings"; //--- output the results Alert(str);
When initialized this way, the str variable will have the string containing "A long string can be split into several substrings".
Leaping slightly ahead here, we should note that the value of a string variable declared without parameters is not identical to an empty string:
string str="";
You can see it for yourself:
string str1; string str2=""; //--- output the comparison results Alert(str1==str2);
When running this code, a window alerting "false" will pop up. Uninitialized string variable has the NULL value which is not the same as an empty string "". You should keep that in mind! When working with strings, we very often have to check whether a string is empty. Therefore you should either stick to the rule of initializing all strings with an empty string "" or check them for being not equal to "" and not equal to NULL:
if(str!="" && str!=NULL) { //--- some operation with a string }
The first method is more advisable as it simplifies the checking condition.
You can do the same when checking the size of a variable. To determine the size, we use the StringLen() function:
if(StringLen(str)!=0) { //--- some operation with a string }
Concatenating Strings
The main, most common operation you get to perform when working with strings is concatenating them, i.e. building phrases using words. Concatenation is implemented using the "+" sign:
string str1,str2,str3,str4,str5; //--- assign values str1="Programming"; str2="in MQL5"; str3="for MetaTrader 5"; //--- add up the strings str4=str1+" "+str2; str5=str1+" "+str3; //--- output the results Alert(str4); Alert(str5);
Following the execution of this code the str4 variable will contain "Programming in MQL5", while the str5 variable will contain "Programming for MetaTrader 5". The above example has demonstrated how you can concatenate two strings, with the resulting string being assigned to another variable.
An additional string is very often concatenated with the main string:
string str1,str2,str3; //--- assign values str1="Programming"; str2="in MQL5"; str3="for MetaTrader 5"; //--- add up the strings to the main string str1=str1+" "+str2; str1=str1+" "+str3; //--- output the results Alert(str1);
Following the execution of this code the str1 string will contain "Programming in MQL5 for MetaTrader 5". The above example has demonstrated how you can concatenate strings with the main str1 string, with the result being assigned to the latter. The same operations can be written in a much simpler way:
str1+=str2; str1+=str3;or:
str1+=str2+str3;
The "+" sign to the left of "=" means that the expression to the right of "=" is appended to the str1 variable.
You can also add a string to the beginning of the main string. This can be implemented as shown in the second to last example: the main string is added to the additional string and the resulting string is assigned to the main variable:
string str1,str2,str3; //--- assign values str1="Programming"; str2="in MQL5"; str3="for MetaTrader 5"; //--- concatenate strings, with a string being added to the beginning str3=str2+" "+str3; str3=str1+" "+str3; //--- output the results Alert(str3);
The following phrase: "Programming in MQL5 for MetaTrader 5" will now be in the str3 variable. You can implement the same using a single string:
str3=str1+" "+str2+" "+str3;In some cases you can perform the concatenation using "," (comma). It is possible when calling the Alert(), Print() or Comment() functions:
Print(str1," ",str2," ",str3);
The end results will in this case be identical to using the "+" sign:
Print(str1+" "+str2+" "+str3);
The "," symbol does not in fact concatenate strings. A comma is a separator of parameters in all functions. It is also true for the Alert(), Print() and Comment() functions. These functions have one mandatory parameter and a lot of optional parameters. Parameters are in effect passed to the function where they are concatenated. The maximum number of parameters is 64.
We can see something similar when writing a string to a file using the FileWrite() function. However, if you open a file in the FILE_CSV mode (with field separators), commas will be replaced with the separator character specified when opening the file (if the separator is not specified, tabbing is used by default). When opening a file in the FILE_TXT mode without specifying the separator, the results of using the "+" sign and "," will be the same:
//--- write to the first file int h=FileOpen("1.txt",FILE_WRITE|FILE_ANSI|FILE_CSV); FileWrite(h,"1","2","3"); FileClose(h); //--- write to the second file h=FileOpen("2.txt",FILE_WRITE|FILE_ANSI|FILE_CSV); FileWrite(h,"1"+"2"+"3"); FileClose(h); //--- write to the third file h=FileOpen("3.txt",FILE_WRITE|FILE_ANSI|FILE_TXT); FileWrite(h,"1","2","3"); FileClose(h); //--- write to the fourth file h=FileOpen("4.txt",FILE_WRITE|FILE_ANSI|FILE_TXT); FileWrite(h,"1"+"2"+"3"); FileClose(h);
After executing this code, the 1.txt file will contain "1 2 3", while the 2.txt file will contain "123" (files have been opened in the FILE_CSV mode). 3.txt and 4.txt will have identical content: "123" (opened in the FILE_TXT mode). This article does not center around file operations. Therefore, if there is anything in the last example that does not seem clear to you, never mind as it will not affect your understanding of the material set forth further in this article. Just note that the use of "+" and "," does not always produce the same effect when dealing with the addition of strings.
In addition to the "+" sign, MQL5 provides special functions for the addition of strings: StringAdd() and StringConcatenate(). According to the description of these functions in MQL5 Reference, they allow us to add up strings in a more space efficient (in terms of the occupied working memory) and faster way. The StringAdd() function allows us to add one string to another:
string str1,str2,str3; //--- assign values str1="Programming"; str2="in MQL5"; str3="for MetaTrader 5"; //--- call the function to concatenate strings StringAdd(str1," "); StringAdd(str1,str2); StringAdd(str1," "); StringAdd(str1,str3); //--- output the results Alert(str1);
Following the execution of this code the str1 variable will have the string containing "Programming in MQL5 for MetaTrader 5".
The StringConcatenate() function allows you to simultaneously combine several strings. The first parameter passed to the function is the variable of the string to which further listed strings will be added. The maximum number of parameters you can pass to the function is 64:
string str1,str2,str3; //--- assign values str1="Programming"; str2="in MQL5"; str3="for MetaTrader 5"; //--- call the function for combining several strings StringConcatenate(str1,str1," ",str2," ",str3); //--- output the results Alert(str1);
After executing this code, the str1 variable will also contain "Programming in MQL5 for MetaTrader 5".
Converting Various Variables to a String
When generating a message string, we very often need to add values of numerical variables. To convert values of integer variables (char, uchar, bool, short, ushort, int, uint, color, long, ulong, datetime) to a string, we use the IntegerToString() function:
int x=1; string str="x = "+IntegerToString(x);
When converting a bool type variable, a returned string will contain either "0" (false) or "1" (true). Similarly, if you convert color or datetime type variables, a returned string will contain a numerical expression of color or date (e.g. "65535" for the yellow color of clrYellow or "1325376000" for the date as follows: 2012.01.01 00:00).
To convert real variables (double, float) to a string, we use the DoubleToString() function. The second parameter of this function determines the precision (the number of decimal places):
double x=1.23456; string str1="x = "+DoubleToString(x,2); string str2="x = "+DoubleToString(x,3);
Following the execution of this code, the str1 variable will contain the string "1.23", while the str2 variable will contain the string "1.235". Truncation to the specified number of digits is performed using the mathematical rounding rules.
The TimeToString() function is used to convert date and time to a standard format string (readily understandable by human beings):
datetime tm=TimeCurrent(); // Current time string str1=IntegerToString(tm); string str2=TimeToString(tm);
After the execution of this code the str1 variable will contain the string with a numerical expression of time (the number of seconds elapsed since January 1, 1970), while the str2 variable will contain the formatted time, e.g. "2012.11.02 22:00" (year, month, day, hour, minute).
When calling the TimeToString() function, you have an option to specify the date and time format. Available options are:
string str1="Date and time with minutes: "+TimeToString(tm); string str2="Date only: "+TimeToString(tm,TIME_DATE); string str3="Time with minutes only: "+TimeToString(tm,TIME_MINUTES); string str4="Time with seconds only: "+TimeToString(tm,TIME_SECONDS); string str5="Date and time with seconds: "+TimeToString(tm,TIME_DATE|TIME_SECONDS);
MQL5 offers a great handy feature to create enumerations that are displayed in the program properties window as drop-down lists of options. Values of such variables can also be converted to a string using the EnumToString() function. Below is the script code demonstrating the operation of this function:
//+------------------------------------------------------------------+ //| Create an enumeration | //+------------------------------------------------------------------+ enum EMode { OFF=0, Mode1 = 1, Mode2 = 2, Mode3 = 3 }; //+------------------------------------------------------------------+ //| Start the script | //+------------------------------------------------------------------+ void OnStart() { EMode Value=1; //--- join strings together string str="The "+IntegerToString(Value)+ value" corresponds to "+EnumToString(Value)+ entry" of the Emode enumeration"; //--- output the results Alert(str); }There is a similar possibility allowing you to convert variables of color. You can convert the color value to the name of the color using the ColorToString() function:
color ColorValue=clrRed; string str=ColorToString(ColorValue,true);
After executing this code, the str variable will store the string containing "clrRed". If the second parameter is set to false, the function will return the string with values of RGB components (red, green and blue):
color ColorValue=clrRed; string str=ColorToString(ColorValue,false);
In this case, the string stored in the str variable will be "255,0,0". If the color you deal with is non-standard (not defined on the web color palette and consequently without a name), the ColorToString() function can be used to return the string with values of components regardless of the second parameter value.
There is yet another method for converting variables using type casting:
int x=123; string str=(string)x;
When a bool type variable is converted this way, the string value will either be " true" or "false":
bool x=true; string str=(string)x;
Converting double and float type variables should be as precise as possible, allowing you to only drop zeros in the fractional part:
double x1=0.1; double x2=0.123; string str1=(string)x1; string str2=(string)x2;
Following the execution of this code the str1 variable will store the string value of "0.1" and the str2 variable will contain the string value of "0.123".
Special Character Output
When initializing a string variable to a value, the assignable string should be written in double quotation marks so that the compiler can distinguish the string from the program code. To be able to put the quotation marks inside the string, you need to specify the fact that the marks are not used here for their regular purpose (as characters separating a string from a code) but rather as a part of a string. To implement this, put a backslash "\" right before the quotation mark:
string str1="Simple text"; string str2="\"Text in quotes\""; //--- output the results Alert(str1); Alert(str2);
Since the backslash is also considered to be one of the special characters, another backslash must be put in front of it to implement the output of the backslash in a string:
string str="\\"; Alert(str);
After executing this code, the only character the string will contain will be "\".
A string can also contain a horizontal tab character represented by "\t":
string str="Column-1\tColumn-2\tColumn-3"; Alert(str);
In this case, the str variable will have the string containing "Column-1 Column-2 Column-3".
A text can also be printed with line breaks, split into several lines using "\n":
string str="Line-1\nLine-2\nLine-3"; Alert(str);
Here, as a result of executing the Alert() function, you will have three lines of text.
When printing using the Alert() and MessageBox() functions, as well as when writing to a file, you can use both "\t" and "\n". However when printing to a chart comment (the Comment() function), only "\n" applies as a wrapping character, while the tab character "\t" is ignored. When output is done using the Print() function, "\n" applies as before (every part of a string is output in a separate line of the journal) and "\t" is replaced with a space like in the log file that stores all the messages output using the Print() function.
Pattern-Based Formatting of Strings
When formatting a string for output, you may need to include in it values of several numerical variables. This can be achieved by adding up strings and converting numerical variables to strings. However in this case, the string of code building a message will be too long and difficult to understand and edit, should any modifications of the program be necessary:
//--- initialize the variables int Variable1=1; int Variable2=2; int Variable3=3; //--- long addition of strings string str="Variable1 = "+IntegerToString(Variable1)+", Variable2 = "+IntegerToString(Variable2)+", Variable3 = "+IntegerToString(Variable2); //--- output the results Alert(str);
The same task can be solved in a much easier way using the StringFormat() function. The first parameter passed to this function is a message template, with indicated places for inserting variables and set output format. It is followed by enumeration of all variables in the order in which they appear in the template:
//--- initialize the variables int Variable1=1; int Variable2=2; int Variable3=3; //--- simpler addition of strings string str=StringFormat("Variable1 = %i, Variable2 = %i, Variable3 = %i",Variable1,Variable2,Variable3); //--- output the results Alert(str);
The places for inserting variables are marked with "%" followed by "i", which in the above example denotes that the variables must be output as integers. Or rather, "i" stands for character integer variables (char, short, int, color), whereas we use "u" for unsigned integer variables (uchar, bool, ushort, uint). For variables of the long, ulong and datetime data type, you should additionally specify the size of the variable by putting "I64" before the type:
string LongMin=StringFormat("%I64i",LONG_MIN); string LongMax=StringFormat("%I64i",LONG_MAX); string ULongMax=StringFormat("%I64u",ULONG_MAX); string DateTimeMax=StringFormat("%I64u",DateMax); //--- output the results Alert("LongMin = "+LongMin); Alert("LongMax = "+LongMax); Alert("ULongMax = "+ULongMax); Alert("DateTimeMax = "+DateTimeMax);As a result of this code, you will see a pop-up window with variable values.
The format of real numbers is denoted by "f":
double Percents=5.5; //--- real number as a string string str=StringFormat("Percents = %f",Percents); //--- output the results Alert(str);
After executing this code, the str variable will store the following string: "Percents = 5.500000". The default output precision is six decimal places. You can set the required number of decimal places:
string str=StringFormat("Percents = %.2f",Percents);
For this purpose, put a dot denoting a decimal symbol immediately followed by the number of decimal places, e.g. 2 as in the example above. In this case the str variable will contain the string as follows: "Percents = 5.50". This formatting option is completely identical to the DoubleToString() function.
You can specify the total length of a number by writing "0" and a number that determines the length of the number at hand right after "%" and then specify the number of decimal places (if necessary):
string str=StringFormat("Percents = %06.2f",Percents);
Here, we have a total length of 6 digits, one of which will be used for the decimal point and two more will represent two decimal places. Therefore, the string stored in the str variable will be "Percents = 005.50".
If you need to output the percent sign "%" in a message, you need to write it two times in a row, i.e. "%%", since one of them will be used to indicate places for inserting values:
string str=StringFormat("Percents = %06.2f%%",Percents);
In this case, the str variable will contain "Percents = 005.50%".
You can also determine the length of a number when outputting integer variables:
int Variable=123; //--- integer as a string with a set output length string str=StringFormat("Variable = %05i",Variable); //--- output the results Alert(str);
After the execution of this code the str variable will store the following string: "Variable = 00123".
If the number of digits specified is less than the number of digits in the number, the output will still be done correctly:
string str=StringFormat("Variable = %02i",Variable);
Here, the str variable will contain the string as follows: "Variable = 123", i.e. the output number will have 3 digits despite the fact that the specified length is 2.
Real numbers can be output using scientific notation (mantissa of six decimal places and power) for which we use the "e" character:
double Variable=123.456; //--- real number as a string in scientific notation string str=StringFormat("Variable = %e",Variable); //--- output the results Alert(str);
After executing this code, the str variable will contain "1.234560e+002". You can also use the capital "E" whose effect is similar to the lowercase "e", with the capital "E" replacing the lowercase "e" in a formatted string.
There is yet another way of formatting real numbers - using "g" whereby only six digits (excluding any decimal point) can be output. If the length of the integer part of a number exceeds six digits, the number will be output using scientific notation:
double Variable1=12.3456789; double Variable2=1234567.89; //--- get real numbers as strings using "g" string str1=StringFormat("Variable = %g",Variable1); string str2=StringFormat("Variable = %g",Variable2); //--- output the results Alert(str1+" "+str2);
In the above example, the str1 variable will contain "12.3457" and the str2 variable will contain "1.23457e+006". The effect will be the same if you use the capital "G" instead, with the only difference being that in the output the lowercase "g" will be replaced with the capital "G".
The StringFormat() function allows you to transform number representation formats, i.e. to convert numbers of the decimal system to the octal or hexadecimal system. To convert a number to the octal system, you need to use the "o" character:
int Variable=17; //--- real number as a string in the octal system string str=StringFormat("Variable = %o",Variable); //--- output the results Alert(str);
Following the execution of this code the str variable will store the string as follows: "Variable = 21" (8*2+1=17).
"x" or "X" is used to convert a number to the hexadecimal system. In such a case, if you use the lowercase "x", a hexadecimal system number will consist of lowercase letters, or uppercase letters, if the capital "X" is used:
color Variable=clrBlue; //--- real number as a string in the hexadecimal system string str=StringFormat("Variable = %x",Variable); //--- output the results Alert(str);
After executing this code, the str variable will contain "Variable = ff0000".
Similarly, you can convert a number of the hexadecimal system back to the decimal system using the "d" character:
int Variable=0x0000ff; //--- real number as a string in the decimal system string str=StringFormat("Variable = %d",Variable); //--- output the results Alert(str);
After the execution of this code, the string that the str variable will store, will be "Variable = 255".
The "s" character can be used to output string variables:
string Variable="text"; //--- output the string variable string str=StringFormat("Variable = %s",Variable); //--- output the results Alert(str);
As soon as you execute the above code, the string containing "Variable = text" will be stored in the str variable.
Sometimes you may need to align numbers when outputting them in a column, given the fact that negative numbers shift because of the "-" sign. To align positive numbers with negative, you should add a space to the beginning of the string, right after "%". In this case, negative numbers will be output without a space unlike positive numbers that will have a space at the beginning:
int Variable1=1; int Variable2=-1; //--- representation of numbers as aligned strings string str1=StringFormat("Variable1=% 03i",Variable1); string str2=StringFormat("Variable2=% 03i",Variable2); //--- output the results Alert(str1); Alert(str2);
Following the execution of this code, the str1 variable will contain "Variable1= 01" (the string with a space), while the str2 variable will store the string as follows: "Variable2=-01".
There are two more functions similar to StringFormat(). These are PrintFormat() and printf() that are absolutely identical in terms of action. Their only difference from the StringFormat() function is that they output text to the journal in the manner similar to the Print() function.
In fact, the StringFormat() function offers much more functionality, while the material provided above represents the minimum required to solve the majority of problems regarding formatting numbers for output.
Messages in Different Languages
The StringFormat() function gives you an opportunity to enhance your program with a very useful feature that provides printing of messages in different languages, depending on the interface language set in the terminal.
You can find out what interface language is set by calling the TerminalInfoString() function with the TERMINAL_LANGUAGE identifier. When running a program, we prepare a format string depending on the interface language and then use it in the program. Below is a template of an Expert Advisor with the above feature implemented:
//--- variable for a format string string FormatString; //+------------------------------------------------------------------+ //| Handling the Init event | //+------------------------------------------------------------------+ int OnInit() { //--- get the format string FormatString=GetFormatString(); //--- additional call in case you want to ensure that the Expert Advisor operates at least once at weekends OnTick(); return(0); } //+------------------------------------------------------------------+ //| Handling the Tick event | //+------------------------------------------------------------------+ void OnTick() { int Variable1,Variable2,Variable3; Variable1=MathRand()%10; // Random number from 0 to 10 Variable2=MathRand()%10; // Another random number Variable3=Variable1+Variable2; // Sum of numbers //--- output the results Alert(StringFormat(FormatString,Variable1,Variable2,Variable3)); } //+------------------------------------------------------------------+ //| Determining the format string | //+------------------------------------------------------------------+ string GetFormatString(void) { string Language=TerminalInfoString(TERMINAL_LANGUAGE); //--- language check if(Language=="Russian") return("%i плюс %i равно %i"); // Russian if(Language=="Spanish") return("%i más %i es igual a %i"); // Spanish //--- English - in all other cases return("%i plus %i equals %i"); }
The Expert Advisor calculates the sum of two random numbers and outputs the message regarding its actions, e.g. "1 plus 2 makes 3".
That's about it regarding the output of strings. We will now proceed to slightly more complex, yet more interesting string manipulations.
Key Functions for Working with Strings
If a string is input through the program properties window or read from a file, it may contain unnecessary spaces. They may appear due to a casual carelessness of the user or out of convenience. Before using the string in any way, it is advisable to delete spaces at the left and right end. For this purpose, MQL5 offers two functions - StringTrimLeft() (deletes spaces at the left end) and StringTrimRight() (deletes spaces at the right end). In addition to spaces, these functions also remove tab and new line characters. When working with strings, we often need to delete spaces at both ends at once, so a function that implements this will be very useful:
string Trim(string Str) { StringTrimLeft(Str); StringTrimRight(Str); return(Str); }
When inputting real numbers, the user may often put a comma instead of a dot. Therefore when working with real numbers you should provide the possibility of using both the dot and comma as a decimal symbol. To replace one string with another, we use the StringReplace() function:
string str="123,456"; //--- replace a comma with a dot StringReplace(str,",","."); double Value=StringToDouble(str); //--- output the results Alert(DoubleToString(Value));
If you do not replace "," with ".", the fractional part of the number will be truncated in converting a string to a number.
In some cases, you may be required to replace a series of spaces with one space. To do this, you should first replace the tab characters with a space and then replace two spaces with one until there is only space left:
string str="Column-1 \t Column-2 \t Column-3"; //--- replace the tab character with a space StringReplace(str,"\t"," "); //--- get one space instead of the series of spaces while(StringReplace(str," "," ")>0){} //--- output the results Alert(str);
The StringReplace() function returns the number of replacements made or -1 in case of an error. So the loop continues with the function returning a value greater than zero until all series of spaces are replaced with one space which is left in each single case. The body of the loop does not contain any code. When checking the loop condition at every iteration, we call the StringReplace() function.
The StringReplace() function allows us to replace substrings of different lengths:
string str="Programming in MQL5!"; //--- replace the substring, output the results StringReplace(str,"in MQL5","for MetaTrader 5"); Alert(str); //--- reverse replacement, output the results StringReplace(str,"for MetaTrader 5","in MQL5"); Alert(str);
When executing this code, the str variable after the first replacement will have the string containing "Programming for MetaTrader 5", and "Programming in MQL5!" following the second replacement.
The StringFind() function is used to search for a substring. It returns the index of the first occurrence of the substring in a string. The first parameter passed to the function is a string where the search is performed. The second parameter determines the target substring, while the third parameter (optional) can determine the position at which the search starts. If the third parameter is not specified, the function operates as if its value were 0, i.e. the search starts at the very beginning of the string. Let us find the position of substring "5" in the "Programming in MQL5 for MetaTrader 5" string:
string str="Programming in MQL5 for MetaTrader 5"; //--- get the position of the character int Pos=StringFind(str,"5"); //--- output the results Alert(IntegerToString(Pos));
Following the execution of this code, the Pos variable value will be 23. Substring "5" occurs two times total but the function only returns the position of the first occurrence. If you count the position by simply looking at the string, you will get 24. The thing is that the function starts counting from zero, rather than from one. If the target substring is not found in the string, the function returns -1.
Once in a while, you may need to find a position of the last occurrence of the substring. For this purpose, we will have to write a custom function, StringFindRev(). We will start with searching for the first occurrence of the substring, then shift the start of the search according to the position found, etc. in a loop:
int StringFindRev(string Str,string Find) { //--- the pos variable for the returned value int pos; //--- auxiliary variable initialized to -1, //--- in case the substring is not found in the string int tmp=-1; //--- loop. It will be executed at least once do { //--- assign the last known position of the substring pos=tmp; //--- continue searching (using the third parameter of the function) tmp=StringFind(Str,Find,tmp+1); } while(tmp!=-1); // If the substring is not found in the remaining part of the string, the loop // is terminated and the pos variable stores the last // known position //--- return the position return(pos); }Let us try to use this function:
string str="Programming in MQL5 for MetaTrader 5"; //--- call the function for searching for a position of the last occurrence of the character in the string int pos=StringFindRev(str,"5"); //--- output the results Alert(pos);
After executing this code, the Pos variable will have the value of 40.
The StringSubstr() function is used to get a substring of a given length from a given position. Get the substring of the length of 1 from position 23:
string str="Programming in MQL5 for MetaTrader 5"; //--- get the substring of the given length from the given position string str2=StringSubstr(str,23,1); //--- output the results Alert(str2);
The resulting figure is "5".
Now that we have considered the main functions, let us use them to write a useful function for deleting a given list of characters from a string. The function receives the source string and a string that represents a list of characters to be deleted from the source string.
string TrimL(string Str,string List="\t\n ;") { //--- variable for one character of the Str string string ch; int Len=StringLen(Str); int i=0; //--- loop iteration over all characters of the Str string for(;i<Len;i++) { //--- the next character of the Str string ch=StringSubstr(Str,i,1); //--- if this character is not on the List list, the string should start from this position if(StringFind(List,ch,0)==-1) { break; // terminate the loop } } //--- get the substring and return it return(StringSubstr(Str,i)); }
The function deletes the tab and new line character, as well as a space and semicolon ";" by default.
The same function for deleting at the right end:
string TrimR(string Str,string List="\t\n ;") { //--- variable for one character of the Str string string ch; int Len=StringLen(Str); //--- characters in the string are numbered from 0, so the last character index is one less than the string length int i=Len-1; //--- loop iteration over all characters of the Str string for(;i>=0;i--) { //--- the next character of the Str string ch=StringSubstr(Str,i,1); //--- if this character is not on the List list, the string should start from this position if(StringFind(List,ch,0)==-1) { break; // terminate the loop } } //--- get the substring and return it return(StringSubstr(Str,0,i+1)); }
This function also deletes the tab and new line character, as well as a space and semicolon ";" by default. It can prove useful when reading CSV files. Inside these files, there may be a lot of field separators (usually semicolons ";") at the right end of a string.
Uppercase and lowercase letters, e.g. "А" and "а" are not seen as different in meaning by humans, whereas computers treat them as two completely different characters. If you write "eurusd" instead of "EURUSD" when requesting the market data using the SymbolInfoDouble() function, the function will not return the required value. This is very likely to happen when inputting the symbol name in the properties window. To change the case in MQL5, you can use the StringToLower() function (to change to lower case) and StringToUpper() function (to change to upper case):
string str="EuRuSd"; string str1=str; string str2=str; //--- change the case of strings StringToUpper(str1); StringToLower(str2); //--- output the results Alert(str1," ",str2);
Following the execution of this code, the str1 variable will store the string that contains "EURUSD", while the str2 variable will have the string containing "eurusd".
If what you need is to compare the strings without taking their case into consideration, the StringCompare() function will be the best fit. The first two parameters of the function are the strings for comparison. The third parameter determines whether the strings should be compared, taking (true) or not taking (false) into account their case:
int Result=StringCompare("eurusd","EURUSD",false); Alert(Result);
If the function returns 0, the strings are identical. The function may return -1 if the first string is less than the second one, or 1 if the first string is greater than the second one. "Greater" and "less" mean the state of the string when sorted alphabetically. The letter "b" is greater than the letter "a":
int Result=StringCompare("a","b",true); Alert(Result);
In this case, the function will return -1.
Now, before we continue with other functions, it is necessary to make a brief theoretical digression.
Strings as Seen by Men and Computers
What a string is for a man is quite clear - it is a text made of characters. Computer, compared to a human being, is somewhat simpler in structure, only dealing with numbers. Computer sees images, strings and everything else as numbers. A string is an array of numbers where one character corresponds to one number, or rather a code, another character to another code, etc. These codes are called ASCII codes (short for the American Standard Code for Information Interchange). We will further below use the term ASCII, implying extended ASCII that contains 256 codes. Thus, we can say that the computer "alphabet" consists of 256 characters. Just like there are different alphabets for different peoples and languages, computer has various character sets - code pages. Computer users in Russia mostly get to use Windows-1251, a character encoding that includes Latin and Cyrillic characters, as well as numbers, punctuation marks and some other symbols. Fig. 1 shows the Windows-1251 code page:
Fig. 1. Windows-1251 code page.
The first 32 characters are not displayed, those are control characters. They are not displayed as such but affect the display of other characters, e.g. tab (code 9), line feed (code 10), etc.
The encoding used to represent texts in Central European languages is Windows-1250 (Fig. 2):
Fig. 2. Windows-1250 code page.
Please note that starting with code 192 where code page 1251 features letters of the Russian alphabet, code page 1250 has letters that contain diacritics (letters with diacritical marks that determine slight changes in sound value) in European languages.
256 characters are a very small number. Difficulties arise if a text needs to be written in several languages, e.g. Russian and French (has a great number of diacritical marks) or English and Arabic (characters are very different from characters in other languages). There is also hieroglyphic script, as in Chinese and Japanese, that has thousands of characters and difficulties in this case are even more obvious. You may need to encode characters not included in their code page using some other way. Those of you who are familiar with HTML, should know about the possibility of inserting non-standard characters into a HTML page, e.g. the code À is used to display À and Á to render Á, etc.
It has recently become common to use the Unicode encoding where one character is encoded not in a single byte (number from 0 to 255), but two bytes, thus totaling 65536 characters. This character set includes letters of all alphabets existing in the world and even the most common hieroglyphs as shown in Fig. 3 (the appropriate fonts should still be installed on your computer):
Fig. 3. Letters of different alphabets and hieroglyphs.
Strings in MQL5 are encoded using Unicode. In other words, a character in a string can be represented by a number from 0 to 65535. Characters with codes from 0 to 127 are the same in ASCII and Unicode. Text files can contain texts encoded using ASCII or Unicode and consequently the MQL5 functionality for working with strings in ASCII and Unicode is different.
Converting a String to an Array and Back to String
When working with strings, the StringLen(), StringFind(), StringSubst() and StringReplace() functions usually suffice to solve the majority of practical tasks. But there may be tasks that are much easier solved working with strings as numbers, such as encryption, data compression, calculation of check values. Although tasks of that type are not dealt with on a daily basis, it is possible that you will need to solve them some day. There are also more important tasks that require a string to be converted to an array, i.e. passing string parameters to the Windows API (Application Programming Interfaces) functions.
To convert a string to a Unicode array, we use the StringToShortArray() function and to convert to an ASCII array - the StringToCharArray() function:
string str="MetaTrader 5"; //--- converting the string to a Unicode array short sha[]; StringToShortArray(str,sha); //--- converting the string to a ASCII array uchar cha[]; StringToCharArray(str,cha); //--- flag the difference bool Dif=false; //--- compare the arrays element by element for(int i=0;i<StringLen(str);i++) { if(sha[i]!=cha[i]) { Dif=true; } } //--- output the results if(Dif) Alert("Different"); else Alert("Identical");
If the arrays obtained using the StringToShortArray() and StringToCharArray() functions in the above example are identical, a window will pop up with the message "Identical" and if there are differences, the message will read "Different". For the "MetaTrader 5" string, the arrays are identical because the string consists of characters with character codes up to 127.
It is all a bit different with character codes above 127. The results of the StringToShortArray() function operation will always be the same everywhere, while the results of the StringToCharArray() function operation will depend on the regional settings of the operating system.
In Windows 7, the language of the system can be selected in Control Panel - Region and Language - Change display language.
Have a look at the following example. In code page 1251, code 192 corresponds to the letter "А" (first letter of the Russian alphabet), while the same code in encoding 1250 corresponds to the letter "Ŕ" (one of the most commonly known letters of the Czech alphabet). When using the StringToShortArray() function, the letter "А" will always have code 1040, while the letter "Ŕ" code 340. If the system is set to the Russian language, then when using the StringToCharArray() function the letter "А" will correspond to code 192 (correct), while the letter "Ŕ" will correspond to code 82 (Latin "R"). If however the system is set to the Czech language, the letter "А" will correspond to code 63 (question mark) and the letter "Ŕ" will correspond to code 192 (correct). Characters that contain diacritics are replaced with similar Latin characters, while not so common characters are replaced with a question mark.
Please note the size of the string and resulting arrays:
int StrLen=StringLen(str); int shaLen=ArraySize(sha); int chaLen=ArraySize(cha); //--- output the lengths Alert(StringFormat("%i, %i, %i",StrLen,shaLen,chaLen));
The number of elements in the arrays is more than the number of characters in the string by one. This has to do with the fact that the end of the string is marked by the character with code 0. This character is not displayed in the string but it is meaningful for computer denoting the end of the string displayed. Data exchange is not always performed with a rate of one byte (character) at a time in the amount corresponding to the string length but the character with code 0 enables you to determine the end of the string in any case. The same zero may also cause problems, e.g. a certain character can be converted to the character with code 0 when encrypting or applying a compression algorithm. In this case, if you inverse convert an array to a string, the string will not be complete. Tasks of this type require the use of special tricks but this is beyond the scope of this article.
The inverse conversion of an array to a string is possible using the ShortArrayToString() and CharArrayToString() functions:
//--- convert an array of Unicode codes to a string short sha[]={85,110,105,99,111,100,101}; string str1=ShortArrayToString(sha); //--- convert an array of ASCII codes to a string uchar cha[]={65,83,67,73,73}; string str2=CharArrayToString(cha); //--- output the results Alert(str1+" "+str2);
As a result of the above code, the str1 variable will store the "Unicode" string and str2 will store the "ASCII" string.
There are two more similar functions: ShortToString() and CharToString(). They convert a single variable of the short or char type to a string consisting of one character. The CharToString() function has a great practical value. A graphical object that allows you to display different symbols, OBJ_ARROW, is anchored to the price axis vertically and to the time axis horizontally so the symbols shift as you scroll through the chart. Using OBJ_LABEL along with the Wingdings font enables us to display different symbols anchored to the coordinates on the screen thus allowing us to create various information panels. We find the required symbol in the Wingdings symbol table, convert its code to a string which is further displayed using the OBJ_LABEL graphical object:
ObjectCreate(0,"lbl",OBJ_LABEL,0,0,0); // create the LABEL graphical object ObjectSetInteger(0,"lbl",OBJPROP_XDISTANCE,100); // set the X-coordinate ObjectSetInteger(0,"lbl",OBJPROP_YDISTANCE,100); // set the Y-coordinate ObjectSetInteger(0,"lbl",OBJPROP_FONTSIZE,20); // set the size ObjectSetString(0,"lbl",OBJPROP_FONT,"Wingdings"); // set the Wingdings font string Icon=CharToString(37); // 37 - the bell ObjectSetString(0,"lbl",OBJPROP_TEXT,Icon); // set the displayed text
As a result of this code, you will see an icon of a bell in the chart. The bell will remain in its place as you scroll through the chart.
Two more functions for working with character codes are StringGetCharacter() and StringSetCharacter(). They work with Unicode codes. The StringGetCharacter() function allows you to get the code of the character at a given position in the string:
string str="L5"; //--- get the Unicode code of the character at the given position in the string ushort uch1=StringGetCharacter(str,0); ushort uch2=StringGetCharacter(str,1); //--- output the results Alert(StringFormat("%i, %i",uch1,uch2));
Following the execution of this code, the uch1 variable will store the value of 76 and uch2 will store 53.
The StringSetCharacter() function allows you to change the code of the character at a given position, as well as to add a character at the end of a string:
string str="MQ5"; //--- replace the character at the given position in the string with the Unicode character corresponding to the passed code StringSetCharacter(str,2,76); Alert(str); //--- add the Unicode character corresponding to the passed code to the end of the string StringSetCharacter(str,3,53); Alert(str);
When executing this code, the str variable instead of "MQ5" will first store "MQL" and then "MQL5".
Calling API Functions
Some API functions use string parameters as their variables. For example, the function for third party applications WinExec uses an array of the uchar type as its first parameter:
#import "kernel32.dll" int WinExec(uchar &Path[],int Flag); #import
Let us try to run notepad.exe (Notepad), a standard Windows program. Convert the path to the notepad to an array of the uchar type:
string PathName="C:\\WINDOWS\\notepad.exe"; uchar ucha[]; StringToCharArray(PathName,ucha); int x=WinExec(ucha,1);
This function operation should result in opening the Notepad text editor.
Another example of using string parameters in API functions is the MessageBoxW function that prints a message in the window using Unicode. For this reason, we will pass arrays of the ushort type as its parameters:
#import "user32.dll" int MessageBoxW(int hWnd,ushort &szText[],ushort &szCaption[],int nType); #import
Now use this function to print a message in the window:
ushort arr[]; ushort capt[]; //--- convert StringToShortArray("Programming in MQL5 for MetaTrader 5.",arr); StringToShortArray("Message",capt); //--- print the message MessageBoxW(0,arr,capt,0);
As a result of this code, you will be able to see a window with the following message: "Programming in MQL5 for MetaTrader 5".
It should be noted that the use of arrays of the ushort type in the above example is not necessary and you can simply pass strings as the function parameters:
#import "user32.dll" int MessageBoxW(int hWnd,string szText,string szCaption,int nType); #import //+------------------------------------------------------------------+ //| Function for running the script | //+------------------------------------------------------------------+ void OnStart() { MessageBoxW(0,"Programming in MQL5 for MetaTrader 5","Message",0); }
The result of this code will be the same as above. However you will not be able to use arrays of the uchar type as the function parameters, in order to print the correct message:
#import "user32.dll" int MessageBoxW(int hWnd,uchar &szText[],uchar &szCaption[],int nType); #import //+------------------------------------------------------------------+ //| Function for running the script | //+------------------------------------------------------------------+ void OnStart() { uchar arr[]; uchar capt[]; //--- convert StringToCharArray("Programming in MQL5 for MetaTrader 5.",arr); StringToCharArray("Message",capt); //--- print the message MessageBoxW(0,arr,capt,0); }
The code will be executed error-free and a pop up window will appear however the message will be distorted.
For cases where it is necessary to print a string in the ASCII encoding (e.g. if you already have an array of the uchar type), there is a similar function, MessageBoxA. To correctly display the message, only arrays of the uchar type should be passed to the function as string parameters. Now import this function and call it to print the message:
#import "user32.dll" int MessageBoxA(int hWnd,uchar &szText[],uchar &szCaption[],int nType); #import //+------------------------------------------------------------------+ //| Function for running the script | //+------------------------------------------------------------------+ void OnStart() { uchar arr[]; uchar capt[]; //--- convert StringToCharArray("Programming in MQL5 for MetaTrader 5",arr); StringToCharArray("Message",capt); //--- print the message MessageBoxA(0,arr,capt,0); }
And we again get the correct message "Programming in MQL5 for MetaTrader 5".
Basically, there are 2 options for many of the WinAPI functions that work with strings - the option for working with ASCII strings and the option for working with Unicode strings.
To be able to call the functions, enable the use of DLLs in the terminal settings (Terminal - Main Menu - Tools - Options - Expert Advisors - Allow DLL imports) or check "Allow DLL imports" in the Dependencies tab of the properties window when running a script, Expert Advisor or indicator. Specify the appropriate script property so as to enable the opening of the properties window for the script:
#property script_show_inputs
Unlimited Parameter Input
The user inputs parameters in the properties window, separating them by a semicolon:
input string Lots="0.1; 0.2; 0.3; 0.5";
We need to convert this string to an array of variables of the double type.
In MQL5, a string can be split using the StringSplit() function. The first parameter passed to the function is a string, the second parameter is the ASCII code of the separator and the third parameter passed is an array that will store the function operation results. There is a very simple way to determine the ASCII code - you need to enclose the required character in single quotes:
int Code='A'; Alert(IntegerToString(Code));
As a result of this code, the Code variable will store the value of 65, being the ASCII code of the Latin character "A".
Let us express the solution to this problem as a separate function so that we easily use it when necessary. The first parameter passed to the function will be a string and the second parameter will be an array returned by reference. The code of the function is provided below with detailed comments and does not require further explanation:
int ParamsToArray(string Str,double &Params[]) { //--- delete spaces at the ends StringTrimLeft(Str); StringTrimRight(Str); //--- if the string is empty if(StringLen(Str)==0) { ArrayFree(Params); // free the array return(0); // function operation complete } //--- auxiliary array string tmp[]; //--- split the string int size=StringSplit(Str,';',tmp); //--- delete spaces at the ends for each element of the array for(int i=0;i<size;i++) { StringTrimLeft(tmp[i]); StringTrimRight(tmp[i]); } //--- delete empty elements from the array (user could accidentally //--- put the separator two times in a row or at the end of the string) for(int i=size-1;i>=0;i--) { if(StringLen(tmp[i])==0) { ArrayCopy(tmp,tmp,i,i+1); size--; // array size reduced } } //--- scale the array according to the new size ArrayResize(tmp,size); //--- replace commas with dots for(int i=0;i<size;i++) { StringReplace(tmp[i],",","."); } //--- prepare the array to be returned ArrayResize(Params,size); //--- convert all elements to the double type and fill the array to be returned for(int i=0;i<size;i++) { Params[i]=StringToDouble(tmp[i]); } //--- the function returns the number of parameters return(size); }
Converting Strings to Various Variables
The ParamsToArray() function has used the standard StringToDouble() function to convert the string to the variable of the double type. The same function is used for converting to the float type. There are standard functions that are used for conversions to other variable types.
The StringToInteger() function converts a string to an integer variable:
string Str="12345.678"; //--- convert the string to an integer long Val=StringToInteger(Str); //--- inverse convert and output the results Alert(IntegerToString(Val));
As a result of this code, the Val variable will store the value of 12345. The fractional part is simply truncated.
The StringToTime() function converts a string expression of time to the relevant numerical value. If you do not specify the time, the default value will be "00:00":
string Str1="2012.11.02 22:00"; string Str2="2012.01.01"; //--- convert the string expression of time to the datetime type datetime DateTime1=StringToTime(Str1); datetime DateTime2=StringToTime(Str2);
The StringToColor() function allows you to convert a color name (standard web color) to the relevant numerical value, or to convert a string of RGB components:
string Str1="clrYellow"; string Str2="255,255,0"; color Color1=StringToColor(Str1); color Color2=StringToColor(Str2);
There is another way of converting strings to datetime and color type. It can be used when assigning certain values to variables:
datetime DateTime=D'2012.11.02 22:00'; color Color=C'255,255,0';
"D" is written before the string expression of date and the date itself is enclosed in single quotes. The string expression of color is preceded by the letter "С" and the RGB components are enclosed in single quotes and separated by a comma.
Enabling Notifications
User enters a series of characters that enable a certain type of notification. This method can be used to have various combinations of notifications enabled. The alert notification corresponds to "а", sound notification to "s", e-mail notification to "e" and push notification to "p". In addition, you can add 1 or 0 to the string to denote the bar on which signals are checked (it can be useful in indicators). The code is expressed as a function whose first parameter is a string followed by the Shift variable (number of the bar) returned by reference and variables of the bool type corresponding to different notification methods. The code is provided with detailed comments:
void NotifyOnOff(string Str,int &Shift,bool &Alerts,bool &Sounds,bool &EMail,bool &Push) { //--- Convert the string to lower case to allow the user //--- to use both lowercase and uppercase characters. StringToLower(Str); //--- search for characters in the string Alerts=(StringFind(Str,"a")!=-1); // "a" found Sounds=(StringFind(Str,"s")!=-1); // "s" found EMail=(StringFind(Str,"e")!=-1); // "e" found Push=(StringFind(Str,"p")!=-1); // "p" found //--- search for zero if(StringFind(Str,"0")!=-1) Shift=0; // "0" found in the string else Shift=1; // by default }
Now, instead of five variables in the properties window, a single one will suffice.
String Buffer
We still have to review three standard functions: StringInit(), StringFill() and StringBufferLen().
The StringInit() function fills a string with identical characters in the number specified:
string str; StringInit(str,10,'|'); Alert(str);
Following the execution of this code, the str variable will store the string containing "||||||||||". The character is specified using its ASCII code, i.e. the character needs to be enclosed in single quotes.
The StringFill() function fills a string with identical characters without changing the string size. In continuation of the previous example:
StringFill(str,'/'); Alert(str);
Following this, the str variable will store the string containing "//////////".
Let us now try to fill a string with a character with code 0 (end of the string):
StringFill(str,0);Check the string size:
int Length=StringLen(str); Alert(IntegerToString(Length));
The size is equal to 0 and the character with code 0 is at the starting point of the string. Check the buffer size:
int BLength=StringBufferLen(str); Alert(IntegerToString(BLength));
The buffer size is different from 0 and exceeds the size of the initial string. The memory allocated to the string is more than enough. Now, when assigning a value to the string within the buffer size range, memory reallocation will not be required and the value will be assigned very quickly. To ensure that the buffer size is not reduced, the new value should be added to the string, rather than assigned to it:
str+="a";
The string length is now 1, while the buffer size has remained the same. This way you can somewhat speed up processing of strings. A string can be cleared by inserting the character with code 0 at the beginning of the string:
StringSetCharacter(str,0,0);
Conclusion
One would think that the subject of the article is of minor importance, only slightly relevant to the main purpose of the MQL5 language, i.e. developing Expert Advisors and indicators. However, what we got here is a quite extensive article inspired by a broad range of functionality for working with strings that the language offers. It is not unlikely that in many cases when programming Expert Advisors and indicators you will not have to deal with strings, yet it may be required some day. After reading this article, you are all set and ready to use strings, as and where necessary, without wasting time on studying the functions. You will be able to easily do what is required.
Let us recap the information provided in the article, classifying the functions according to their purpose, importance and frequency of use.
- StringLen(), StringFind(), StringSubstr(), StringReplace() and StringSplit() are key essential functions that are used for determining the string length, substring search, getting and replacing a substring, as well as splitting a string.
- StringTrimLeft(), StringTrinRight(), StringToLower() and StringToUpper() are very useful auxiliary functions that are used for deleting spaces at the ends and changing the case.
- ColorToString(), DoubleToString(), EnumToString(), IntegerToString(), TimeToString() and StringFormat() are functions that convert numerical variables to a string.
- StringToColor(), StringToDouble(), StringToInteger(), StringToTime() and StringCompare() are functions that convert a string to a numerical variable.
- StringAdd() and StringConcatenate() are functions that you can use to add up and combine strings in a space efficient way.
- ShortToString(), ShortArrayToString(), StringToShortArray(), as well as CharToString(), CharArrayToString() and StringToCharArray() are functions for working with strings as arrays that can be useful when dealing with tasks which require very complex string manipulations. From the above list, we can point out two functions as being especially important:
- CharToString() is used for working with graphical objects together with the Wingdings font,
- CharArrayToString() is used to prepare a string parameter when calling API functions.
- StringSetCharacter(), StringGetCharacter(), StringInit(), StringFill() and StringBufferLen() are secondary functions.
Attached files
- IncStrFunctions.mqh contains the Trim(), StringFindRev(), TrimL(), TrimR(), ParamsToArray() and NotifyOnOff() functions.
- eMultiLanguageMessage.mq5 is an example of an Expert Advisor featuring messages in different languages.
Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/585
![MQL5 Cookbook: How to Avoid Errors When Setting/Modifying Trade Levels](https://c.mql5.com/2/0/avatar1.png)
![MQL5 Cloud Network: Are You Still Calculating?](https://c.mql5.com/2/0/avatar.png)
![Debugging MQL5 Programs](https://c.mql5.com/2/0/avatar21a.png)
![MQL5 Market Results for Q1 2013](https://c.mql5.com/2/0/MQL5_Market_Results.png)
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
According to the description of these functions in MQL5 Reference, they allow us to add up strings in a more space efficient (in terms of the occupied working memory) and faster way.
In facts there are incoherence in documentation. I don't know about memory usage, but about faster or not, StringConcatenate() is MUCH slower than StringAdd and +
2013.04.11 19:09:48 teststring (EURUSD,M1) time for 'StringConcatenate(c,a,b)' = 1170 milliseconds, i = 1000000
2013.04.11 19:09:47 teststring (EURUSD,M1) time for 'StringAdd(a,b)' = 94 milliseconds, i = 1000000
2013.04.11 19:09:47 teststring (EURUSD,M1) time for 'c = a + b' = 265 milliseconds, i = 1000000
Good article, a must for all beginners.
it is nice to tire you to make us less ignorant. thank you for your work