"StringToEnum" 함수 또는 대안이 있습니까? - 페이지 3

 
cyberglassed :

위의 코드는 항상 "b = 0"을 반환하기 때문에 쓸모가 없습니다.

정보: "b = 0"은 매번 정보를 제공하지 않습니다.

아니요 3을 반환합니다.


또는 그것이 만나는 마지막 것.

저를 오해하시는 것 같아요.

 sinput string e_string= "MODE_SMMA" ; // Input Ma Method

int b;
if (e_string== EnumToString ( MODE_SMA )){b= 0 ;}
if (e_string== EnumToString ( MODE_EMA )){b= 1 ;}
if (e_string== EnumToString ( MODE_SMMA )){b= 2 ;}
if (e_string== EnumToString ( MODE_LWMA )){b= 3 ;}

Print (b);
 

내가 맞았어? 당신은 문자열로 시작 ??

당신은 또한 그것을 포장 할 수 있습니다 ()

 int b;
sinput string e_string; // Input Ma Method here AS A STRING 

void OnTick (){StringToEnum(); Print (b);} 
  
void StringToEnum()
 {
 if (e_string== EnumToString ( MODE_SMA )){b= 0 ;}
 if (e_string== EnumToString ( MODE_EMA )){b= 1 ;}
 if (e_string== EnumToString ( MODE_SMMA )){b= 2 ;}
 if (e_string== EnumToString ( MODE_LWMA )){b= 3 ;}
 }

그러나 명백한 이유로 문자열이 정확히 일치하는지 확인해야 했습니다. 그렇지 않으면 펑키하지 않도록 더 많은 코드가 필요합니다.

 
Marco vd Heijden :

아니요 3을 반환합니다.

또는 그것이 만나는 마지막 것.

저를 오해하시는 것 같아요.

예, 내 의견을 작성한 후 "else if"를 사용하지 않았으며 3으로 변경했습니다.

마르코 vd 하이덴 :

내가 맞았어? 당신은 문자열로 시작 ??

당신은 또한 그것을 포장 할 수 있습니다 ()

그러나 명백한 이유로 문자열이 정확히 일치하는지 확인해야 했습니다. 그렇지 않으면 펑키하지 않도록 더 많은 코드가 필요합니다.

예, 저는 문자열에서 시작합니다. 그래서 제가 제안하는 함수 의 서명은 다음과 같습니다.

 int StringToEnum( string strId);

어쨌든 우리 모두가 분석했듯이 지금까지 우리가 가진 유일한 해결 방법은 여러 "if"를 사용하는 것입니다.)

 

"그런 다음 어떤 부분에서 문자열 형식 의 일부 열거형 값을 지정하고 싶습니다."

나는 이것의 어떤 이점도 보지 못한다. 예를 보여 주시겠습니까?


방법 1:

int StringToEnum( string strId) {          if ( false ) {}          else if (strId == "PRICE_CLOSE" )     return 1 ;          else if (strId == "PRICE_OPEN" )       return 2 ;          else if (strId == "PRICE_HIGH" )       return 3 ;          else if (strId == "PRICE_LOW" )       return 4 ;          else if (strId == "PRICE_MEDIAN" )     return 5 ;          else if (strId == "PRICE_TYPICAL" )   return 6 ;          else if (strId == "PRICE_WEIGHTED" )   return 7 ;          // ...          return - 1 ; } void OnStart () {          string strId = "PRICE_MEDIAN" ;          printf ( "%s: %d " , strId, StringToEnum(strId)); }

방법 2:

 void OnStart () {
         ENUM_APPLIED_PRICE b= PRICE_MEDIAN ;
        
         printf ( "%s: %d " , EnumToString (b), b);
}

두 경우 모두 열거형의 문자열 이름만 알아야 합니다. 또한 코드가 잘못되었습니다. 이 열거형은 0부터 시작합니다.


 
cyberglassed :

안녕 Alain, 나는 당신의 호기심을 만족시킵니다 :P

여러 개의 외부 mql5 코드를 사용 중이고 여기에 정의된 여러 "열거형" 데이터 유형을 처리한다고 상상해 보십시오. 물론 사람처럼 각 "열거형"의 각 값에 대한 문자열 이름을 기억하는 것이 좋습니다. . 그런 다음 어떤 부분에서 문자열 형식으로 일부 열거형의 값을 지정하고 싶지만 직접 수행할 수 없으므로 위에서 쓴 대로 몇 가지 해결 방법을 사용해야 합니다. 여기에는 두 가지 큰 단점이 있습니다. 첫 번째는 관련된 모든 열거형의 모든 값을 수집해야 하고 두 번째 단점은 유지 관리입니다. 따라서 개발자가 일부 상수 표현과 관련된 int 값을 변경한 외부 mql5 코드를 업데이트하면 다음을 수행할 수 있습니다. 예기치 않은 동작이 발생하므로 코드 업데이트를 계속 검사해야 합니다.

감사합니다만 제가 요청한 것은 아닙니다. 구체적인 코드 예제를 게시할 수 있습니까?

StringToEnum() 함수에 대한 모든 요점은 잘못된 코딩 습관에서 비롯된 것이라고 100% 확신합니다. 열거형의 목표는 어떤 식으로든 코드에 영향을 주지 않는 이 값이 변경되는 경우 기본 정수 값과 독립적인 코드를 빌드하는 것입니다. 또한 MODE_SMA와 같은 식별자를 기억할 수 없지만 문자열 "MODE_SMA"를 사용하면 기억할 수 있는 이유를 모르겠습니다.

보안 누출 주제에 대해... 보안 누출에 대한 열린 문이라는 귀하의 말에 전적으로 동의하지 않습니다. 물론 열린 문이 될 수 있지만 프로그래머는 한계를 설정하고 가능한 중요한 상황을 처리해야 합니다. PHP와 같은 상황을 완벽하게 관리할 수 있습니다. 코드 주입이 있는 SQL에서도 일부 구문을 분석해야 합니다. 사용자가 코드에 액세스할 수 있는 경우 중요한 가능한 입력 데이터입니다.

나는 보안이 코더에 의해 관리될 수 없다고 말하지 않았다. 나는 Metaquotes가 보안이 프로그래머에 의존하는 것을 허용하지 않을 것이라고 말했습니다. 그런 일은 절대 일어나지 않을 것입니다 . ServiceDesk에 요청을 게시하여 요청 하는 것이 좋습니다. 저는 이미 답을 알고 있습니다.

 
cyberglassed :

예, 내 의견을 작성한 후 "else if"를 사용하지 않았으며 3으로 변경했습니다.

예, 저는 문자열에서 시작합니다. 그래서 제가 제안하는 함수의 서명은 다음과 같습니다.

어쨌든 우리 모두가 분석했듯이 지금까지 우리가 가진 유일한 해결 방법은 여러 "if"를 사용하는 것입니다.)


네, 하지만 반복해서 줄로 할 수도 있습니다 .

 //string in="MODE_SMA";  //uncheck either one
 //string in="MODE_EMA";
 string in = "MODE_SMMA" ;
 //string in="MODE_LWMA";    

void OnTick()

{
 int out ;
 
 for ( int i= 0 ;i<= 3 ;i++){ENUM_MA_METHOD mode=i; if ( in ==EnumToString(mode)){ out =i;Print( "out: " , out );}} 
}


하지만 거의 4페이지가 지나도 ...왜그래 하하 :)

 
Marco vd Heijden :

네, 하지만 반복해서 줄로 할 수도 있습니다 .

하지만 거의 4페이지가 지나도 ...왜그래 하하 :)

라즐로 토르마시 :

"그런 다음 어떤 부분에서 문자열 형식의 일부 열거형 값을 지정하고 싶습니다."

나는 이것의 어떤 이점도 보지 못한다. 예를 보여 주시겠습니까?

두 경우 모두 열거형의 문자열 이름만 알아야 합니다. 또한 코드가 잘못되었습니다. 이 열거형은 0부터 시작합니다.

ㅋㅋㅋㅋ 마르코 랑 라즐로 죄송합니다 가끔 문제를 축소하려고 하면 상대방의 궁금증이 커지는 경우가 있습니다 :P

여기에 내가 얻고자 하는 것에 대한 아주 가까운 예가 있습니다. 다음은 완전한 작업 스크립트(복사/붙여넣기/실행)입니다.

 string get_price_type() {
         string
                config_url = "http://tempsend.com/D56DA3A9EA/CBB5/config.txt" , /* available for 30 days from now */
                cookie = NULL ,
                headers,
                ret;
         char
                post[],
                result[];               

         // WebRequest needs the following configuration:
         // 1- check: Tools/Options/Expert Advisors/Allow WebRequest for listed URL
         // 2- add url: http://tempsend.com  [this is the domain name on: config_url]
         int res = WebRequest( "GET" , config_url, cookie, NULL , 5000 ,  post, 0 , result, headers);
        
         if (res == - 1 ) {
                 Print ( "Error in WebRequest. Error code: " , GetLastError ());
                ret = "Error" ;
        }
         else {
                ret = CharArrayToString (result);
                 StringTrimRight (ret);
        }
         return ret;
}

int StringToEnum( string strId) {
         if ( false ) {}
         else if (strId == "PRICE_CLOSE" )     return 1 ;
         else if (strId == "PRICE_OPEN" )       return 2 ;
         else if (strId == "PRICE_HIGH" )       return 3 ;
         else if (strId == "PRICE_LOW" )       return 4 ;
         else if (strId == "PRICE_MEDIAN" )     return 5 ;
         else if (strId == "PRICE_TYPICAL" )   return 6 ;
         else if (strId == "PRICE_WEIGHTED" )   return 7 ;
         return - 1 ;
}

void OnStart () {
         string price_type = get_price_type();
         int price_type_int = StringToEnum(price_type);
         printf ( "price_type -> %s: %d" , price_type, price_type_int);
        
         ChartSetInteger ( 0 , CHART_SCALE , 3 );
         ChartSetInteger ( 0 , CHART_MODE , CHART_CANDLES );

         int handle = iMA ( "EURUSD" , PERIOD_CURRENT , 10 , 0 , MODE_SMA , price_type_int);
         ChartIndicatorAdd ( 0 , 0 , handle);
}

가격 유형은 "config_url"에 제공된 온라인 파일에 설정되며 해당 내용은 다음 값 중 하나로 언제든지 변경할 수 있습니다.

{PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED}

유형은 사람이 읽을 수 있는 형식으로 제공됩니다(예: PRICE_MEDIAN(int가 아님)).

Laszlo , mql5에서 오프셋은 0이 아니라 1입니다(mql4와 다름). 간단한 스크립트로 확인 하고 놀랐습니다. 그렇기 때문에 유지보수 문제 -> 혼선 가능성에 대해 이야기하는 것입니다.
 
Alain Verleyen :

감사합니다만 그건 제가 요청한 것이 아닙니다. 구체적인 코드 예제를 게시할 수 있습니까?

StringToEnum() 함수에 대한 모든 요점은 잘못된 코딩 관행에서 비롯된 것이라고 100% 확신합니다. 열거형의 목표는 어떤 식으로든 코드에 영향을 주지 않는 이 값이 변경되는 경우 기본 정수 값과 독립적인 코드를 빌드하는 것입니다. 또한 MODE_SMA와 같은 식별자를 기억할 수 없지만 문자열 "MODE_SMA"를 사용하면 기억할 수 있는 이유를 모르겠습니다.

나는 보안이 코더에 의해 관리될 수 없다고 말하지 않았다. 나는 Metaquotes가 보안이 프로그래머에 의존하는 것을 허용하지 않을 것이라고 말했습니다. 그런 일은 절대 일어나지 않을 것입니다 . ServiceDesk에 요청을 게시하여 요청 하는 것이 좋습니다. 저는 이미 답을 알고 있습니다.

내가 틀렸고 StringToEnum() 함수(일반 각 열거형에 대해 코딩되지 않음)가 필요한 상황에 직면했다는 것을 알고 있습니다. 이해하기에 너무 늦지 않았습니다. 100% 확신해서는 안 됩니다.

 
Alain Verleyen :

내가 틀렸고 StringToEnum() 함수(일반 각 열거형에 대해 코딩되지 않음)가 필요한 상황에 직면했다는 것을 알고 있습니다. 이해하기에 너무 늦지 않았습니다. 100% 확신해서는 안 됩니다.

확인. 다음은 일반 StringToEnum() 함수 입니다.

#define MIN_ENUM_VALUES 0
#define MAX_ENUM_VALUES 255
//+------------------------------------------------------------------+
//| StringToEnum : Convert a string to an ENUM value,                |
//|   it loop between min(0) and max(255), adjustable if needed.     |
//|   Non existing enum value defined as -1. If -1 is used as an     |
//|   enum value, code need to be adjusted to an other default.      |
//| Parameters :                                                     |
//|   in       - string to convert                                   |
//|   out      - ENUM value                                          |
//|   @return  - true if conversion succeed, false otherwise         |
//+------------------------------------------------------------------+
template<typename ENUM>
bool StringToEnum( string in ,ENUM & out )
  {
   out =- 1 ;
//---
   for ( int i=MIN_ENUM_VALUES;i<=MAX_ENUM_VALUES;i++)
     {
      ENUM enumValue=(ENUM)i;
       if ( in ==EnumToString(enumValue))
        {
         out =enumValue;
         break ;
        }
     }
//---
   return ( out !=- 1 );
  }

사용 예:

 //+------------------------------------------------------------------+
//| testing enums                                                    |
//+------------------------------------------------------------------+
enum ENUM_TEST
  {
   FIRST_CASE= 1 ,
   SECOND_CASE= 2

  };
//---
enum ENUM_ANOTHER_TEST
  {
   CASE_ONE,
   CASE_TWO,
   CASE_THREE
  };
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void    OnStart ()
  {
   ENUM_TEST which;
   if (!StringToEnum( "SECOND_CASE" ,which)) return ;

   ENUM_ANOTHER_TEST which_other;
   if (!StringToEnum( "CASE_ONE" ,which_other)) return ;

   ENUM_TEST wrongwhich;
   if (!StringToEnum( "blah blah" ,wrongwhich)) return ;

//---
  }
 
Alain Verleyen 함수 입니다.

사용 예:

4.5년 후, 그러나 나 자신을 위한 이러한 요구에 대한 해결책을 찾기 위해 이 게시물을 보게 되었습니다. @Alain Verleyen 초기 "이 기능이 필요한 이유를 알 수 없음" 및 "이 기능이 필요한 경우 코드가 잘못된 것입니다"라는 응답에 대응하는 용도를 찾은 것을 기쁘게 생각합니다. 😛

나는 이것이 유용할 수 있는 다양한 상황을 겪었지만, 당신이나 나 모두 그 필요성을 발견한 적이 없다 하더라도 질문이 있습니다. StringToEnum()이 존재할 이유가 없다면, 왜 존재해야 할까요? EnumToString()이 존재하는 이유는 무엇입니까? 또는 반대로 EnumToString()이 존재하는 경우 해당 함수를 사용하여 열거형을 문자열로 변환한 다음 때때로 다시 변환하고 싶을 때가 있다고 생각하는 것이 확실히 부당하지 않습니까? 😉

말할 필요도 없이 내 실제 예: 한 번에 여러 차트에서 실행할 필요 없이 실행 중인 차트와 상관없이 여러 기호/시간 프레임 조합에서 한 번에 작동하는 EA가 있습니다. 그 접근 방식에는 장단점이 있지만 제 경우에는 확실히 장점이 단점보다 큽니다.

