bazı "StringToEnum" işlevi veya alternatifi var mı? - sayfa 3

 
cyberglassed :

yukarıdaki kodunuz işe yaramaz çünkü her zaman "b = 0" döndürür

ve bilgi: "b = 0" her seferinde herhangi bir bilgi vermez.

hayır 3 döndürür.


ya da son karşılaştığı kişi.

sanırım beni yanlış anlıyorsun

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

doğru mu anladım bir dize ile başlar mısın?

onu da sarabilirsin ()

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

ancak bariz nedenlerden dolayı dizenin tam olarak eşleştiğinden emin olmanız gerekiyordu, yoksa korkak olmadığından emin olmak için daha fazla koda ihtiyacı olacak.

 
Marco vd Heijden :

hayır 3 döndürür.

ya da en son karşılaştığı kişi.

sanırım beni yanlış anlıyorsun

evet, yorumumu yazdıktan sonra "else if" kullanmadığınızı fark ettim ve 3 olarak değiştirdim

Marco vd Heijden :

doğru mu anladım bir dize ile başlar mısın?

onu da sarabilirsin ()

ancak bariz nedenlerden dolayı dizenin tam olarak eşleştiğinden emin olmanız gerekiyordu, yoksa korkak olmadığından emin olmak için daha fazla koda ihtiyacı olacak.

evet, bir dizgeden başlıyorum, bu yüzden önerdiğim fonksiyonun imzası:

 int StringToEnum( string strId);

neyse, hepimizin analiz ettiği gibi, şimdiye kadar sahip olduğumuz tek geçici çözüm, birden fazla "if" kullanmaktır;)

 

"Sonra bir kısımda, bazı enumların bazı değerlerini dize biçiminde belirtmek istiyorsunuz."

Bunun bir avantajını görmüyorum. Bir örnek gösterebilir misiniz?


Yöntem 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)); }

Yöntem 2:

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

Her iki durumda da numaralandırmanın yalnızca dize adını bilmeniz gerekir. Ayrıca kodunuz yanlış, bu numaralandırma 0'dan başlıyor.


 
cyberglassed :

Merhaba Alain, merakınızı giderdim :P

Birden çok harici mql5 kodu kullandığınızı, o zaman üzerlerinde tanımlanmış birden çok "enum" veri türüyle uğraştığınızı ve elbette bir insan gibi, her "enum" değerinin dize adını hatırlamanız sizin için daha iyidir. . Sonra bir kısımda bazı enumların bazı değerlerini string formatında belirtmek istiyorsunuz, o zaman bunu doğrudan yapamazsınız, bu yüzden yukarıda yazdığım gibi bir geçici çözüm kullanmanız gerekiyor. Bunun iki büyük dezavantajı vardır, birincisi, ilgili tüm numaralandırmaların tüm değerlerini toplamanız gerekir ve ikinci dezavantaj, bakımdır, bu nedenle geliştiricinin bazı sabit temsillerle ilişkili int değerini değiştirdiği bazı harici mql5 kodunu güncellerseniz, o zaman yapabilirsiniz. beklenmeyen davranışlar elde edin, bu nedenle koddaki güncellemeleri incelemeye devam etmeniz gerekir.

Teşekkürler ama gerçekten istediğim şey bu değildi. Somut bir kod örneği gönderebilir misiniz?

StringToEnum() işleviyle ilgili tüm noktanızın kötü bir kodlama uygulamasından geldiğinden %100 eminim. Bir numaralandırmanın amacı, temeldeki tamsayı değerinden bağımsız olarak kod oluşturmaktır, bu değer değiştirilirse bu, kodunuzu hiçbir şekilde etkilememelidir. Ayrıca MODE_SMA gibi bir tanımlayıcıyı neden hatırlayamadığınızı anlamıyorum, ancak "MODE_SMA" dizesiyle yapabilirsiniz.

Güvenlik sızıntısı konusu hakkında... Güvenlik sızıntısına açık bir kapı olduğu konusunda söylediklerinize tam olarak katılmıyorum. Tabii ki bu açık bir kapı olabilir, ancak programcı olarak sınırları belirlemeli ve olası kritik durumlarla ilgilenmelisiniz, yani PHP'deki gibi durumları mükemmel bir şekilde yönetebilirsiniz, hatta bazılarını ayrıştırmanız gereken kod enjeksiyonu ile SQL'de bile. kodunuza erişimleri olması durumunda kullanıcılardan gelen kritik olası giriş verileri.

Güvenliğin kodlayıcı tarafından yönetilemeyeceğini söylemedim. Metaquotes'ın bu güvenliğin programcılara güvenmesine izin VERMEZ dedim. Bu asla olmayacak, ServiceDesk'e bir isteğinizi göndererek onlara sormanızı öneririm, cevabı zaten biliyorum.

 
cyberglassed :

evet, yorumumu yazdıktan sonra "else if" kullanmadığınızı fark ettim ve 3 olarak değiştirdim

evet, bir dizgeden başlıyorum, bu yüzden önerdiğim fonksiyonun imzası:

neyse, hepimizin analiz ettiği gibi, şimdiye kadar sahip olduğumuz tek geçici çözüm, birden fazla "if" kullanmaktır;)


evet ama bunu döngüye alıp tek satırda da yapabilirsiniz.

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


ama yine de neredeyse 4 sayfadan sonra ...neden haha :)

 
Marco vd Heijden :

evet ama bunu döngüye alıp tek satırda da yapabilirsiniz.

ama yine de neredeyse 4 sayfadan sonra ...neden haha :)

Laszlo Torması :

"Sonra bir kısımda, bazı enumların bazı değerlerini dize biçiminde belirtmek istiyorsunuz."

Bunun bir avantajını görmüyorum. Bir örnek gösterebilir misiniz?

Her iki durumda da numaralandırmanın yalnızca dize adını bilmeniz gerekir. Ayrıca kodunuz yanlış, bu numaralandırma 0'dan başlıyor.

hahaha Marco ve Laszlo üzgünüm, bazen sorunu küçültmeye çalışırken karşı taraftaki merak artıyor :P

burada almak istediğim şeye çok yakın bir örneğiniz var (hepinizi rahatsız etmemek için biraz küçülttüm). Aşağıda tam bir çalışan komut dosyası bulunmaktadır (kopyala/yapıştır/çalıştır):

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

fiyat türü "config_url" adresinde verilen çevrimiçi dosyada belirlenir ve içeriği herhangi bir zamanda aşağıdaki değerlerden biri ile değiştirilebilir:

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

Tür, insan tarafından okunabilir biçimde verilecektir, örneğin: PRICE_MEDIAN (int değil).

Laszlo , mql5'te ofset 0 değil (mql4'ten farklı) 1'dir, basit bir komut dosyasıyla kontrol ettim ve şaşırdım. Bu yüzden bakım probleminden -> olası karışıklıklardan bahsediyorum.
 
Alain Verleyen :

Teşekkürler ama gerçekten istediğim şey bu değildi. Somut bir kod örneği gönderebilir misiniz?

StringToEnum() işleviyle ilgili tüm noktanızın kötü bir kodlama uygulamasından geldiğinden %100 eminim. Bir numaralandırmanın amacı, temeldeki tamsayı değerinden bağımsız olarak kod oluşturmaktır, bu değer değiştirilirse bu, kodunuzu hiçbir şekilde etkilememelidir. Ayrıca MODE_SMA gibi bir tanımlayıcıyı neden hatırlayamadığınızı anlamıyorum, ancak "MODE_SMA" dizesiyle yapabilirsiniz.

Güvenliğin kodlayıcı tarafından yönetilemeyeceğini söylemedim. Metaquotes'ın bu güvenliğin programcılara güvenmesine izin VERMEZ dedim. Bu asla olmayacak, ServiceDesk'e bir isteğinizi göndererek onlara sormanızı öneririm, cevabı zaten biliyorum.

Yanılmışım ve bir StringToEnum() işlevine ihtiyaç duyacağım bir durumla karşı karşıya olduğumu biliyorum (her numaralandırma için kodlanmaması gereken genel). Anlamak için asla geç değil, asla %100 emin olmamalıyım

 
Alain Verleyen :

Yanılmışım ve bir StringToEnum() işlevine ihtiyaç duyacağım bir durumla karşı karşıya olduğumu biliyorum (her numaralandırma için kodlanmaması gereken genel). Anlamak için asla geç değil, asla %100 emin olmamalıyım

Tamam. İşte genel bir StringToEnum() işlevi :

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

Kullanım örneği:

 //+------------------------------------------------------------------+
//| 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 işlevi :

Kullanım örneği:

4.5 yıl sonra, ancak kendim için bu ihtiyaca bir çözüm ararken bu gönderiye rastladım. @Alain Verleyen "Neden buna ihtiyacımız olduğunu göremiyorum" ve "bu işleve ihtiyacınız varsa, kodunuz bozuk" yanıtlarınıza karşı bir kullanım bulduğunuza sevindim. 😛

Bunun yararlı olacağı bir dizi farklı durumla karşılaştım, ancak ne sen ne de ben hiçbir zaman bir ihtiyaç bulamamış olsak bile, şu soru var: StringToEnum()'un var olması için bir neden yoksa, neden var olsun ki? EnumToString() var olma nedeni? Veya tersine, eğer EnumToString() varsa, o zaman bu işlevi kullanarak bir enum'u bir dizgeye dönüştüreceğimiz ve sonra bazen onu geri dönüştürmek isteyeceğimiz zamanların olabileceğini düşünmek kesinlikle mantıksız değil mi? 😉

Söylemeye gerek yok, benim pratik örneğim: Üzerinde çalıştığı grafikten bağımsız olarak, aynı anda birden çok simge/zaman aralığı kombinasyonu üzerinde çalışan bir EA'm var - aynı anda birden çok grafik üzerinde çalıştırmaya gerek kalmadan. Bu yaklaşımın artıları ve eksileri var, ama benim durumumda artılar kesinlikle eksilerden daha ağır basıyor.

Yani... bir işlem yaptığımda, işlemin yorumlarında, İşlem Bilgisi işlevlerinin sağlamadığı, bununla ilgili birkaç ayrıntı görmek istiyorum; bunlardan biri, işlem yapılıp yapılmayacağının mantığını belirlemek için kullanılan zaman dilimidir. Bu mantık (bazıları zaman çerçevesine bağlıdır) bazen ticaretin ne zaman değiştirileceğini (örn. SL) veya kapatılacağını etkileyeceğinden, ticareti ilk etapta yerleştirin. Bu yüzden bu bilgiyi insan tarafından okunabilir bir biçimde görmek istiyorum (örn. H4, 14400 değil), ancak elbette EA'nın ticareti değiştirme veya kapatma hakkında kararlar verirken sayısal enum değerinden yararlanabilmesini istiyorum. .

Bu yüzden yorumda zaman çerçevesinin bir dize temsiline sahip olmak için EnumToString(timeframe) kullanıyorum. Daha sonra OrderComment() (veya ilgili mql5 sürümünü) kullanarak ticaretten yorumu alabilirim ve daha sonra örneğin elde etmek için yorumdan zaman çerçevesinin dize temsilini ayrıştırabilirim. "PERIOD_H4". Bir StringToEnum("...") işlevi, bunu, zaman dilimleri söz konusu olduğunda dakika sayısı olan sayısal değere dönüştürür (yani numaralandırma, 0'dan çoğu numaralandırma gibi bir şeye sıralı değildir, büyük boşluklar vardır). , örneğin D1, W1 ve MN1) arasında. Tabii ki yoruma enum tamsayı değerini de ekleyebilirim, ancak bu StringToEnum() yokluğunun (gereksiz olması gereken) bir geçici çözümü.

Çözümünüz şu anda olduğu kadar iyi görünüyor, ancak bu durumda, genel kalırken bunu kapsayacak kadar kapsamlı olması için MAX değerini 43200'e çıkarmamız gerekecek ( https://docs.mql4. com/constants/chartconstants/enum_timeframes ).

Elbette bir OrderTimeframe() veya OrderPeriod() işlevi bu özel ihtiyacı karşılayacaktır, ancak dediğim gibi bu, bir StringToEnum() işlevinin yardımcı olabileceği birkaç durumdan sadece biri. Görünüşe göre sen de bir tane bulmuşsun. 😉

Çözümünüzü paylaştığınız için teşekkürler. Ve yanıldığını kabul etme konusundaki alçakgönüllülüğün için seni tebrik ederim. 😊

MQL4/5 belgelerinde bir yerde olası tüm numaralandırmaların ve numaralandırma değerlerinin bir listesi olup olmadığını merak ediyorum. Şu var: https://www.mql5.com/en/docs/constant_indices ve o sayfanın karşılık gelen mql4 sürümü, ancak sayısal değerlerin hiçbirini listelemese de. Sanırım o sayfanın metnini kopyalayabilir, hepsini bir değerler listesi içinde ayrıştırabilir ve olası tüm değerleri yazdırmak için bir işlev yazabilirim. Ama tabii ki bu biraz sıkıcı, ayrıca gelecekteki eklemeleri hesaba katmıyor. En azından bana herhangi bir numaralandırmanın mümkün olan maksimum değerini söyleyecek.

Hızdan tasarruf etmek için, muhtemelen işlevinizi, 256 yerine maksimum 1440'a kadar tüm değerler arasında döngü yapacak şekilde uyarlayabilirim (zaman dilimleri durumunda D1 için ve diğer numaralandırmalar durumunda başka ne olursa olsun) ve sonra iki tane ekleyin W1 ve MN1 için daha spesifik kontroller. Maks değerini artırmak, yine de alt maksimuma sığacak tüm durumlara herhangi bir ek yük eklemeyecektir, çünkü alt maksimumun altına uyan herhangi bir şey her iki şekilde de aynı anda döngüden çıkar.

1440'tan daha yüksek sayısal değerlere sahip başka numaralar var mı?

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
Neden: