初学者的问题 MQL5 MT5 MetaTrader 5 - 页 1201

 
Сергей Таболин:

我把所有东西都写在一个文件里。写入,然后读取,几个结构到同一个文件,都很顺利。

但它从头到尾都是在读数组。你如何把它分成三部分?你是如何写出一个结构并设法将一个数组写入同一个文件的? 我是自学成才的,我知道的不多,但事实上,它们是不同的数据格式,我多少有些怀疑。

我承认,你可以设法打开文件 写一次,把三个数组塞进去,但你不能像这样分次读取。

[删除]  
Alexey Viktorov:

但它从头到尾都是在读数组。你如何把它分成三部分?你是如何写一个结构并设法将一个数组写入同一个文件的?我是自学成才的,知道的不多,但事实上,它们是不同的数据格式,不知为何我怀疑。

我承认,我可以侥幸地打开一个文件 写一次,把三个数组塞进去,但我不能那么容易地分次阅读。

我说,如果你只向同一个文件写入1个结构和3个数组,那么你可以从那里读取它们(假设要读取数组,你必须指定每个数组的大小)。但写完后再读几个这样的序列的技巧对我来说并不奏效。也许我需要移动指针,但它已经很紧张了......

 
Сергей Таболин:

我告诉过你,如果你只把1个结构和3个数组写到一个文件里,那么你以后就可以从那里读取它们(前提是你必须指定每个数组的大小来读取数组)。但写完后再读几个这样的序列的技巧对我来说并不奏效。也许我需要移动指针,但这有点麻烦......。

它是如何紧张的?马力不够?而你怎么能确定写是成功的,如果读失败了,你又怎么能假设这一点?据我所知,你不能用眼睛去看一个.bin文件。

 
Сергей Таболин:

Artyom,你能给我一个例子吗?考虑到数组的大小是动态的。

不,现在还不会有例子--我自己还没有做过,等我做了,我会在我的文章中描述。而这将是不快的。事实是,你只能用FileWriteStruct()将POD结构写入文件。这就是不包含字符串的简单结构、动态数组、虚拟函数,以及指向对象和函数的指针。

而这意味着,你必须发明和测试它们。但我已经写好了方向。需要考虑实施的问题。

 
Artyom Trishkin:

不,现在还不会有例子--我自己还没有做过,等我做了,我会在文章中描述。而且不会很快。事实上,只有POD结构可以使用FileWriteStruct()写入文件。也就是说,不包含 字符串的简单结构、动态 数组、虚拟函数,以及指向对象和函数的指针。

而这意味着我们必须发明并测试它。但我已经写好了方向。应该对执行情况进行思考。

事实证明,无论你怎么看,这个任务都是无法解决的。毕竟,Sergei的例子里面有三个动态数组。无论结构中如何安排,它都将是一个动态数组。

但如果你创建了一个结构数组,问题就可以通过写数组来解决了。FileWriteArray()。这已经被测试过了,文档中清楚地说明了关于写一个结构数组的问题。

 
Alexey Viktorov:

但它从头到尾都是在读数组。你如何把它分成三部分?你是如何写一个结构并设法将一个数组写入同一个文件的?我是自学成才的,我不知道很多事情,但事实上,他们是不同的数据格式,不知为何我怀疑。

我承认,你可以不这样做,打开一个文件 写一次,把三个数组塞进去,但你将无法像这样分次读取。

在二进制文件中,你可以在一个文件中写入任何结构、数组,甚至单个变量。

但是,在读取时,你必须以相同的顺序读取数据。

一切都会成功。

没有看到文件转储,当用FileWriteArray()写的时候,很可能数组的大小会写在第一个字节里 - 但是做一个测试脚本更容易,有十几行代码;)

 
Alexey Viktorov:

事实证明,无论你怎么看,这个问题都是无法解决的。毕竟,在Sergei的例子中,里面有三个动态数组。无论你如何构建结构中的结构,它仍将是一个动态阵列。

而如果你创建了一个结构数组,你将通过写数组来解决这个问题。FileWriteArray()。这一点已经被测试过了,而且在文档中明确说明了关于写一个结构数组的问题。

一个结构数组被存储起来,但是......如果有字符串,它们可以被打包成结构内的ucar数组,这就成功了。但是,数组中的双倍数不可能装入数组中的Uchar。此外,它是动态的。把三个数组分别保存到文件中,然后把它们塞进从文件中解压的结构中。我还没有试过。我没有想过这个问题,也不知道。

 
Igor Makanu:

你可以将任何结构、数组,甚至单个变量写入二进制文件--都在同一个文件中。

但在读取时,你必须以相同的顺序读取数据。

一切都会成功

没有看到用FileWriteArray()写入时的文件转储,最可能的是,数组的大小会写在第一个字节中--但做一个测试脚本更容易,有十几行代码;)

我不知道你是从哪里开始读到这个问题的,让我提醒你一下,以防万一:你必须把一个包含三个动态数组的结构写进一个文件。然后我有一个问题,就是文件没有被正确读取。

关于交易、自动交易系统和策略测试的论坛

初学者的常见问题 MQL5 MT5 MetaTrader 5

Sergey Tabolin, 2020.03.24 18:02

我在问))))

我曾试图用 "我的方式 "来做。

第一个结构和3个数组读取正常(前提是数组接收器不是动态的,否则在结构之后写入的所有数据都会被读入第一个数组)。

然而,如果有更多的条目,那么

   // Проверка
   double   rdata_1[6];
   double   rdata_2[6];
   double   rdata_3[6];
   
   filehandle = FileOpen(filename,FILE_READ|FILE_COMMON|FILE_BIN);
   if(filehandle != INVALID_HANDLE)
   {
      while(!FileIsEnding(filehandle))
      {
         FileReadStruct(filehandle,rfann);
         FileReadArray(filehandle,rdata_1);
         FileReadArray(filehandle,rdata_2);
         FileReadArray(filehandle,rdata_3);
         Print("++++++++++++++++++++++++++++++");
         Print("Структура");
         Print(rfann.v_main_up+"|"+rfann.v_main_dn+"|"+rfann.v_add_up+"|"+rfann.v_add_dn+"|"+rfann.answer);
         Print("Массивы");
         Print("--- 1");
         ArrayPrint(rdata_1);
         Print("--- 2");
         ArrayPrint(rdata_2);
         Print("--- 3");
         ArrayPrint(rdata_3);
      }
   }

它发出了大量的地狱...

Структура
4.0|-1.0|2.8|-0.7|1
Массивы
--- 1
 1.00000  0.33225 -0.76202 -0.93263 -1.00000 -0.79174
--- 2
-0.14603  0.89562  0.91407  0.93450  0.89481  0.89829
--- 3
 0.89564  0.89217 -0.91174 -0.86623 -1.00000 -0.07680
++++++++++++++++++++++++++++++
Структура
1.839259944929932 e+277|-nan|5.295254096666168 e-315|3.0|-618173028
Массивы
--- 1
 2.10000 -2.00000 -1.40000 -0.85098 -1.00000 -0.79900
--- 2
-0.30490  0.47926  1.00000  0.70827  0.84163  0.84134
--- 3
 0.83925  0.84173  0.84760  0.84678  0.80368 -0.00063
++++++++++++++++++++++++++++++
Структура
9.384173261527221 e-276|5.298850499315376 e-315|2.955277867691187 e+299|-9.638234784517503 e-243|-1705145188
Массивы
--- 1
+0.00000 +0.00000  4.00000  2.80000  0.00000  0.00000
--- 2
 1.00000  0.22097 -0.37383 -0.73115 -0.81752 -1.00000
--- 3
-0.87753  0.46919  0.59706  0.76223  0.82610  0.84312
++++++++++++++++++++++++++++++

所以我在想:怎么可能从一个文件中读取结构和三个数组,而你又不知道它是怎么写的。

这就是为什么我说我是自学成才的,知道的不多,但你不能部分地读懂它

我知道有一些选项可以把所有东西都加到.bin文件中,但要阅读它,你需要知道什么东西是按什么顺序写的。而且有可能不是通过mql的方式。

[删除]  

我完全不明白这一点......

      FileSeek(filehandle,0,FILE_END);
'FILE_END' - cannot convert enum                        282     31
'FILE_END' - improper enumerator cannot be used         282     31

它有什么问题?

 
Alexey Viktorov:

所以我在想:怎么可能从一个文件中读出一个结构和三个数组,而你又不知道它是怎么写的。

这就是我写的,它更容易检查,在10分钟内....检查了,FileWriteArray()没有在头或第一个字节中写入数组的大小,这意味着你应该自己写入这些值

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"

struct SMystruct
{
   double            d_arr[];
   int               i_arr[];
   uchar             c_arr[];
   int               a;
   double            b;
};

//+------------------------------------------------------------------+
void OnStart()
{
   SMystruct mstruct;
   ArrayResize(mstruct.d_arr,5);    ArrayInitialize(mstruct.d_arr,3.1415926);
   ArrayResize(mstruct.i_arr,3);    ArrayInitialize(mstruct.i_arr,1234567890);
   ArrayResize(mstruct.c_arr,7);    ArrayInitialize(mstruct.c_arr,127);
   mstruct.a = 666;
   mstruct.b = 123.123;
//---  
   if(!SaveMStructToFile("mfile.bin",mstruct)) return;
   SMystruct read_struct;
   if(!LoadMStructInFile("mfile.bin",read_struct)) return;
   Print("1. d_arr");
   ArrayPrint(read_struct.d_arr);
   Print("2. i_arr");
   ArrayPrint(read_struct.i_arr);
   Print("2. c_arr");
   ArrayPrint(read_struct.c_arr);
   printf("mstruct.a = %i , mstruct.b = %f",read_struct.a , read_struct.b);
   
}
//+------------------------------------------------------------------+
bool SaveMStructToFile(const string fname,const SMystruct &data)
{
   int h = FileOpen(fname,FILE_WRITE | FILE_BIN | FILE_COMMON);
   if(h<0) { Print("Write IO Err #",GetLastError()); return(false); }
   FileWriteInteger(h,ArraySize(data.d_arr));   FileWriteArray(h,data.d_arr);
   FileWriteInteger(h,ArraySize(data.i_arr));   FileWriteArray(h,data.i_arr);
   FileWriteInteger(h,ArraySize(data.c_arr));   FileWriteArray(h,data.c_arr);
   FileWriteInteger(h,data.a);
   FileWriteDouble(h,data.b);
   FileClose(h);  
   return(true);
}

bool LoadMStructInFile(const string fname,SMystruct &data)
{
   int h = FileOpen(fname,FILE_READ | FILE_BIN | FILE_COMMON);
   if(h<0) { Print("Write IO Err #",GetLastError()); return(false); } 
   int amount = ArrayResize(data.d_arr,(int)FileReadInteger(h));     FileReadArray(h,data.d_arr,0,amount);
       amount = ArrayResize(data.i_arr,(int)FileReadInteger(h));     FileReadArray(h,data.i_arr,0,amount);
       amount = ArrayResize(data.c_arr,(int)FileReadInteger(h));     FileReadArray(h,data.c_arr,0,amount);
   data.a = FileReadInteger(h);
   data.b = FileReadDouble(h);
   FileClose(h); 
   return(true);
}

2020.03.25 10:18:36.058 tst (EURUSD,H1) 1. d_arr

2020.03.25 10:18:36.058 tst (EURUSD,H1) 3.14159 3.14159 3.14159 3.14159

2020.03.25 10:18:36.058 tst (EURUSD,H1) 2. i_arr

2020.03.25 10:18:36.058 tst (EURUSD,H1) 1234567890 1234567890

2020.03.25 10:18:36.058 tst (EURUSD,H1) 2. c_arr

2020.03.25 10:18:36.058 tst (EURUSD,H1) 127 127 127 127 127 127

2020.03.25 10:18:36.058 tst (EURUSD,H1) mstruct.a = 666 , mstruct.b = 123.123000

也就是说,如果数组的尺寸是动态的,这意味着我们在写的时候写数组本身的尺寸,而在读的时候,我们从文件中读取数组尺寸的值并设置结构中数组的尺寸

在我的例子中,有两个结构--一个被初始化并写入,第二个被读取,从文件数据中初始化。