НЕ работает! динамический многомерный строковый массив и файл? что происходит? Oo

Pavel Kolchin  

создаю динамический многомерный строковый массив например [5][3] (15 элементов) записываю его в файл

читаю из файла (15 элементов) - смотрю массив, там 39 элементов, что я делаю не так?

   int t_h;
   int n1,n2;
   
   int p1=5,p2=3;

   string arr_1[][3];
   string arr_2[][3];
   
   ArrayResize(arr_1,p1,100);
   for(int i=0;i<p1;i++){
      for(int k=0;k<p2;k++){
         arr_1[i][k]="str("+i+"|"+k+")";
      }
   }
   
   t_h=FileOpen("test\\0000.txt",FILE_WRITE|FILE_TXT);
   if(t_h!=INVALID_HANDLE){n1=FileWriteArray(t_h,arr_1);FileClose(t_h);}
   
   t_h=FileOpen("test\\0000.txt",FILE_READ|FILE_TXT);
   if(t_h!=INVALID_HANDLE){n2=FileReadArray(t_h,arr_2);FileClose(t_h);}
     
   Print("n1="+n1+"    n2="+n2);                                  //    n1=15    n2=15
   Print("ArraySize = "+ArraySize(arr_1)+" = "+ArraySize(arr_2)); //    ArraySize = 15 = 39
   
   ArrayPrint(arr_1);
   /*
               [,0]       [,1]       [,2]
   [ 0,] "str(0|0)" "str(0|1)" "str(0|2)"
   [ 1,] "str(1|0)" "str(1|1)" "str(1|2)"
   [ 2,] "str(2|0)" "str(2|1)" "str(2|2)"
   [ 3,] "str(3|0)" "str(3|1)" "str(3|2)"
   [ 4,] "str(4|0)" "str(4|1)" "str(4|2)"
   */

   ArrayPrint(arr_2);
   /*
               [,0]       [,1]       [,2]
   [ 0,] "str(0|0)" "str(0|1)" "str(0|2)"
   [ 1,] "str(1|0)" "str(1|1)" "str(1|2)"
   [ 2,] "str(2|0)" "str(2|1)" "str(2|2)"
   [ 3,] "str(3|0)" "str(3|1)" "str(3|2)"
   [ 4,] "str(4|0)" "str(4|1)" "str(4|2)"
   [ 5,] null       null       null      
   [ 6,] null       null       null      
   [ 7,] null       null       null      
   [ 8,] null       null       null      
   [ 9,] null       null       null      
   [10,] null       null       null      
   [11,] null       null       null     
   [12,] null       null       null     
   */
Alexey Viktorov  

FILE_READ

1

Файл открывается для чтения. Флаг используется при открытии файлов (FileOpen()). При открытии файла обязательно должен быть указан флаг FILE_WRITE и/или флаг FILE_READ

FILE_WRITE

2

Файл открывается для записи. Флаг используется при открытии файлов (FileOpen()). При открытии файла обязательно должен быть указан флаг FILE_WRITE и/или флаг FILE_READ

FILE_BIN

4

Двоичный режим чтения-записи (без преобразования из строки и в строку). Флаг используется при открытии файлов (FileOpen())

FILE_CSV

8

Файл типа csv (все записанные элементы преобразуются к строкам соответствующего типа, unicode или ansi, и разделяются разделителем). Флаг используется при открытии файлов (FileOpen())

FILE_TXT

16

Простой текстовый файл (тот же csv, однако разделитель не принимается во внимание). Флаг используется при открытии файлов (FileOpen())

FILE_ANSI

32

Строки типа ANSI (однобайтовые символы). Флаг используется при открытии файлов (FileOpen())

FILE_UNICODE

64

Строки типа UNICODE (двухбайтовые символы). Флаг используется при открытии файлов (FileOpen())

FILE_SHARE_READ

128

Совместный доступ по чтению со стороны нескольких программ. Флаг используется при открытии файлов (FileOpen()), но не заменяет при открытии файла необходимости указать FILE_WRITE и/или флаг FILE_READ

FILE_SHARE_WRITE

256

Совместный доступ по записи со стороны нескольких программ. Флаг используется при открытии файлов (FileOpen()), но не заменяет при открытии файла необходимости указать FILE_WRITE и/или флаг FILE_READ

FILE_REWRITE

512

Возможность перезаписывания файла функциями FileCopy() и FileMove(). Файл должен существовать или открываться для записи. В противном случае файл открыт не будет

FILE_COMMON

4096

Расположение файла в общей папке всех клиентских терминалов \Terminal\Common\Files. Флаг используется при открытии файлов (FileOpen()), копировании файлов (FileCopy(), FileMove()) и проверке существования файлов (FileIsExist())


После устранения этой ошибки можно будет думать дальше.

Pavel Kolchin  
Alexey Viktorov:

написал FILE_READ — абсолютно ничего не изменилось

   t_h=FileOpen("FastCopy\\0000_.txt",FILE_READ|FILE_TXT);
   if(t_h!=INVALID_HANDLE){n2=FileReadArray(t_h,arr_2);FileClose(t_h);}
Alexey Viktorov  

Цитата из документации

FileWriteArray

Записывает в файл типа BIN массивы любых типов, кроме строковых (может быть массив структур, не содержащих строки и динамические массивы).


Я-бы не стал экспериментировать с файлами .txt
Alexey Viktorov  

Согласен. Не всегда читаю документацию до последней буквы. Точней сказать крайне редко дочитываю до конца.

Может резерв массива даёт такой эффект?

ArrayResize(arr_1,p1,100);
Pavel Kolchin  
Alexey Viktorov:

Может резерв массива даёт такой эффект?

это массив из которого записывается в файл(проверил ничего не меняется), в данном примере функция FileWriteArray показывает что записано в фаил 15 элементов , функция FileReadArray показывает что считано из файла 15 элементов, это значит(скорее всего) что там внутри что то работает не правильно, раз массив создается не верной величины, [13][3] = 39 вместо [5][3] = 15

вот файл


Konstantin Nikitin  
FileWriteArray

Записывает в файл типа BIN массивы любых типов, кроме строковых (может быть массив структур, не содержащих строки и динамические массивы).

FileReadArray

Читает массивы любых типов, кроме строковых (может быть массив структур, не содержащих строки и динамические массивы), из бинарного файла с текущего положения файлового указателя.


Для многомерных может правильней использовать ArrayRange

Pavel Kolchin  
Konstantin Nikitin:

FileWriteArray

Записывает в файл типа BIN массивы любых типов, кроме строковых (может быть массив структур, не содержащих строки и динамические массивы).

Примечание Строковый массив может записываться только в файл типа TXT.

FileReadArray

Читает массивы любых типов, кроме строковых (может быть массив структур, не содержащих строки и динамические массивы), из бинарного файла с текущего положения файлового указателя.

Примечание Строковый массив может читаться только из файла типа TXT.


Для многомерных может правильней использовать ArrayRange

куда и как его воткнуть? и зачем?

Alexey Viktorov  
Pavel Kolchin:

это массив из которого записывается в файл(проверил ничего не меняется), в данном примере функция FileWriteArray показывает что записано в фаил 15 элементов , функция FileReadArray показывает что считано из файла 15 элементов, это значит(скорее всего) что там внутри что то работает не правильно, раз массив создается не верной величины, [13][3] = 39 вместо [5][3] = 15

вот файл


Если нужно просто обойти проблему, то можно ещё перед чтением файла изменить размер массива. И ещё попробовать явно указать количество читаемых элементов.

uint  FileReadArray( 
   int    file_handle,               // handle файла 
   void&  array[],                   // массив для записи 
   int    start=0,                   // стартовая позиция для записи в массив 
   int    count=WHOLE_ARRAY          // сколько читать 
   );

Если-же разобраться в проблеме, то писать в СД. Проблема не только в этом случае. Ещё есть проблема размера записанных и читаемых данных типа double не всегда составляет 8 байт если данные писались в .csv или .txt файл. А если писать в .bin то всё чётко совпадает и можно смело перемещать курсор на нужную строку.

Причина обращения: