ライブラリ: TypeToBytes - ページ 6

 

構造体を文字列に変換するコード

#include <Data_String.mqh>
#define  DEFINE_STRING(A)                        \
  struct STRING##A                              \
  {                                             \
  private:                                      \
    short Array[A];                             \
                                                \
  public:                                       \
    void operator =( const string Str )         \
    {                                           \
      ::StringToShortArray(Str, this.Array);    \
      return;                                   \
    }                                           \
                                                \
    string operator []( const int = 0 ) const   \
    {                                           \
      return(::ShortArrayToString(this.Array)); \
    }                                           \
  };
DEFINE_STRING(120) // 最大128文字を持つ文字列のアナログ。
#undef  DEFINE_STRING

struct str_Message
  {
   int               cnt;
   bool              res;
   double            ter;
   STRING120          str;
  };
void OnStart()
  {
//---
   str_Message a;
   a.cnt = 10;
   a.res = false;
   a.ter = 20.0123;
   a.str = "hello world";
   Print(DATA_STRING::ToString(str1););
  }

// Результат
//2020.03.31 10:43:18.320	StructTest2 (EURUSD,H1)	CgAAAAClvcEXJgM0QGgAZQBsAGwAbwAgAHcAbwByAGwAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


逆変換の方法は?(文字列から構造体へ)

 
Sergey Likho:

コードは構造体を文字列に変換する

逆変換を行うには?(文字列から構造体へ)

const string Str = DATA_STRING::ToString(a); // 構造体を文字列に変換。

str_Message Tmp[1];

// 文字列から構造体の配列を取得する
if (DATA_STRING::FromString(Str, Tmp))   
{
  ArrayPrint(Tmp);
  Print(Tmp[0].str[]);   
  
  Print(_R(Tmp) == a); // データが元のデータと一致しているか確認する。
}

// 文字列から構造体を取得する。
// Tmp[0] = DATA_STRING::FromString<str_Message>(Str);// これは代入演算子がない場合に可能である(STRING120::operator =参照)。
 
ライブラリーの能力のもう一つの応用 例。
 
//+------------------------------------------------------------------+
//|をテストします。mq5
//|著作権 2021, MetaQuotes Ltd.|
//|https://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <TypeToBytes.mqh> 


CONTAINER <uchar> Container;


int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
|エキスパート初期化関数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| エキスパートティック機能|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+


黄色の行のコードがコンパイルできなくなりました。次のようなエラーが出ます(ビルド2980):

この問題を解決する方法があれば教えてください。

 
Enrique Dangeroux:

黄色の行のコードがコンパイルできなくなりました。以下のようなエラーが発生する(ビルド2980):

この問題を解決する方法があれば教えてください。

 
ありがとう。
 

更新発見された機能を 回避。以前は_ArrayCopyと CONTAINERに 悪影響を与える可能性があった。

 

あなたのライブラリを使って、任意の長さの文字列をグローバル変数に 保存する関数を書きました。すべてを理解しているわけではないので、100%使いこなせていないのは確かです。

もっと効率的な使い方があれば教えてください。

#include <TypeToBytes.mqh>


//--------------------------------------------------------------------------------------------------
string
GVarGetString(string name) {
        double dbl[];
        
        // 変数の各部分を読む:Name, Name(1), Name(2), ...
        for (int i = 0; ; ++i) {
                string s = (i == 0)? "" : "(" + (string)i + ")";
                double t = GlobalVariableGet(name + s);
                if (t == 0)
                        break;
                
                MyArrayResize(dbl, i + 1);
                dbl[i] = t;
        }
        
        uchar tmp0[], tmp[], tmp1[];  
        _ArrayCopy(tmp0, dbl);
        if (tmp0[0] != 0)
                // 非圧縮
                return CharArrayToString(tmp0);
        else {
                // 圧縮あり
                ArrayCopy(tmp, tmp0, 0, 1);
                CryptDecode(CRYPT_ARCH_ZIP, tmp, tmp1, tmp1);
                return CharArrayToString(tmp1);
        }
}


//--------------------------------------------------------------------------------------------------
void
GVarSetString(string name, string val) {
        double dbl[];
        uchar tmp[];
        uchar zero[1];
        int cnt = CryptEncode(CRYPT_ARCH_ZIP, _R(val).Bytes, tmp, tmp);
        if (cnt >= StringLen(val)) {
                // 非圧縮
                string str[1];
                str[0] = val;
                _ArrayCopy(dbl, str);
        }
        else {
                // 圧縮あり
                _ArrayCopy(dbl, zero, 0, 0, 1);         // Byte[0] == 0 - 圧縮あり
                _ArrayCopy(dbl, tmp, 1);                // バイト[1]データから
        }
        
        // 変数の各部分を書く:Name、Name(1)、Name(2)、...
        cnt = ArraySize(dbl);
        for (int i = 0; i < cnt; ++i) {
                string s = (i == 0)? "" : "(" + (string)i + ")";
                GlobalVariableSet(name + s, dbl[i]);
        }
        GlobalVariablesFlush();
}
 
Edgar Akhmadeev グローバル変数に 保存する関数を書きました。すべてを理解しているわけではないので、100%使いこなせていないことは確かだ。

もっと効率的な使い方があれば教えてください。

このオプションを チェックしてみてください。


グローバル変数にCONTAINER<double>を 使うのも便利だと思います

Нужны ли глобальные переменные терминала типа string? - Используйте темплейты, чтобы разработчики платформы отвлекались на всякую блажь.
Нужны ли глобальные переменные терминала типа string? - Используйте темплейты, чтобы разработчики платформы отвлекались на всякую блажь.
  • 2017.04.08
  • Mikhail Dovbakh
  • www.mql5.com
и динамическое формирование имени массива не обязательно строкового. Отдельный тип глобальных переменных - скорее всего не добавят. таким образом можно записывать и считывать из глобальных переменных строки
 
fxsaber #:

このオプションを チェックしてみよう。


グローバル変数にCONTAINER<double>を 使うのも便利だろう。

ありがとうございます。