English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL5 프로그래밍 기본: 문자열

MQL5 프로그래밍 기본: 문자열

MetaTrader 5 | 2 9월 2021, 16:44
120 0
Dmitry Fedoseev
Dmitry Fedoseev

소개

문자열 또는 문자열 변수는 문자 데이터, 즉 텍스트를 저장하는 데 사용됩니다.

string str="Any text";

MQL5 언어는 문자열 작업을 위한 광범위한 사용자 친화적인 기능을 제공합니다. Expert Advisors 및 지표를 프로그래밍할 때 문자열은 주로 정보 메시지를 생성하는 데 사용됩니다. 지표에서 이는 특정 조건(예: 거래 신호)의 이행에 관한 메시지일 수 있지만 Expert Advisors에서는 거래 활동 결과를 보고할 수 있습니다. 실행 시 Expert Advisor, 스크립트 또는 지표는 사용자가 설정한 매개변수를 확인하고 매개변수 집합이 유효하지 않은 경우 알림을 프린트할 수 있습니다. 알림 외에도 매개변수 설정에 대한 권장 사항을 제공하는 프롬프트 메시지가 표시될 수 있습니다. 광범위하게 말하면 MQL5로 프로그래밍할 때 무엇보다도 문자열이 사용자 친화성을 제공합니다.

또한 문자열은 파일로 작업할 때 필수적입니다. 파일에서 데이터 쓰기 및 읽기는 문자열 변수를 사용하여 수행됩니다. 분명히 숫자 변수와 배열을 읽고 쓰는 이진 방법인 파일 작업의 다른 방법을 선택할 수 있습니다. 그러나 데이터의 양이 너무 많지 않다면 텍스트 파일과 문자열을 사용하는 것이 좋습니다. 이 경우 프로그램 조작이 사용자에게 더 명확하고 프로그램 개발 프로세스가 더 간단하여 즉각적인 데이터 제어가 제공됩니다. 텍스트 파일 데이터는 프로그램 내부의 데이터와 동일하게 보입니다.

문자열을 사용하면 필요한 수의 매개변수를 미리 알지 못하는 경우(예: 평균 축적을 위한 랏 크기) 데이터(매개변수) 입력과 관련된 프로그램 기능을 크게 확장할 수 있습니다. 이러한 경우 값은 세미콜론과 같은 구분 기호로 구분된 단일 문자열에 기록될 수 있습니다.

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

그런 다음 Expert Advisor를 초기화할 때 문자열이 분할되고 숫자 값 배열이 채워집니다. 불행히도 최적화에서 이러한 문자열 매개변수를 검토하는 것은 불가능합니다. 즉, 단계 값과 함께 초기 및 최종 값을 설정하는 것입니다. 어떤 경우에는 속성 창에서 많은 숫자 변수를 사용하는 것이 더 나을 수 있습니다. 그러나 그 수가 사실상 무제한일 수 있기 때문에 편의성과 목적(최적화 가능성이 필요한지 여부)의 문제에 직면할 수 있습니다.

매개변수의 최적화가 필요하지 않은 것으로 알려진 다른 경우가 있을 수 있습니다 (예: 알림 활성화). MQL5는 소리 알림, 팝업 알림, 이메일 알림 및 푸시 알림과 같은 다양한 사용자 알림 방법을 지원합니다. 속성 창에서 이러한 알림 각각에 대해 bool 유형 스포지션을 만들거나(최소한 4개의 변수가 필요함) 변수 수를 하나의 문자열 변수로 줄일 수 있습니다.

소리 알림을 활성화해야 하는 경우 "s"(소리)를 씁니다. 이메일 알림이 필요한 경우 "e"를 추가합니다. 따라서 단 하나의 변수를 사용하여 알림 조합을 활성화할 수 있습니다. Expert Advisor에게 외부 매개변수의 수는 별로 중요하지 않습니다. 그것은 단지 사용자 친화성의 문제입니다.

반면에 지표를 개발할 때는 외부 매개변수의 수를 줄이는 방법을 모색해야 합니다. 지표는 매개변수 수가 제한된 iCustom() 또는 IndicatorCreate() 함수를 사용하여 Expert Advisor 또는 다른 지표에서 호출될 가능성이 매우 높습니다(iCustom( )에는 64개의 매개변수만 있고 IndicatorCreate() 함수의 매개변수 배열 크기는 64개 요소입니다. 따라서 문자열을 사용하는 것은 매우 실용적인 가치가 있습니다.

이 글에서는 문자열 작업을 위한 모든 표준 MQL5 함수를 검토하고 몇 가지 유용한 사용자 정의 함수도 만들 것입니다.

 

문자열 변수 선언

다른 유형의 변수와 마찬가지로 문자열 변수를 선언할 수 있습니다.

string str;
또는 선언 시 값 할당(값으로 초기화):
string str="Any text";

문자열의 길이에 대한 제한은 없습니다. 긴 문자열은 편의상 여러 하위 문자열로 나눌 수 있습니다.

string str= "A long string can be "
            "split into several "
            "substrings";
//--- output the results
Alert(str);

이 방법으로 초기화되면 str 변수는 "긴 문자열을 여러 하위 문자열로 분할할 수 있음"을 포함하는 문자열을 갖게 됩니다.

여기서 약간 앞서서 매개변수 없이 선언된 문자열 변수의 값이 빈 문자열과 동일하지 않다는 점에 유의해야 합니다.

string str="";

이를 직접 볼 수 있습니다.

string str1;
string str2="";
//--- output the comparison results
Alert(str1==str2);

이 코드를 실행하면 "false"라는 경고 창이 나타납니다. 초기화되지 않은 문자열 변수에 빈 문자열 ""이 아닌 NULL 값이 있습니다. 당신은 그것을 염두에 두어야합니다! 문자열로 작업할 때 문자열이 비어 있는지 확인해야 하는 경우가 많습니다. 따라서 빈 문자열 ""로 모든 문자열을 초기화하는 규칙을 고수하거나 ""와 같지 않고 NULL과 같지 않은지 확인해야 합니다.

if(str!="" && str!=NULL)
  {
   //--- some operation with a string
  }

첫 번째 방법은 확인 조건을 단순화하므로 더 권장됩니다. 

변수의 크기를 확인할 때도 동일한 작업을 수행할 수 있습니다. 크기를 결정하기 위해 StringLen() 함수를 사용합니다.

if(StringLen(str)!=0)
  { 
   //--- some operation with a string
  }


문자열 연결

문자열로 작업할 때 수행하는 가장 일반적인 작업은 문자열을 연결하는 것입니다. 즉, 단어를 사용하여 구를 작성하는 것입니다. 연결은 "+" 기호를 사용하여 구현됩니다.

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);

이 코드를 실행하면 str4 변수에는 "Programming in MQL5"가 포함되고 str5 변수에는 "MetaTrader 5를 위한 프로그래밍"이 포함됩니다. 위의 예는 두 문자열을 연결하여 결과 문자열을 다른 변수에 할당하는 방법을 보여주었습니다.

추가 문자열은 매우 자주 기본 문자열과 연결됩니다. 

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);

이 코드를 실행하면 str1 문자열에 "MetaTrader 5용 MQL5 프로그래밍"이 포함됩니다. 위의 예는 문자열을 기본 str1 문자열에 연결하고 결과를 후자에 할당하는 방법을 보여주었습니다. 동일한 작업을 훨씬 더 간단한 방법으로 작성할 수 있습니다.

str1+=str2;
str1+=str3;
또는:
str1+=str2+str3;

"="의 왼쪽에 있는 "+" 기호는 "="의 오른쪽에 있는 표현식이 str1 변수에 추가됨을 의미합니다.

기본 문자열의 시작 부분에 문자열을 추가할 수도 있습니다. 이것은 마지막에서 두 번째 예제와 같이 구현할 수 있습니다. 기본 문자열이 추가 문자열에 추가되고 결과 문자열이 기본 변수에 할당됩니다.

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);

다음 문구: "MetaTrader 5용 MQL5 프로그래밍"은 이제 str3 변수에 있습니다. 단일 문자열을 사용하여 동일하게 구현할 수 있습니다. 

str3=str1+" "+str2+" "+str3;
경우에 따라 ","(쉼표)를 사용하여 연결을 수행할 수 있습니다. Alert(), Print() 또는 Comment() 함수를 호출할 때 가능합니다.
Print(str1," ",str2," ",str3);

이 경우 최종 결과는 "+" 기호를 사용하는 것과 동일합니다.

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

"," 기호는 실제로 문자열을 연결하지 않습니다. 쉼표는 모든 함수에서 매개변수의 구분 기호입니다. Alert(), Print()Comment() 함수도 마찬가지입니다. 이러한 함수에는 하나의 필수 매개변수와 많은 선택적 매개변수가 있습니다. 매개변수는 실제로 연결된 함수에 전달됩니다. 최대 매개변수 수는 64개입니다.

FileWrite() 함수를 사용하여 파일에 문자열을 쓸 때도 비슷한 것을 볼 수 있습니다. 그러나 FILE_CSV 모드(필드 구분 기호 포함)에서 파일을 열면 쉼표는 파일을 열 때 지정된 구분 문자로 대체됩니다( 구분 기호가 지정되지 않은 경우 기본적으로 탭이 사용됨). 구분 기호를 지정하지 않고 FILE_TXT 모드에서 파일을 열 때 "+" 기호와 ","를 사용한 결과는 동일합니다.

//--- 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);

이 코드를 실행하면 1.txt 파일에는 "1 2 3"이 포함되고 2.txt 파일에는 "123"이 포함됩니다(파일은 FILE_CSV 모드에서 열림). 3.txt 및 4.txt는 "123"(FILE_TXT 모드에서 열림)과 같은 동일한 내용을 갖습니다. 이 문서에서는 파일 작업을 중심으로 다루지 않습니다. 따라서 마지막 예에서 명확하지 않은 부분이 있는 경우 이 문서에 추가로 설명된 자료에 대한 이해에 영향을 미치지 않으므로 신경 쓰지 마십시오. 문자열 추가를 처리할 때 "+" 및 ","의 사용이 항상 동일한 효과를 생성하는 것은 아닙니다.

"+" 기호 외에도 MQL5는 문자열 추가를 위한 특수 기능인 StringAdd()StringConcatenate()를 제공합니다. MQL5 Reference의 이러한 기능에 대한 설명에 따르면 더 효율적인 공간(점유 작업 메모리 측면에서)과 더 빠른 방법으로 문자열을 추가할 수 있습니다. StringAdd() 함수를 사용하면 한 문자열을 다른 문자열에 추가할 수 있습니다.

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);

이 코드를 실행한 후 str1 변수에는 "MetaTrader 5용 MQL5 프로그래밍"이 포함된 문자열이 있습니다.

StringConcatenate() 함수를 사용하면 여러 문자열을 동시에 결합할 수 있습니다. 함수에 전달된 첫 번째 매개변수는 나열된 문자열이 추가될 문자열의 변수입니다. 함수에 전달할 수 있는 최대 매개변수 수는 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);

이 코드를 실행한 후 str1 변수에는 "MetaTrader 5용 MQL5 프로그래밍"도 포함됩니다.

 

다양한 변수를 문자열로 변환

메시지 문자열을 생성할 때 숫자 변수 값을 추가해야 하는 경우가 많습니다. 정수 변수(char, uchar, bool, short, ushort, int, uint, color, long, ulong, datetime)의 값을 문자열로 변환하려면 IntegerToString() 함수:

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

bool 유형 변수를 변환할 때 반환된 문자열에는 "0"(거짓) 또는 "1"(참)이 포함됩니다. 마찬가지로 색상 또는 날짜/시간 유형 변수를 변환하는 경우 반환된 문자열에는 색상 또는 날짜의 숫자 표현이 포함됩니다(예: clrYellow의 노란색에 대해 "65535" 또는 날짜에 대해 "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(); // Current time 
string str1=IntegerToString(tm);
string str2=TimeToString(tm);

이 코드를 실행한 후 str1 변수에는 숫자 표현이 포함된 문자열(1970년 1월 1일 이후 경과된 초 수)이 포함되고 str2 변수에는 형식화된 시간이 포함됩니다 (예: "2012.11.02 22:00"(년, 월, 일, 시, 분)).

TimeToString() 함수를 호출할 때 날짜 및 시간 형식을 지정하는 옵션이 있습니다. 사용 가능한 옵션은 다음과 같습니다.

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는 프로그램 속성 창에 옵션의 드롭다운 목록으로 표시되는 열거를 생성하는 매우 편리한 기능을 제공합니다. 이러한 변수의 값은 EnumToString() 함수를 사용하여 문자열로 변환할 수도 있습니다. 다음은 이 함수의 작동을 보여주는 스크립트 코드입니다.

//+------------------------------------------------------------------+
//| 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);
  } 
색상 변수를 변환할 수 있는 유사한 가능성이 있습니다. 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 유형 변수를 변환하는 것은 가능한 한 정확해야 하므로 소수 부분에서 0만 삭제할 수 있습니다. 

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

이 코드를 실행한 후 str1 변수는 "0.1"의 문자열 값을 저장하고 str2 변수는 "0.123"의 문자열 값을 포함합니다.

 

특수 문자 출력

문자열 변수를 값으로 초기화할 때 컴파일러가 문자열과 프로그램 코드를 구분할 수 있도록 할당 가능한 문자열을 큰따옴표로 묶어야 합니다. 문자열 안에 따옴표를 넣을 수 있으려면 여기에서 기호가 일반적인 목적(문자열과 코드를 구분하는 문자)으로 사용되지 않고 문자열의 일부로 사용된다는 사실을 지정해야 합니다. 이를 구현하려면 인용 부호 바로 앞에 백슬래시 "\"를 넣어보세요.

string str1="Simple text";
string str2="\"Text in quotes\"";
//--- output the results
Alert(str1);
Alert(str2);

백슬래시는 특수 문자 중 하나로 간주되기 때문에 백슬래시 출력을 문자열로 구현하려면 백슬래시를 그 앞에 추가해야 합니다.

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

이 코드를 실행한 후 문자열에 포함되는 유일한 문자는 "\"입니다.

문자열에는 "\t"로 표시되는 가로 탭 문자도 포함될 수 있습니다.

string str="Column-1\tColumn-2\tColumn-3";
Alert(str);

이 경우 str 변수에는 "Column-1 Column-2 Column-3"이 포함된 문자열이 있습니다.

"\n"을 사용하여 여러 줄로 분할하여 라인 바꿈으로 텍스트를 프린트할 수도 있습니다.

string str="Line-1\nLine-2\nLine-3";
Alert(str);

여기서 Alert() 함수를 실행한 결과 3줄의 텍스트가 생성됩니다.

Alert()MessageBox() 함수를 사용하여 프린트할 때와 파일에 쓸 때 "\t"와 "\n"을 모두 사용할 수 있습니다. 그러나 차트 주석으로 프린트할 때(Comment() 함수), "\n"만 라인 바꿈 문자로 적용되고 탭 문자 "\t"는 무시됩니다. Print() 함수를 이용하여 출력을 하면 "\n"이 기존과 같이 적용되고(문자열의 모든 부분은 저널의 별도 행에 출력됨) "\t"는 다음과 같이 대체됩니다. Print() 함수를 사용하여 출력된 모든 메시지를 저장하는 로그 파일과 같은 공간입니다.

 

문자열의 패턴 기반 서식 지정

출력을 위해 문자열을 형식화할 때 여러 숫자 변수의 값을 포함해야 할 수도 있습니다. 이것은 문자열을 더하고 숫자 변수를 문자열로 변환하여 달성할 수 있습니다. 그러나 이 경우 프로그램 수정이 필요한 경우 메시지를 작성하는 코드 문자열이 너무 길어 이해하고 편집하기 어려울 것입니다.

//--- 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);

StringFormat() 함수를 사용하면 동일한 작업을 훨씬 쉽게 해결할 수 있습니다. 이 함수에 전달된 첫 번째 매개변수는 변수를 삽입하고 출력 형식을 설정하기 위한 표시된 포지션이 있는 메시지 템플릿입니다. 템플릿에 나타나는 순서대로 모든 변수를 열거합니다. 

//--- 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);

변수 삽입 포지션는 "%" 다음에 "i"로 표시되며, 위의 예에서 변수는 정수로 출력되어야 함을 나타냅니다. 또는 "i"는 문자 정수 변수(char, short, int, color)를 나타내는 반면, "u"는 부호 없는 정수 변수(uchar, bool, ushort, uint)에 사용합니다. 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);
//--- output the results
Alert("LongMin = "+LongMin);
Alert("LongMax = "+LongMax);
Alert("ULongMax = "+ULongMax);
Alert("DateTimeMax = "+DateTimeMax);
이 코드의 결과로 변수 값이 있는 팝업 창이 표시됩니다.

실수의 형식은 "f"로 표시됩니다.
double Percents=5.5;
//--- real number as a string
string str=StringFormat("Percents = %f",Percents);
//--- output the results
Alert(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;
//--- integer as a string with a set output length
string str=StringFormat("Variable = %05i",Variable);
//--- output the results
Alert(str);

이 코드를 실행한 후 str 변수는 "Variable = 00123" 문자열을 저장합니다.

지정된 자릿수가 숫자의 자릿수보다 작더라도 출력은 여전히 ​​올바르게 수행됩니다.

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

여기서 str 변수는 "Variable = 123"과 같은 문자열을 포함합니다. 즉, 지정된 길이가 2임에도 불구하고 출력 번호는 3자리입니다.

실수는 "e" 문자를 사용하는 과학적 표기법(소수점 6자리의 가수 및 거듭제곱)을 사용하여 출력할 수 있습니다.

double Variable=123.456;
//--- real number as a string in scientific notation
string str=StringFormat("Variable = %e",Variable);
//--- output the results
Alert(str);

이 코드를 실행하면 str 변수에 "1.234560e+002"가 포함됩니다. 소문자 "e"와 효과가 유사한 대문자 "E"를 사용할 수도 있으며, 대문자 "E"는 서식이 지정된 문자열에서 소문자 "e"를 대체합니다.

실수 형식을 지정하는 또 다른 방법이 있습니다. "g"를 사용하여 6자리(소수점 제외)만 출력할 수 있습니다. 숫자의 정수 부분의 길이가 6자리를 초과하는 경우 과학 표기법을 사용하여 숫자가 출력됩니다.

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);

위의 예에서 str1 변수에는 "12.3457"이 포함되고 str2 변수에는 "1.23457e+006"이 포함됩니다. 대문자 "G"를 대신 사용하는 경우 효과는 동일하지만 출력에서 ​​소문자 "g"가 대문자 "G"로 대체된다는 점만 다릅니다.

StringFormat() 함수를 사용하면 숫자 표현 형식을 변환할 수 있습니다. 즉, 10진수 시스템의 숫자를 8진수 또는 16진수 시스템으로 변환합니다. 숫자를 8진법으로 변환하려면 "o" 문자를 사용해야 합니다.

int Variable=17;
//--- real number as a string in the octal system
string str=StringFormat("Variable = %o",Variable);
//--- output the results
Alert(str);

이 코드를 실행하면 str 변수는 "Variable = 21"(8*2+1=17)과 같이 문자열을 저장합니다.

"x" 또는 "X"는 숫자를 16진수 시스템으로 변환하는 데 사용됩니다. 이러한 경우 소문자 "x"를 사용하는 경우 16진수 시스템 번호는 대문자 "X"가 사용되는 경우 소문자 또는 대문자로 구성됩니다.

color Variable=clrBlue;
//--- real number as a string in the hexadecimal system
string str=StringFormat("Variable = %x",Variable);
//--- output the results
Alert(str);

이 코드를 실행하면 str 변수에 "Variable = ff0000"이 포함됩니다.

마찬가지로 "d" 문자를 사용하여 16진수 시스템의 숫자를 다시 10진수 시스템으로 변환할 수 있습니다.

int Variable=0x0000ff;
//--- real number as a string in the decimal system
string str=StringFormat("Variable = %d",Variable);
//--- output the results
Alert(str);

이 코드를 실행한 후 str 변수가 저장할 문자열은 "Variable = 255"가 됩니다.

"s" 문자를 사용하여 문자열 변수를 출력할 수 있습니다.

string Variable="text";
//--- output the string variable
string str=StringFormat("Variable = %s",Variable);
//--- output the results
Alert(str);

위의 코드를 실행하자마자 "Variable = text"가 포함된 문자열이 str 변수에 저장됩니다.

