String constant is a sequence of ASCII-code characters enclosed in double quotes: "Character constant".
A string constant is an array of characters enclosed in quotes. It is of the string type. If there is a need to insert a double quote (") into the string, a reverse slash (\) must be put before it. Any special character constants can be inserted into the string if they have a reverse slash (\) before them. The length of a string constant lies between 0 and 255 characters. If the string constant is longer, the superfluous characters on the right will be rejected, and compiler will alert correspondingly.
while (true) {
str = stringconcentenate(str, abc);
.
.
.
}
String str could be anything from several bytes to ~200Kbytes.
When I tried Print("Size: ", StringLen(str)); I am getting garbage printouts.
aha! indeed when it hits more than 4K, its screwed.
Here is the actual code I am working on. It fetches webpages from the internet and stores them into the external string WebPage.
extern string URL = "";
start () {
string Data= "";
GrabWeb(URL,Data);
int size = StringLen(Data);
Comment("Size : ", size);
Print(Data);
}
//==================================== GrabWeb Functions ======================================
int hSession_IEType;
int hSession_Direct;
int Internet_Open_Type_Preconfig = 0;
int Internet_Open_Type_Direct = 1;
int Internet_Open_Type_Proxy = 3;
int Buffer_LEN = 16;
#import "wininet.dll"
#define INTERNET_FLAG_PRAGMA_NOCACHE 0x00000100 // Forces the request to be resolved by the origin server, even if a cached copy exists on the proxy.
#define INTERNET_FLAG_NO_CACHE_WRITE 0x04000000 // Does not add the returned entity to the cache.
#define INTERNET_FLAG_RELOAD 0x80000000 // Forces a download of the requested file, object, or directory listing from the origin server, not from the cache.
int InternetOpenA(
string sAgent,
int lAccessType,
string sProxyName="",
string sProxyBypass="",
int lFlags=0
);
int InternetOpenUrlA(
int hInternetSession,
string sUrl,
string sHeaders="",
int lHeadersLength=0,
int lFlags=0,
int lContext=0
);
int InternetReadFile(
int hFile,
string sBuffer,
int lNumBytesToRead,
int& lNumberOfBytesRead[]
);
int InternetCloseHandle(
int hInet
);
#import
int hSession(bool Direct) {
string InternetAgent;
if (hSession_IEType == 0) {
InternetAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Q312461)";
hSession_IEType = InternetOpenA(InternetAgent, Internet_Open_Type_Preconfig, "0", "0", 0);
hSession_Direct = InternetOpenA(InternetAgent, Internet_Open_Type_Direct, "0", "0", 0);
}
if (Direct) {
return(hSession_Direct);
} else {
return(hSession_IEType);
}
}
bool GrabWeb(string strUrl, string& strWebPage) {
int iResult;
int lReturn[]={1};
string sBuffer="x";
strWebPage = "";
int hInternet = InternetOpenUrlA(hSession(FALSE), strUrl, "0", 0, INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0);
if (hInternet != 0) {
while (InternetReadFile(hInternet, sBuffer, Buffer_LEN, lReturn) != 0) {
if (lReturn[0] == 0) break;
strWebPage = strWebPage + StringSubstr(sBuffer, 0, lReturn[0]);
}
iResult = InternetCloseHandle(hInternet);
return(true);
} else {
return(false);
}
}
Above, Buffer_LEN is 16; I find this number too small so I increased it to 256, 2048, 4096 all fails resulting in wrong StringLen count to total crash.
How do I increase this "Initial Buffer" such that it wont crash when the string grows big? A small Buffer_LEN is inefficient.
#import "wininet.dll" bool InternetReadFile(int hInternet, string lpBuffer, int dwNumberOfBytesToRead, int& lpdwNumberOfBytesRead[]); ... ... string sBuffer=" "; // not more than 255 spaces int nBufferLen=StringLen(sBuffer); int lReturn[1]; ... while (InternetReadFile(hInternet, sBuffer, nBufferLen, lReturn) != 0) ...
Two important things:
- long constant string
- String addition instead of StringConcatenate (I was wrong - string functions don't increase internal buffer, addition operation only)
string sBuffer=" "; // not more than 255 spaces
forces MT4 to allocate sBuffer with x spaces such that, when it is passed to the dll, dll can work with x bytes!
string1 = StringConcatenate( string1, string2) not ok on long strings
string1 = string1 + string2 OK for long strings
Is this correct about the string addition?
2. Yes
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
The string could range from a few bytes to almost 200Kbytes.
Initial testing shows that if the string is small (less than 200), the function works properly.
but when the sting is big (>4K ~ 170K), a simple
int size = StringLen(data); Comment("Size : ", size); Print("Size: ", size);would print part of the string on the chart and on the Log.
And when th sting is long also, it does not return the full data.