그래서... 내가 거래를 할 때 거래의 코멘트에서 Trade Info 기능이 제공하지 않는 몇 가지 세부 사항을 보고 싶습니다. 그 논리(일부는 기간에 따라 다름)가 때때로 거래를 수정(예: SL)하거나 거래를 마감하는 시기에 영향을 미치므로 거래를 가장 먼저 배치하십시오. 그래서 나는 그 정보를 사람이 읽을 수 있는 형식(예: H4, 14400이 아님)으로 보고 싶지만 물론 EA가 거래 수정 또는 종료에 대한 결정을 내릴 때 숫자 열거형 값을 사용할 수 있기를 바랍니다. .

따라서 EnumToString(timeframe)을 사용하여 주석에 있는 시간 프레임의 문자열 표현을 사용합니다. 그런 다음 나중에 OrderComment()(또는 해당 mql5 버전)를 사용하여 거래에서 주석을 얻을 수 있고 주석에서 시간 프레임의 문자열 표현을 구문 분석하여 예를 들어 얻을 수 있습니다. "PERIOD_H4". StringToEnum("...") 함수는 이를 다시 숫자 값으로 변환합니다. 이 값은 시간 프레임의 경우 분 수입니다(즉, 열거형은 0에서 대부분의 열거형과 같이 순차적이지 않으며 큰 간격이 있습니다. , 예를 들어 D1, W1 및 MN1 사이). 물론 주석에 enum 정수 값을 포함할 수도 있지만 이는 StringToEnum()이 없는 경우의 (불필요한) 해결 방법입니다.

귀하의 솔루션은 현재 얻을 수 있는 만큼 좋은 것 같습니다. 단, 이 경우 MAX 값을 43200으로 늘려 포괄적인 상태를 유지하면서 포괄적인 상태를 유지해야 합니다( https://docs.mql4. com/constants/chartconstants/enum_timeframes ).

물론 OrderTimeframe() 또는 OrderPeriod() 함수는 특정 요구 사항을 충족하지만 내가 말했듯이 이것은 StringToEnum() 함수가 도움이 될 몇 가지 상황 중 하나일 뿐입니다. 분명히 당신도 하나를 찾았습니다. 😉

솔루션을 공유해 주셔서 감사합니다. 그리고 당신이 틀렸음을 인정하는 겸손함에 대해 경의를 표합니다. 😊

MQL4/5 문서 어딘가에 가능한 모든 열거형 및 열거형 값의 목록이 있는지 궁금합니다. https://www.mql5.com/en/docs/constant_indices 및 해당 페이지의 해당 mql4 버전이 있습니다. 그러나 숫자 값은 나열되지 않습니다. 그 페이지의 텍스트를 복사하여 값 목록으로 모두 구문 분석하고 가능한 모든 값을 인쇄하는 함수를 작성할 수 있다고 가정합니다. 그러나 물론 그것은 약간 지루하고 향후 추가 사항을 설명하지 않습니다. 적어도 모든 열거 형의 가능한 최대 값을 알려줄 것입니다.

속도를 절약하기 위해 함수를 최대 256 대신 1440(시간 프레임의 경우 D1, 다른 열거형의 경우 다른 모든 값)까지 모든 값을 반복하도록 조정한 다음 두 개를 추가할 수 있습니다. W1 및 MN1에 대한 보다 구체적인 검사. 최대값을 늘리면 여전히 더 낮은 최대값에 맞는 모든 경우에 오버헤드가 추가되지 않습니다. 왜냐하면 더 낮은 최대값 아래에 맞는 모든 것이 어쨌든 같은 시간에 루프에서 나오기 때문입니다.

1440보다 높은 숫자 값을 가진 다른 열거형이 있습니까?

Chart Timeframes - Chart Constants - Constants, Enumerations and Structures - MQL4 Reference
Chart Timeframes - Chart Constants - Constants, Enumerations and Structures - MQL4 Reference
  • docs.mql4.com
Chart Timeframes - Chart Constants - Constants, Enumerations and Structures - MQL4 Reference
사유: