Discussion of article "MQL5 Programming Basics: Strings" - page 2

 
denkir:

...Personally, I was interested in the question about line length limitations....

I've experimented now, 32 mb fits, it would fit even more, but it would take a long time.
 

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.

[Deleted]  
Thanks.
 
Good article, thanks.
 

it is nice to tire you to make us less ignorant. thank you for your work

 

Adds a digit group separator to the string:

//+------------------------------------------------------------------+
//|DelimiterGroupsDigits.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. | |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property script_show_inputs
//--- External parameters
input double Value     =1000000;
input string Delimiter =" "; // Delimiter, by default: " ", example: 1 000 000.0
//+------------------------------------------------------------------+
//| Script programme start function|
//+------------------------------------------------------------------+
void OnStart(void)
  {
   ::Print(DelimiterGroupsDigits(string(Value),Delimiter));
  }
//+------------------------------------------------------------------+
//| Separator of digit groups|
//+------------------------------------------------------------------+
string DelimiterGroupsDigits(const string value,const string delimiter=" ")
  {
   string res=value;
   string elements[];
//--- Remove the extra characters from the edges.
   ::StringTrimLeft(res);
   ::StringTrimRight(res);
//--- Check for a real number
   ushort sep   =::StringGetCharacter(".",0);
   int    total =::StringSplit(res,sep,elements);
//--- Got the string
   if(total>0)
     {
      string str[];
      int length=::StringLen(elements[0]);
      for(int k=0,i=length-1; i>=0; i--)
        {
         int size=::ArraySize(str);
         ::ArrayResize(str,size+1);
         str[size]=::StringSubstr(elements[0],i,1);
         k++;
         //--- Add a separator
         if(k>=3 && i>0)
           {
            int array_size=::ArraySize(str);
            ::ArrayResize(str,array_size+1);
            str[array_size]=delimiter;
            k=0;
           }
        }
      //--- Collect the string
      res="";
      int elements_total=::ArraySize(str);
      for(int i=elements_total-1; i>=0; i--)
         ::StringAdd(res,str[i]);
      //--- If real number
      if(total>1)
         ::StringAdd(res,"."+elements[1]);
     }
//--- Return the result
   return(res);
  }
//+------------------------------------------------------------------+

//---

Result:

1 000 000.0
10,000,000.0
100'000'000.0
10 000.545
 
Anatoli Kazharski:

Adds a digit group separator to a string:

Somehow complicated.
 
fxsaber:
It's kind of complicated.
Will you try to optimise it?
 
Anatoli Kazharski:
Will you try to optimise it?
string ModToString( ulong &Num, const int Mod = 1000, const int Len = 3 )
{
  const string Res = ((bool)(Num / Mod) ? IntegerToString(Num % Mod, Len, '0') : (string)(Num % Mod));
  
  Num /= Mod;
  
  return(Res);
}

string NumToString( ulong Num, const string Delimeter = " " )
{
  string Res = ModToString(Num);

  while (Num)
    Res = ModToString(Num) + Delimeter + Res;

  return(Res);
}

string NumToString( double Num, const int digits = 8, const string Delimeter = NULL )
{
  const string PostFix = (Num < 0) ? "-" : NULL;
  
  Num = MathAbs(Num);
    
  return(PostFix + NumToString((ulong)Num, Delimeter) + StringSubstr(DoubleToString(Num - (long)Num, digits), 1));
}

void OnStart()
{
  Print(NumToString(1234567.89, 2, " "));
}
 
fxsaber:

That's great! And four times as fast:

void OnStart(void)
  {
   long count=10000000;
   uint start=GetTickCount();
   for(int i=0; i<count && !IsStopped(); i++)
      DelimiterGroupsDigits(string(Value),Delimiter);

   uint end=GetTickCount()-start;
   Print("01 > ms: ",end,"; res: ",DelimiterGroupsDigits(string(Value),Delimiter));
//---
   start=GetTickCount();
   for(int i=0; i<count && !IsStopped(); i++)
      NumToString(Value,2,Delimiter);

   end=GetTickCount()-start;
   Print("02 > ms: ",end,"; res: ",NumToString(Value,2,Delimiter));
  }

//---

2018.01.30 21:02:15.996 01 > ms: 19047; res: 1 000 000.0
2018.01.30 21:02:20.683 02 > ms: 4688; res: 1 000 000.00