"-" 기호로 인해 음수가 이동한다는 사실을 감안할 때 열에 출력할 때 숫자를 정렬해야 하는 경우가 있습니다. 양수와 음수를 정렬하려면 문자열 시작 부분에 "%" 바로 뒤에 공백을 추가해야 합니다. 이 경우 시작 부분에 공백이 있는 양수와 달리 음수는 공백 없이 출력됩니다.

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);

이 코드를 실행하면 str1 변수에는 "Variable1= 01"(공백이 있는 문자열)이 포함되고 str2 변수에는 "Variable2=-01"과 같은 문자열이 저장됩니다.

StringFormat()과 유사한 두 가지 함수가 더 있습니다. PrintFormat()과 printf()는 동작 면에서 완전히 동일합니다. StringFormat() 함수와의 유일한 차이점은 Print() 함수와 유사한 방식으로 저널에 텍스트를 출력한다는 것입니다.

사실, StringFormat() 함수는 훨씬 더 많은 기능을 제공하지만, 위에 제공된 자료는 출력을 위한 숫자 형식 지정과 관련된 대부분의 문제를 해결하는 데 필요한 최소한의 것입니다.
 

다른 언어로 된 메시지

StringFormat() 함수는 터미널에 설정된 인터페이스 언어에 따라 다양한 언어로 메시지를 프린트할 수 있는 매우 유용한 기능으로 프로그램을 향상시킬 수 있는 기회를 제공합니다.

TERMINAL_LANGUAGE 식별자로 TerminalInfoString() 함수를 호출하여 어떤 인터페이스 언어가 설정되어 있는지 알 수 있습니다. 프로그램을 실행할 때 인터페이스 언어에 따라 형식 문자열을 준비하여 프로그램에서 사용합니다. 다음은 위의 기능이 구현된 Expert Advisor 템플릿입니다.

//--- 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");
  }

Expert Advisor는 두 난수의 합을 계산하고 해당 작업에 대한 메시지를 출력합니다. "1 더하기 2는 3"입니다.

그것은 문자열의 출력에 관한 것입니다. 이제 우리는 조금 더 복잡하지만 더 흥미로운 문자열 조작을 진행할 것입니다.

 

문자열 작업을 위한 주요 기능

프로그램 속성 창을 통해 문자열을 입력하거나 파일에서 읽을 경우 불필요한 공백이 포함될 수 있습니다. 사용자의 우연한 부주의나 편의상 나타날 수 있습니다. 어떤 식으로든 문자열을 사용하기 전에 왼쪽과 오른쪽 끝에 있는 공백을 삭제하는 것이 좋습니다. 이를 위해 MQL5는 StringTrimLeft()(왼쪽 끝의 공백 삭제) 및 StringTrimRight()(오른쪽 끝의 공백 삭제)라는 두 가지 기능을 제공합니다. 공백 외에도 이러한 기능은 탭 및 라인 바꿈 문자도 제거합니다. 문자열로 작업할 때 종종 한 번에 양쪽 끝의 공백을 삭제해야 하므로 이를 구현하는 함수는 매우 유용할 것입니다.

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

실수를 입력할 때 점 대신 쉼표를 사용하는 경우가 많습니다. 따라서 실수로 작업할 때 점과 쉼표를 모두 소수점 기호로 사용할 수 있는 가능성을 제공해야 합니다. 한 문자열을 다른 문자열로 바꾸려면 StringReplace() 함수를 사용합니다.

string str="123,456";
//--- replace a comma with a dot
StringReplace(str,",",".");
double Value=StringToDouble(str);
//--- output the results
Alert(DoubleToString(Value));

","를 "."로 바꾸지 않으면 문자열을 숫자로 변환할 때 숫자의 소수 부분이 잘립니다.

경우에 따라 일련의 공백을 하나의 공백으로 바꿔야 할 수도 있습니다. 이렇게 하려면 먼저 탭 문자를 공백으로 바꾼 다음 공백만 남을 때까지 두 개의 공백을 하나로 바꿔야 합니다.

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);

StringReplace() 함수는 교체 횟수를 반환하거나 오류의 경우 -1을 반환합니다. 따라서 루프는 모든 일련의 공백이 각각의 단일 경우에 남아 있는 하나의 공백으로 대체될 때까지 0보다 큰 값을 반환하는 함수로 계속됩니다. 루프 본문에는 코드가 포함되어 있지 않습니다. 모든 반복에서 루프 조건을 확인할 때 StringReplace() 함수를 호출합니다.

StringReplace() 함수를 사용하면 길이가 다른 부분 문자열을 바꿀 수 있습니다.

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);

이 코드를 실행할 때 첫 번째 교체 후의 str 변수에는 두 번째 교체에 이어 "Programming for MetaTrader 5" 및 "Programming in MQL5!"가 포함된 문자열이 있습니다.

StringFind() 함수는 하위 문자열을 검색하는 데 사용됩니다. 문자열에서 하위 문자열이 처음 나타나는 인덱스를 반환합니다. 함수에 전달된 첫 번째 매개변수는 검색이 수행되는 문자열입니다. 두 번째 매개변수는 대상 하위 문자열을 결정하는 반면, 세 번째 매개변수(선택 사항)는 검색이 시작되는 포지션을 결정할 수 있습니다. 세 번째 매개변수가 지정되지 않은 경우 함수는 해당 값이 0인 것처럼 작동합니다. 즉, 검색은 문자열의 맨 처음부터 시작됩니다. "MetaTrader 5용 MQL5 프로그래밍" 문자열에서 하위 문자열 "5"의 포지션을 ​​찾아보겠습니다.

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));

이 코드를 실행하면 Pos 변수 값은 23이 됩니다. 하위 문자열 "5"는 총 두 번 발생하지만 함수는 첫 번째 발생 포지션만 반환합니다. 단순히 문자열을 보고 포지션을 계산하면 24가 됩니다. 문제는 함수가 1이 아닌 0부터 계산하기 시작한다는 것입니다. 대상 하위 문자열이 문자열에서 발견되지 않으면 함수는 -1을 반환합니다.

때때로 부분 문자열이 마지막으로 나타나는 포지션을 찾아야 할 수도 있습니다. 이를 위해 사용자 정의 함수 StringFindRev()를 작성해야 합니다. 부분 문자열의 첫 번째 발생 검색으로 시작한 다음 루프에서 찾은 포지션 등에 따라 검색 시작을 이동합니다.

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);
  }
이 기능을 사용해 보겠습니다.
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);

이 코드를 실행하면 Pos 변수의 값이 40이 됩니다.

StringSubstr() 함수는 주어진 포지션에서 주어진 길이의 부분 문자열을 가져오는 데 사용됩니다. 포지션 23에서 길이가 1인 부분 문자열을 가져옵니다.

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);

결과 숫자는 "5"입니다.

이제 주요 기능을 고려했으므로 이 기능을 사용하여 문자열에서 주어진 문자 목록을 삭제하는 유용한 기능을 작성해 보겠습니다. 함수는 소스 문자열과 소스 문자열에서 삭제할 문자 목록을 나타내는 문자열을 수신합니다.

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));
  }

이 함수는 탭과 라인 바꿈 문자, 공백 및 세미콜론 ";"을 삭제합니다. 기본적으로.

오른쪽 끝에서 삭제하는 것과 동일한 기능:

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));
  }

이 기능은 탭과 라인 바꿈 문자, 공백 및 세미콜론 ";"도 삭제합니다. 기본적으로. CSV 파일을 읽을 때 유용할 수 있습니다. 이러한 파일 내부에는 문자열의 오른쪽 끝에 많은 필드 구분 기호(일반적으로 세미콜론 ";")가 있을 수 있습니다.

대문자 및 소문자, 예: "А"와 "а"는 인간이 의미하는 바가 다르지 않은 반면, 컴퓨터는 완전히 다른 두 문자로 취급합니다. SymbolInfoDouble() 함수를 사용하여 시장 데이터를 요청할 때 "EURUSD" 대신 "eurusd"를 쓰면 함수가 필요한 값을 반환하지 않습니다. 이는 속성 창에서 기호 이름을 입력할 때 발생할 가능성이 매우 높습니다. MQL5에서 대소문자를 변경하려면 StringToLower() 함수(소문자로 변경) 및 StringToUpper() 함수(대문자로 변경)를 사용할 수 있습니다.

string str="EuRuSd";
string str1=str;
string str2=str;
//--- change the case of strings
StringToUpper(str1);
StringToLower(str2);
//--- output the results
Alert(str1," ",str2);

이 코드를 실행하면 str1 변수에는 "EURUSD"가 포함된 문자열이 저장되고 str2 변수에는 "eurusd"가 포함된 문자열이 저장됩니다.

대소문자를 고려하지 않고 문자열을 비교해야 하는 경우 StringCompare() 함수가 가장 적합합니다. 함수의 처음 두 매개변수는 비교를 위한 문자열입니다. 세 번째 매개변수는 문자열을 비교해야 하는지(true) 또는 대소문자를 고려하지 않는(false) 여부를 결정합니다.

int Result=StringCompare("eurusd","EURUSD",false);
Alert(Result); 

함수가 0을 반환하면 문자열이 동일합니다. 함수는 첫 번째 문자열이 두 번째 문자열보다 작으면 -1을 반환하고, 첫 번째 문자열이 두 번째 문자열보다 크면 1을 반환할 수 있습니다. "Greater" 및 "less"는 알파벳순으로 정렬될 때 문자열의 상태를 의미합니다. 문자 "b"가 문자 "a"보다 큽니다.

int Result=StringCompare("a","b",true);
Alert(Result); 

이 경우 함수는 -1을 반환합니다.

이제 다른 기능을 계속하기 전에 이론적으로 간략하게 설명할 필요가 있습니다.
  

인간과 컴퓨터가 보는 끈

사람에게 문자열이 무엇인지는 매우 분명합니다. 문자로 구성된 텍스트입니다. 컴퓨터는 인간에 비해 구조가 다소 단순하며 숫자만 취급합니다. 컴퓨터는 이미지, 문자열 및 기타 모든 것을 숫자로 봅니다. 문자열은 한 문자가 한 숫자에 해당하거나 오히려 코드, 다른 문자가 다른 코드 등에 해당하는 숫자 배열입니다. 이러한 코드를 ASCII 코드(American Standard Code for Information Interchange의 약자)라고 합니다. 아래에서는 256개의 코드를 포함하는 확장된 ASCII를 의미하는 ASCII라는 용어를 더 사용합니다. 따라서 컴퓨터 "알파벳"은 256자로 구성되어 있다고 말할 수 있습니다. 사람과 언어에 따라 알파벳이 다르듯이 컴퓨터에도 다양한 문자 집합(코드 페이지)이 있습니다. 러시아의 컴퓨터 사용자는 대부분 라틴 문자와 키릴 문자, 숫자, 구두점 및 기타 기호를 포함하는 문자 인코딩인 Windows-1251을 사용합니다. 그림 1은 Windows-1251 코드 페이지를 보여줍니다.


그림 1. Windows-1251 코드 페이지.

처음 32자는 표시되지 않으며 제어 문자입니다. 그것들은 그대로 표시되지 않지만 다른 문자의 표시에 영향을 미칩니다. 탭(코드 9), 라인 바꿈(코드 10) 등

중부 유럽 언어로 텍스트를 나타내는 데 사용되는 인코딩은 Windows-1250입니다(그림 2).


그림 2. Windows-1250 코드 페이지.

코드 페이지 1251이 러시아 알파벳 문자를 특징으로 하는 코드 192로 시작하는 코드 페이지 1250에는 유럽 언어의 분음 부호(음량 값의 약간의 변화를 결정하는 분음 부호가 있는 문자)가 포함된 문자가 있습니다.

256자는 매우 작은 숫자입니다. 텍스트가 여러 언어로 작성되어야 하는 경우 어려움이 발생합니다. 러시아어 및 프랑스어(많은 수의 발음 구별 부호가 있음) 또는 영어 및 아랍어(문자가 다른 언어의 문자와 매우 다름). 또한 중국어와 일본어와 같이 수천 개의 문자가 있는 상형 문자가 있으며 이 경우 어려움이 훨씬 더 분명합니다. 다른 방법을 사용하여 코드 페이지에 포함되지 않은 문자를 인코딩해야 할 수도 있습니다. HTML에 익숙한 사용자는 HTML 페이지에 비표준 문자를 삽입할 수 있는 가능성에 대해 알고 있어야 합니다. 코드 &Agrave; 는 À 및 &Aacute;를 표시하는 데 사용됩니다. Á 등을 렌더링합니다.

최근에는 하나의 문자가 단일 바이트(0에서 255 사이의 숫자)가 아니라 2바이트로 인코딩되어 총 65536개의 문자가 인코딩되는 유니코드 인코딩을 사용하는 것이 일반적이 되었습니다. 이 문자 집합에는 그림 3과 같이 세계에 존재하는 모든 알파벳의 문자와 가장 일반적인 상형 문자가 포함됩니다(컴퓨터에 적절한 글꼴이 설치되어 있어야 함).

그림 3. 다른 알파벳과 상형 문자의 편지. 

그림 3. 다른 알파벳과 상형 문자의 편지.

MQL5의 문자열은 유니코드를 사용하여 인코딩됩니다. 즉, 문자열의 문자는 0에서 65535 사이의 숫자로 나타낼 수 있습니다. 0에서 127 사이의 코드를 가진 문자는 ASCII와 유니코드에서 동일합니다. 텍스트 파일은 ASCII 또는 유니코드를 사용하여 인코딩된 텍스트를 포함할 수 있으며 결과적으로 ASCII 및 유니코드의 문자열 작업을 위한 MQL5 기능이 다릅니다.

 

문자열을 배열로 변환하고 다시 문자열로 변환

문자열로 작업할 때 StringLen(), StringFind(), StringSubst() 및 StringReplace() 함수는 일반적으로 대부분의 실제 작업을 해결하는 데 충분합니다. 그러나 암호화, 데이터 압축, 확인 값 계산과 같이 문자열을 숫자로 사용하여 훨씬 쉽게 해결할 수 있는 작업이 있을 수 있습니다. 이러한 유형의 작업은 매일 처리되지 않지만 언젠가는 해결해야 할 수도 있습니다. 문자열을 배열로 변환해야 하는 더 중요한 작업도 있습니다. 즉, 문자열 매개변수를 Windows API(응용 프로그래밍 인터페이스) 함수에 전달하는 것입니다.

문자열을 유니코드 배열로 변환하려면 StringToShortArray() 함수를 사용하고 ASCII 배열로 변환하려면 StringToCharArray() 함수를 사용합니다.

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");

위의 예에서 StringToShortArray() 및 StringToCharArray() 함수를 사용하여 얻은 배열이 동일한 경우 "Identical"이라는 메시지 창이 팝업되고 차이가 있는 경우 "Different"라는 메시지가 표시됩니다. "MetaTrader 5" 문자열의 경우 문자열이 최대 127개의 문자 코드를 가진 문자로 구성되어 있기 때문에 배열이 동일합니다.

127 이상의 문자 코드에서는 모두 약간 다릅니다. StringToShortArray() 함수 작업의 결과는 항상 모든 곳에서 동일하지만 StringToCharArray() 함수 작업의 결과는 운영 체제의 지역 설정에 따라 다릅니다.

Windows 7에서는 제어판 - 지역 및 언어 - 표시 언어 변경에서 시스템 언어를 선택할 수 있습니다.

다음 예를 살펴보십시오. 코드 페이지 1251에서 코드 192는 문자 "А"(러시아 알파벳의 첫 글자)에 해당하는 반면 인코딩 1250의 동일한 코드는 문자 "Ŕ"(체코 알파벳의 가장 일반적으로 알려진 문자 중 하나)에 해당합니다. StringToShortArray() 함수를 사용할 때 문자 "А"는 항상 코드 1040이고 문자 "Ŕ"은 코드 340입니다. 시스템이 러시아어로 설정된 경우 StringToCharArray() 함수를 사용할 때 문자 "А"는 코드 192(정확함)에 해당하고 문자 "Ŕ"은 코드 82(라틴어 "R")에 해당합니다. 그러나 시스템이 체코어로 설정된 경우 문자 "А"는 코드 63(물음표)에 해당하고 문자 "Ŕ"은 코드 192(정확함)에 해당합니다. 분음 부호가 포함된 문자는 유사한 라틴 문자로 대체되고 일반적이지 않은 문자는 물음표로 대체됩니다.

문자열의 크기와 결과 배열을 확인하세요.

int StrLen=StringLen(str);
int shaLen=ArraySize(sha);
int chaLen=ArraySize(cha);
//--- output the lengths
Alert(StringFormat("%i, %i, %i",StrLen,shaLen,chaLen));

배열의 요소 수가 문자열의 문자 수보다 1만큼 많습니다. 이것은 문자열의 끝이 코드 0인 문자로 표시된다는 사실과 관련이 있습니다. 이 문자는 문자열에 표시되지 않지만 표시되는 문자열의 끝을 나타내는 컴퓨터에 의미가 있습니다. 문자열 길이에 해당하는 양만큼 한 번에 1바이트(문자)의 속도로 데이터 교환이 항상 수행되는 것은 아니지만 코드가 0인 문자를 사용하면 어떤 경우에도 문자열의 끝을 결정할 수 있습니다. 동일한 0도 문제를 일으킬 수 있습니다. 특정 문자는 암호화 또는 압축 알고리즘 적용 시 코드 0인 문자로 변환될 수 있습니다. 이 경우 배열을 문자열로 역변환하면 문자열이 완성되지 않습니다. 이러한 유형의 작업에는 특별한 트릭을 사용해야 하지만 이는 이 문서의 범위를 벗어납니다.

ShortArrayToString()CharArrayToString() 함수를 사용하여 배열을 문자열로 역변환할 수 있습니다.

//--- 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);

위 코드의 결과로 str1 변수는 "Unicode" 문자열을 저장하고 str2는 "ASCII" 문자열을 저장합니다.

ShortToString()CharToString()과 같은 두 가지 유사한 함수가 더 있습니다. short 또는 char 유형의 단일 변수를 하나의 문자로 구성된 문자열로 변환합니다. CharToString() 함수는 실용적인 가치가 있습니다. 다양한 기호를 표시할 수 있는 그래픽 개체(OBJ_ARROW)는 차트를 스크롤할 때 기호가 이동하도록 가격 축에 수직으로, 시간 축에 수평으로 고정됩니다. OBJ_LABELWingdings 글꼴과 함께 사용하면 화면의 좌표에 고정된 다양한 기호를 표시할 수 있으므로 다양한 정보 패널을 만들 수 있습니다. Wingdings 기호 테이블에서 필요한 기호를 찾고 해당 코드를 OBJ_LABEL 그래픽 개체를 사용하여 추가로 표시되는 문자열로 변환합니다.

   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

이 코드의 결과로 차트에 종 모양의 아이콘이 표시됩니다. 차트를 스크롤하는 동안 종 (the bell)은 제자리에 남아 있습니다.

문자 코드 작업을 위한 두 가지 추가 함수는 StringGetCharacter()StringSetCharacter()입니다. 유니코드 코드로 작동합니다. StringGetCharacter() 함수를 사용하면 문자열의 지정된 포지션에서 문자 코드를 가져올 수 있습니다.

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));

이 코드를 실행하면 uch1 변수는 76의 값을 저장하고 uch2는 53을 저장합니다.

StringSetCharacter() 함수를 사용하면 주어진 포지션에서 문자의 코드를 변경하고 문자열 끝에 문자를 추가할 수 있습니다.

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);

이 코드를 실행할 때 "MQ5" 대신 str 변수는 먼저 "MQL"을 저장한 다음 "MQL5"를 저장합니다.

 

API 함수 호출

일부 API 함수는 문자열 매개변수를 변수로 사용합니다. 예를 들어, 타사 응용 프로그램용 함수 WinExec은 uchar 유형의 배열을 첫 번째 매개변수로 사용합니다.

#import "kernel32.dll"
int WinExec(uchar &Path[],int Flag);
#import 

Windows 표준 프로그램인 notepad.exe(메모장)를 실행해 보겠습니다. 메모장 경로를 uchar 유형의 배열로 변환합니다.

string PathName="C:\\WINDOWS\\notepad.exe";
uchar ucha[];
StringToCharArray(PathName,ucha);
int x=WinExec(ucha,1); 

이 함수 작업은 메모장 텍스트 편집기를 열어야 합니다.

API 함수에서 문자열 매개변수를 사용하는 또 다른 예는 유니코드를 사용하여 창에 메시지를 프린트하는 MessageBoxW 함수입니다. 이러한 이유로 ushort 유형의 배열을 매개변수로 전달합니다.

#import "user32.dll"
int MessageBoxW(int hWnd,ushort &szText[],ushort &szCaption[],int nType);
#import

이제 이 함수를 사용하여 창에 메시지를 프린트합니다.

ushort arr[];
ushort capt[];
//--- convert
StringToShortArray("Programming in MQL5 for MetaTrader 5.",arr);
StringToShortArray("Message",capt);
//--- print the message
MessageBoxW(0,arr,capt,0);

이 코드의 결과로 "MetaTrader 5용 MQL5 프로그래밍" 메시지가 포함된 창이 표시됩니다.

위의 예에서 ushort 유형의 배열을 사용할 필요는 없으며 단순히 문자열을 함수 매개변수로 전달할 수 있습니다.

#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);
  }

이 코드의 결과는 위와 같을 것입니다. 그러나 올바른 메시지를 프린트하기 위해 uchar 유형의 배열을 함수 매개변수로 사용할 수 없습니다.

#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);
  }

코드는 오류 없이 실행되고 팝업 창이 나타나지만 메시지가 왜곡됩니다.

ASCII 인코딩으로 문자열을 프린트해야 하는 경우(예: 이미 uchar 유형의 배열이 있는 경우) 비슷한 함수인 MessageBoxA가 있습니다. 메시지를 올바르게 표시하려면 uchar 유형의 배열만 함수에 문자열 매개변수로 전달해야 합니다. 이제 이 함수를 가져오고 호출하여 메시지를 프린트합니다.

#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);
  }

그리고 "MetaTrader 5용 MQL5 프로그래밍"이라는 올바른 메시지가 다시 표시됩니다.

기본적으로 문자열과 함께 작동하는 많은 WinAPI 함수에는 2가지 옵션이 있습니다. ASCII 문자열로 작업하기 위한 옵션과 유니코드 문자열로 작업하기 위한 옵션입니다.

기능을 호출하려면 터미널 설정(터미널 - 메인 메뉴 - 도구 - 옵션 - Expert Advisors - DLL 가져오기 허용)에서 스크립트, Expert Advisor 또는 지표 실행 시 DLL 사용을 활성화하거나 속성 창의 종속성 탭에서 "DLL 가져오기 허용"을 체크하세요. 스크립트에 대한 속성 창을 열 수 있도록 적절한 스크립트 속성을 지정합니다.

#property script_show_inputs

 

무제한 매개변수 입력

사용자는 속성 창에서 매개변수를 세미콜론으로 구분하여 입력합니다.

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

이 문자열을 이중 유형의 변수 배열로 변환해야 합니다.

MQL5에서는 StringSplit() 함수를 사용하여 문자열을 분할할 수 있습니다. 함수에 전달된 첫 번째 매개변수는 문자열이고 두 번째 매개변수는 구분 기호의 ASCII 코드이며 전달된 세 번째 매개변수는 함수 연산 결과를 저장할 배열입니다. ASCII 코드를 결정하는 매우 간단한 방법이 있습니다. 필요한 문자를 작은따옴표로 묶어야 합니다.

int Code='A';
Alert(IntegerToString(Code)); 

이 코드의 결과로 Code 변수는 라틴 문자 "A"의 ASCII 코드인 65 값을 저장합니다.

필요할 때 쉽게 사용할 수 있도록 이 문제에 대한 해결책을 별도의 함수로 표현해 보겠습니다. 함수에 전달된 첫 번째 매개변수는 문자열이고 두 번째 매개변수는 참조로 반환된 배열입니다. 함수 코드는 아래에 자세한 설명과 함께 제공되며 추가 설명이 필요하지 않습니다.

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);
  }

 

문자열을 다양한 변수로 변환

ParamsToArray() 함수는 표준 StringToDouble() 함수를 사용하여 문자열을 이중 유형의 변수로 변환합니다. float 유형으로 변환하는 데 동일한 기능이 사용됩니다. 다른 변수 유형으로의 변환에 사용되는 표준 함수가 있습니다.

StringToInteger() 함수는 문자열을 정수 변수로 변환합니다.

string Str="12345.678";
//--- convert the string to an integer
long Val=StringToInteger(Str);
//--- inverse convert and output the results
Alert(IntegerToString(Val));

이 코드의 결과로 Val 변수는 12345 값을 저장합니다. 소수 부분은 단순히 잘립니다.

StringToTime() 함수는 시간의 문자열 표현을 관련 숫자 값으로 변환합니다. 시간을 지정하지 않으면 기본값은 "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);

StringToColor() 함수를 사용하면 색상 이름(표준 웹 색상)을 관련 숫자 값으로 변환하거나 RGB 구성요소 문자열을 변환할 수 있습니다.

string Str1="clrYellow";
string Str2="255,255,0";
color Color1=StringToColor(Str1);
color Color2=StringToColor(Str2); 

문자열을 날짜/시간 및 색상 유형으로 변환하는 또 다른 방법이 있습니다. 특정 값을 변수에 할당할 때 사용할 수 있습니다.

datetime DateTime=D'2012.11.02 22:00';
color Color=C'255,255,0'; 

"D"는 날짜의 문자열 표현식 앞에 쓰여지며 날짜 자체는 작은 따옴표로 묶입니다. 색상의 문자열 표현 앞에는 문자 "С"가 오고 RGB 구성 요소는 작은 따옴표로 묶이고 쉼표로 구분됩니다.

 

알림 활성화

사용자는 특정 유형의 알림을 활성화하는 일련의 문자를 입력합니다. 이 방법을 사용하여 다양한 알림 조합을 활성화할 수 있습니다. 경고 알림은 "а", 소리 알림은 "s", 이메일 알림은 "e", 푸시 알림은 "p"에 해당합니다. 또한 문자열에 1 또는 0을 추가하여 신호가 확인되는 바를 표시할 수 있습니다(지표에서 유용할 수 있음). 코드는 첫 번째 매개변수가 문자열이고 참조에 의해 반환된 Shift 변수(바 번호)와 다른 알림 방법에 해당하는 bool 유형의 변수인 함수로 표현됩니다. 코드는 자세한 설명과 함께 제공됩니다.

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
  }

이제 속성 창에 있는 5개의 변수 대신 하나의 변수로 충분합니다. 

 

문자열 버퍼

StringInit(), StringFill()StringBufferLen()의 세 가지 표준 함수를 검토해야 합니다.

StringInit() 함수는 지정된 숫자의 동일한 문자로 문자열을 채웁니다.

string str;
StringInit(str,10,'|');
Alert(str); 

이 코드를 실행하면 str 변수에 "||||||||||"가 포함된 문자열이 저장됩니다. 문자는 ASCII 코드를 사용하여 지정됩니다. 즉, 문자는 작은따옴표로 묶어야 합니다.

StringFill() 함수는 문자열 크기를 변경하지 않고 동일한 문자로 문자열을 채웁니다. 이전 예에 이어:

StringFill(str,'/');
Alert(str); 

그 다음에 str 변수는 "//////////"를 포함하는 문자열을 저장합니다.

이제 코드 0(문자열 끝)이 있는 문자로 문자열을 채우도록 합시다.

StringFill(str,0); 
문자열 크기를 확인하세요.
int Length=StringLen(str);
Alert(IntegerToString(Length)); 

크기는 0이고 코드가 0인 문자는 문자열의 시작점에 있습니다. 버퍼 크기를 확인하세요.

int BLength=StringBufferLen(str);
Alert(IntegerToString(BLength)); 

버퍼 크기가 0과 다르며 초기 문자열의 크기를 초과합니다. 문자열에 할당된 메모리가 충분합니다. 이제 버퍼 크기 범위 내에서 문자열에 값을 할당할 때 메모리 재할당이 필요하지 않고 값이 매우 빠르게 할당됩니다. 버퍼 크기가 줄어들지 않도록 하려면 새 값을 문자열에 할당하는 대신 문자열에 추가해야 합니다.

str+="a"; 

문자열 길이는 이제 1이고 버퍼 크기는 동일하게 유지됩니다. 이렇게 하면 문자열 처리 속도를 어느 정도 높일 수 있습니다. 문자열 시작 부분에 코드 0이 있는 문자를 삽입하여 문자열을 지울 수 있습니다.

StringSetCharacter(str,0,0); 

 

결론

누군가는 이 글의 주제가 중요하지 않으며 MQL5 언어의 주요 목적, 즉 Expert Advisors 및 지표 개발과 약간정도만 관련이 있다고 생각할 수 있습니다. 그러나 우리가 여기서 얻을 수 있던 것은 여기에서 얻을 수 있던 것은 언어가 제공하는 문자열 작업을 위한 광범위한 기능으로부터 영감을 받아 작성된 매우 광범위한 글입니다. 많은 경우 Expert Advisors 및 지표를 프로그래밍할 때 문자열을 처리할 필요가 없지만 언젠가는 필요할 수 있습니다. 이 글을 읽고 난 당신은 함수를 연구하는 데 시간을 낭비하지 않고 필요한 경우 문자열을 사용할 준비를 마쳤습니다. 필요한 작업을 쉽게 수행할 수 있습니다.

글에 제공된 정보를 요약하여 목적, 중요성 및 사용 빈도에 따라 기능을 분류해 보겠습니다.

  1. StringLen(), StringFind(), StringSubstr(), StringReplace() 및 StringSplit()은 문자열 길이 결정, 하위 문자열 검색, 하위 문자열 가져오기 및 바꾸기, 문자열 분할에 사용되는 핵심 필수 함수입니다.
     
  2. StringTrimLeft(), StringTrinRight(), StringToLower() 및 StringToUpper()는 끝의 공백을 삭제하고 대소문자를 변경하는 데 사용되는 매우 유용한 보조 함수입니다.
     
  3. ColorToString(), DoubleToString(), EnumToString(), IntegerToString(), TimeToString() 및 StringFormat()은 숫자 변수를 문자열로 변환하는 함수입니다.
     
  4. StringToColor(), StringToDouble(), StringToInteger(), StringToTime() 및 StringCompare()는 문자열을 숫자 변수로 변환하는 함수입니다.
     
  5. StringAdd() 및 StringConcatenate()는 공간 효율적인 방식으로 문자열을 추가하고 결합하는 데 사용할 수 있는 함수입니다.
     
  6. ShortToString(), ShortArrayToString(), StringToShortArray(), CharToString(), CharArrayToString() 및 StringToCharArray()는 매우 복잡한 문자열 조작이 필요한 작업을 처리할 때 유용할 수 있는 배열로 문자열을 작업하기 위한 함수입니다. 위 목록에서 특히 중요한 두 가지 기능을 지적할 수 있습니다. 

    • CharToString()은 Wingdings 글꼴과 함께 그래픽 개체 작업에 사용되며,
    • CharArrayToString()은 API 함수를 호출할 때 문자열 매개변수를 준비하는 데 사용됩니다.

  7. StringSetCharacter(), StringGetCharacter(), StringInit(), StringFill() 및 StringBufferLen()은 보조 함수입니다.

 

첨부 파일

  1. IncStrFunctions.mqh에는 Trim(), StringFindRev(), TrimL(), TrimR(), ParamsToArray() 및 NotifyOnOff() 함수가 포함되어 있습니다.
  2. eMultiLanguageMessage.mq5는 다양한 언어로 된 메시지를 제공하는 Expert Advisor의 예입니다.

MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/585

매수하기 전에 거래 로봇을 테스트하는 방법 매수하기 전에 거래 로봇을 테스트하는 방법
MQL5 Market에서 거래 로봇을 매수하면 다른 모든 유사한 옵션에 비해 뚜렷한 이점이 있습니다. 제공되는 자동화 시스템은 MetaTrader 5 터미널에서 직접 철저히 테스트할 수 있습니다. 매수하기 전에 Expert Advisor는 시스템을 완전히 파악하기 위해 내장된 전략 테스터의 모든 불리한 모드에서 신중하게 실행할 수 있고 또 실행해야 합니다.
머신 러닝: 트레이딩에서 서포트 벡터 머신을 사용하는 방법 머신 러닝: 트레이딩에서 서포트 벡터 머신을 사용하는 방법
Support Vector Machine은 복잡한 데이터 세트를 평가하고 데이터를 분류하는 데 사용할 수 있는 유용한 패턴을 추출하기 위해 생물정보학 및 응용 수학과 같은 분야에서 오랫동안 사용되어 왔습니다. 이 글에서는 서포트 벡터 머신이 무엇인지, 어떻게 작동하는지, 왜 복잡한 패턴을 추출하는 데 유용할 수 있는지 살펴봅니다. 그런 다음 시장에 적용할 수 있는 방법과 잠재적으로 거래에 조언하는 데 사용할 수 있는 방법을 조사합니다. Support Vector Machine Learning Tool을 사용하여 이 글은 독자가 자신의 거래를 실험할 수 있는 작업 예제를 제공합니다.
MetaTrader 4 및 MetaTrader 5의 신호 제공자가 되는 방법 MetaTrader 4 및 MetaTrader 5의 신호 제공자가 되는 방법
거래 시그널을 제공하고 수익을 내고 싶으시나요? MQL5.com 웹사이트에 판매자로 등록하고 거래 계정을 지정하고 트레이더들이 여러분의 거래를 복사할 수 있는 구독을 제공하세요.
"즉석에서" 사용자 패널에서 Expert Advisor 매개변수 변경 "즉석에서" 사용자 패널에서 Expert Advisor 매개변수 변경
이 글은 사용자 패널에서 매개변수를 제어할 수 있는 Expert Advisor의 구현을 보여주는 작은 예시를 제공합니다. "즉시" 매개변수를 변경할 때 Expert Advisor는 정보 패널에서 얻은 값을 파일에 기록하여 파일에서 추가로 읽고 그에 따라 패널에 표시합니다. 이 글은 수동 또는 반자동 모드에서 거래하는 사람들과 관련이 있을 수 있습니다.