201 lines
5.2 KiB
MQL5
201 lines
5.2 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| String.mqh |
|
|
//| Copyright 2026, Niquel Mendoza |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2026, Niquel Mendoza"
|
|
#property link "https://www.mql5.com"
|
|
#property strict
|
|
|
|
#ifndef MQLARTICLES_UTILS_FA_STRING_STRING_MQH
|
|
#define MQLARTICLES_UTILS_FA_STRING_STRING_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
namespace TSN
|
|
{
|
|
//+------------------------------------------------------------------+
|
|
//| Macros |
|
|
//+------------------------------------------------------------------+
|
|
#define StringSubstrRange(s, ps, pe) s.Substr(ps,((pe)-(ps))+1)
|
|
|
|
//---
|
|
#define StringTrim(text) \
|
|
StringTrimRight(text); \
|
|
StringTrimLeft(text);
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Funcinoes extra de string |
|
|
//+------------------------------------------------------------------+
|
|
class CStringFunc
|
|
{
|
|
public:
|
|
CStringFunc(void) {}
|
|
~CStringFunc(void) {}
|
|
|
|
|
|
//--- Find
|
|
static __forceinline int FindCh(const string &str, const uchar c, int l, int r = 0);
|
|
|
|
//--- RFind
|
|
static __forceinline int RFindCh(const string &str, const uchar c, int r);
|
|
|
|
|
|
//---
|
|
template <typename TValue, typename TConvert>
|
|
static ulong ToVector(const string& str, vector<TValue>& vec, ushort sep)
|
|
{
|
|
//---
|
|
int pos = 0;
|
|
const int len = StringLen(str);
|
|
//TConvert::s_len = len;
|
|
//---
|
|
ulong r = vec.Size();
|
|
//---
|
|
ulong w = 0;
|
|
//--
|
|
while(pos < len)
|
|
{
|
|
//---
|
|
const ushort c = str[pos];
|
|
if(c < 33 || c == sep)
|
|
{
|
|
pos++;
|
|
continue;
|
|
}
|
|
|
|
//---
|
|
if(w >= r)
|
|
{
|
|
r = (r << 1) + 8;
|
|
vec.Resize(r);
|
|
}
|
|
|
|
//---
|
|
// CAracter real
|
|
// la idea es que convert haga su trabajo y pare hasta donde considere que debe
|
|
// luego nos deja.. y segimos nosotrs..
|
|
TConvert::ToValue(str, pos, vec[w++], len);
|
|
}
|
|
//---
|
|
return w;
|
|
}
|
|
|
|
//---
|
|
template <typename TValue, typename TConvert>
|
|
static int ToArr(const string& str, TValue& arr[], ushort sep)
|
|
{
|
|
//---
|
|
int pos = 0;
|
|
const int len = StringLen(str);
|
|
//TConvert::s_len = len;
|
|
//---
|
|
int r = ArraySize(arr);
|
|
//---
|
|
int w = 0;
|
|
//--
|
|
while(pos < len)
|
|
{
|
|
//---
|
|
const ushort c = str[pos];
|
|
if(c < 33 || c == sep)
|
|
{
|
|
pos++;
|
|
continue;
|
|
}
|
|
|
|
//---
|
|
if(w >= r)
|
|
{
|
|
r = (r << 1) + 8;
|
|
ArrayResize(arr, r);
|
|
}
|
|
|
|
//---
|
|
// CAracter real
|
|
// la idea es que convert haga su trabajo y pare hasta donde considere que debe
|
|
// luego nos deja.. y segimos nosotrs..
|
|
TConvert::ToValue(str, pos, arr[w++], len);
|
|
}
|
|
//---
|
|
return w;
|
|
}
|
|
|
|
//--- Split complejo (por "")
|
|
static int StringSplitStr(const string& str, const string& sep, string& arr[], int reserve);
|
|
};
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
static int CStringFunc::StringSplitStr(const string &str, const string &sep, string &arr[], int reserve)
|
|
{
|
|
//---
|
|
if(str == NULL)
|
|
return -1; // Vacio
|
|
|
|
//---
|
|
int last_start = 0;
|
|
const int len_str = int(str.Length());
|
|
const int len_sep = int(sep.Length());
|
|
int s = 0;
|
|
int r = ArrayResize(arr, reserve);
|
|
|
|
// 1||N||0||1||sAdasdasdasd"
|
|
//---
|
|
while(true)
|
|
{
|
|
int init;
|
|
if((init = str.Find(sep, last_start)) >= 0)
|
|
{
|
|
//---
|
|
if(s >= r)
|
|
{
|
|
r <<= 1;
|
|
ArrayResize(arr, r);
|
|
}
|
|
|
|
|
|
//---
|
|
arr[s++] = StringSubstrRange(str, last_start, init - 1);
|
|
last_start = init + len_sep;
|
|
}
|
|
else
|
|
{
|
|
// resize fijo desde ultima pos hasta todo..
|
|
arr[ArrayResize(arr, (++r)) - 1] = str.Substr(last_start, len_str);
|
|
return r;
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Find |
|
|
//+------------------------------------------------------------------+
|
|
static __forceinline int CStringFunc::FindCh(const string &str, const uchar c, int l, int r = 0)
|
|
{
|
|
l += r;
|
|
for(; r < l; r++)
|
|
if(str[r] == c)
|
|
return r; // posicion absoluta
|
|
return -1;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| RFind |
|
|
//+------------------------------------------------------------------+
|
|
static __forceinline int CStringFunc::RFindCh(const string &str, const uchar c, int r)
|
|
{
|
|
for(; r >= 0; r--)
|
|
if(str[r] == c)
|
|
return r; // posicion absoluta
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif // MQLARTICLES_UTILS_FA_STRING_STRING_MQH
|