Автор | Сообщение |
|
| |
Пост N: 27
Зарегистрирован: 15.12.06
|
|
Отправлено: 09.02.07 14:50. Заголовок: Сохранение массивов в MEM-файле
Товарищи, кто подскажет - я помню, где-то видел, что в Харборе, в отличие от Клиппера, можно сохранять и массивы. А у меня почему-то не работает. (Используется Harbour Compiler (CVS 2007-01-17 13:50) Copyright 1999-2007, http://www.harbour-project.org/ Harbour MiniGUI Extended Distribution) Заранее благодарен.
|
|
|
Ответов - 22
, стр:
1
2
All
[только новые]
|
|
|
| постоянный участник
|
Пост N: 57
Зарегистрирован: 13.10.05
|
|
Отправлено: 11.02.07 10:34. Заголовок: Re:
В Клиппере массивы в текстовый файл можно сохранять и восстанавливать , с Мемо полями не пробовал
|
|
|
|
| постоянный участник
|
Пост N: 111
Зарегистрирован: 09.10.06
|
|
Отправлено: 11.02.07 18:35. Заголовок: Re:
AM пишет: цитата: | я помню, где-то видел, что в Харборе, в отличие от Клиппера, можно сохранять и массивы. А у меня почему-то не работает |
| Вместе с Harbour MiniGUI Extended Distribution распространяется (x)harbour.chm ( см. harbour\doc) Цитата: The SAVE command saves public and private memory variables visible within the current procedure or user-defined function to a memory file. The arrays and local and static variables can not be saved to a file. Vlad04 пишет: цитата: | В Клиппере массивы в текстовый файл можно сохранять и восстанавливать |
| Это реализуется с использованием пользовательской функции. Так можно поступать и в [x]Harbour. Если не хочется писать самому. можно поискать на http://www.the-oasis.net
|
|
|
|
| |
Пост N: 28
Зарегистрирован: 15.12.06
|
|
Отправлено: 12.02.07 12:18. Заголовок: Re:
Жаль, но где-то я что-то такое видел. Наверно, перепутал с Аляской.
|
|
|
|
| |
Пост N: 107
Зарегистрирован: 06.06.06
|
|
Отправлено: 13.02.07 11:44. Заголовок: Re:
|
|
|
|
| |
Пост N: 29
Зарегистрирован: 15.12.06
|
|
Отправлено: 13.02.07 16:52. Заголовок: Re:
Чего-то я по указанным ссылкам не нашёл, вот сам написал: function saveArr(el) //преобразование массива в строку (для SAVE) local i,res:='' DO CASE CASE VALTYPE(el)='N' res+='N'+str_t(el) CASE VALTYPE(el)='L' res+='L'+IF(el,'T','F') CASE VALTYPE(el)='C' res+='C'+str_t(len(el))+':'+el CASE VALTYPE(el)='D' res+='D'+DTOS(el) CASE VALTYPE(el)='U' res+='U' CASE VALTYPE(el)='A' res+='A'+str_t(len(el))+':' for i=1 to len(el) res+=saveArr(el)+if(i=len(el),'',',') next OTHERWISE res+='U' //msay('Недопустимый тип') ENDCASE return res function restArr() //преобразование строки в массив (после RESTORE) parameters r private cur_ind:=1 return add_el() static func add_el() memvar r,cur_ind local data_type:=substr(r,cur_ind++,1) local ret,l,i do case case data_type='A' l=val(substr(r,cur_ind)) do while substr(r,cur_ind++,1)#':' enddo ret={} for i=1 to l aadd(ret,add_el()) next l if l=0 cur_ind++ endif case data_type='C' l=val(substr(r,cur_ind)) do while substr(r,cur_ind++,1)#':' enddo ret=substr(r,cur_ind,l) cur_ind+=l+1 case data_type='N' ret=val(substr(r,cur_ind)) do while substr(r,cur_ind++,1)#','.and.cur_ind<len(r) enddo case data_type='D' ret=STOD(substr(r,cur_ind,8)) cur_ind+=9 case data_type='L' ret=(substr(r,cur_ind,1)='T') cur_ind+=2 case data_type='U' cur_ind++ ret=nil endcase return ret Вроде в первом приближении работает.
|
|
|
|
| постоянный участник
|
Пост N: 282
Зарегистрирован: 17.05.05
|
|
Отправлено: 13.02.07 18:21. Заголовок: Re:
Коллега, позвольте высказать свои критические замечания. Вместо VALTYPE( el ) = 'N' // 'C', 'L' etc. я предпочитаю известные макросы ISNUMBER( el ) ISCHARACTER( el ) ISLOGICAL( el ) или ISNIL( el ) то есть код выглядел бы так DO CASE CASE ISNUMBER( el ) ... CASE ISCHARACTER( el ) ... CASE ISLOGICAL( el ) На мой взгляд такой текст выглядет более привлекательным. Не понятно назначение функции restArr(). Она введена только для того, чтобы объявить две PRIVATE переменные r и cur_ind? Зачем это делается? В программе не должно быть НИ одной PRIVATE переменной. Наличие PRIVATE переменной говорит о том, что код неудачно спроектирован. Да, чтобы не получить GPF, не забудьте проверять, чтобы суммарная длина строки не превосходила максимального значения длины для строк в Clipper.
|
|
|
|
| |
Пост N: 33
Зарегистрирован: 27.04.06
|
|
Отправлено: 13.02.07 20:03. Заголовок: Re:
А я думал здесь форум [x]Harbour... заблудился
|
|
|
|
| постоянный участник
|
Пост N: 58
Зарегистрирован: 13.10.05
|
|
Отправлено: 14.02.07 09:45. Заголовок: Re:
Вот нормальные функции для записи и чтения многомерных массивов в текстовые файлы. Нашел в толстой книге много лет назад. /*** Запись и сохранение в текстовом файле МАССИВА ***/ func Asave(NameF,Mas) Private N:=FCreate(Namef) if(N #-1,(_save(Mas),Fclose(n)),) Return N#-1 *** Static Proc _Save(Mas,Alen,tip,i,M) Alen=Len(Mas) FWrite(N,"A"+str(Alen,4)) For i:=1 TO Alen M=Mas;tip=Valtype(M) tip+=Iif(tip="N",(M:=Ltrim(Str(M)),Str(Len(M),2)+M),; Iif(tip="C",Str(Len(M),4) +M,Iif(tip="D",dtoc(M),; Iif(tip="L",Iif(M,"T","F"),"")))) Iif(tip="A",_Save(M),Iif(tip#"B",Fwrite(N,tip),)) NEXT *** FUNC Arest (NameF,Ret) Private N:=Fopen(Namef) if(N #-1,(Fseek(N,1),Ret:=_Rest(),Fclose(N)),Ret:=NIL) Return Ret *** Static Func _Rest(Alen,tip,i,M) Alen =Val(Freadstr(N,4)); M= Array(Alen) For i:=1 TO Alen tip = Freadstr(N,1) M =Iif(tip ="A",_Rest(),; Iif(tip="C",Freadstr(N,Val(Freadstr(N,4))),; Iif(tip="N",Val(Freadstr(N,Val(Freadstr(N,2)))),; Iif(tip="D",CTOD(Freadstr(N,8)),; Iif(tip="L",Freadstr(N,1)="T",NIL ))))) Next return M Все работает и на Клиппере и на Харборе. Ну, а в Мемо записать - еще пару операций добавить.
|
|
|
|
| |
Пост N: 636
Зарегистрирован: 17.05.05
|
|
Отправлено: 14.02.07 09:54. Заголовок: Re:
Vlad04 пишет: цитата: | Нашел в толстой книге много лет назад |
| а что это за книга ?
|
|
|
|
| |
Пост N: 30
Зарегистрирован: 15.12.06
|
|
Отправлено: 14.02.07 10:31. Заголовок: Re:
Григорьев Владимир пишет: цитата: | я предпочитаю известные макросы ISNUMBER( el ) ISCHARACTER( el ) ISLOGICAL( el ) или ISNIL( el ) |
| Я их не знал. Григорьев Владимир пишет: цитата: | Не понятно назначение функции restArr(). |
| Для многомерных массивов нужны рекурсивные вызовы, а переменные должны быть одни и те же во всех вызовах. Наверно, можно и как-то иначе, но, главное - работает. ( str_t() - это trim(str()) ) Григорьев Владимир пишет: цитата: | В программе не должно быть НИ одной PRIVATE переменной. Наличие PRIVATE переменной говорит о том, что код неудачно спроектирован. |
| Зачем отказываться от использования возможностей языка? Когда-то я писал на Клиппере и мне было велено обойтись без PUBLIC и PRIVATE переменных. Для процедур, вызываемых асинхронно (по клавишам), при таком ограничении приходилось "вставать на уши". Отмена этого ограничения сделала программирование лёгким и приятным. Григорьев Владимир пишет: цитата: | не забудьте проверять, чтобы суммарная длина строки не превосходила максимального значения длины для строк в Clipper |
| В Харборе же вроде такое ограничение снято. Vlad04 пишет: цитата: | нормальные функции для записи и чтения многомерных массивов в текстовые файлы. |
| В общем, примерно как у меня, только пишет в файл. Но в отдельный файл как раз не очень надо, лучше всё вместе в один стандартный .MEM, формат которого можно и не знать.
|
|
|
|
| постоянный участник
|
Пост N: 283
Зарегистрирован: 17.05.05
|
|
Отправлено: 14.02.07 12:30. Заголовок: Re:
AM пишет: цитата: | Для многомерных массивов нужны рекурсивные вызовы, а переменные должны быть одни и те же во всех вызовах. Наверно, можно и как-то иначе, но, главное - работает. |
| Вы можете легко обойтись без PRIVATE переменных и без дополнительного уровня в виде функции просто вызывая add_el() с параметрами. Например, если add_el() вызывается без параметров, то вы внутри нее сами устанавливаете начальные значения. В остальных случаях эта функция использует значения из параметров. Можно также использовать механизм STATIC переменных, объявленных внутри самой функции. Я уже давно убедился, что на самом деле важно не то, чтобы "работало", а то, чтобы "правильно" было написано. Тогда "работало" будет простым следствием. А правильно писать - это 1) чтобы код был читабелен любому программисту, который даже не знает Clipper (а это значит, например, не использовать сокращения команд до 4 знаков, как это многие обычно делают в Clipper); 2) не использовать конструкции языка, которые имеют побочные эффекты и чреваты возникновением потенциальных ошибок и трудно сопровождаемые.
|
|
|
|
|
| |
Пост N: 31
Зарегистрирован: 15.12.06
|
|
Отправлено: 14.02.07 14:08. Заголовок: Re:
Да, возможно, вы правы. Но, как правило, более читабелен более короткий код (я не имею в виду сокращения). Да и для разных людей более читабельно разное, а слишком узкие рамки губительны для творчества - я имею в виду не бедность средств, а необходимость мыслить в определённом ключе. Из-за этого я совершенно не смог работать с 1С, хотя меня сначала сами позвали по старой памяти.
|
|
|
|
| |
Пост N: 108
Зарегистрирован: 06.06.06
|
|
Отправлено: 14.02.07 19:07. Заголовок: Re:
Dima пишет: цитата: | Vlad04 пишет: цитата: Нашел в толстой книге много лет назад а что это за книга ? |
| Может быть, это книга Рика Спенса? Вот здесь есть много примеров из этой книги, в том числе и по сохранению массивов: http://ort.ho.com.ua/spense.exe
|
|
|
|
| |
Пост N: 7
Зарегистрирован: 19.12.06
|
|
Отправлено: 15.02.07 12:05. Заголовок: Re:
А кто знает - как обойти проблему - программа на клиппере сохраняет массив в мемо файле. Та же программа на harbour этот массив при чтении видит как строку. Драйвер баз данных ADS, копался в исходниках - похоже не умеет ADS в harbour читать / писать массивы в мемо файл . Где бы взять хотя-бы формат в котором эти массивы записываются ?
|
|
|
|
| постоянный участник
|
Пост N: 284
Зарегистрирован: 17.05.05
|
|
Отправлено: 15.02.07 15:58. Заголовок: Re:
k_dima пишет: цитата: | Где бы взять хотя-бы формат в котором эти массивы записываются ? |
| Я думаю, это можно взять в той программе на Clipper, которая их записывает. Или самому по строке, которая считывается из MEMO поля, определить формат.
|
|
|
|
| |
Пост N: 8
Зарегистрирован: 19.12.06
|
|
Отправлено: 15.02.07 17:02. Заголовок: Re:
хороший совет - только строка то бинарная - то есть имеется заголовок - наверное длина массива и имеются разделители элементов массива - то же в двоичном виде и вот это как раз расшифровать не удается нужно знать формат, так, чтобы иметь возможность и читать и писать массивы в мемо поле. Причем глюки идут только с драйвером ADS, harbour DBFCDX отрабатывает нормально и возвращает при чтении из мемо поля массив. Попробовал покопаться в исходниках dbfcdx, но силенок не хватает
|
|
|
|
| постоянный участник
|
Пост N: 59
Зарегистрирован: 13.10.05
|
|
Отправлено: 16.02.07 10:29. Заголовок: Re:
А поподробнее нельзя, что делает ADS с массивом ? А книга(см.выше) назавалась "CLIPPER & FOXPRO Практикум программирования". Автор Зубов
|
|
|
|
| |
Пост N: 32
Зарегистрирован: 15.12.06
|
|
Отправлено: 16.02.07 11:37. Заголовок: Re: - новое!
k_dima пишет: цитата: | то же в двоичном виде и вот это как раз расшифровать не удается нужно знать формат |
| Чтобы расшифровать двоичный файл, рекомендую посмотреть, чем отличаются результаты при небольших изменениях данных (для поиска отличий можно использовать FC /B ). Для последующего анализа удобно распечатать нужные куски в HEX-формате (чтоб можно было на них черкать). Если не было специально сделано, чтобы затруднить расшифровку, то должно получиться, хотя более сложные случаи могут вылезти потом.
|
|
|
|
| |
Пост N: 9
Зарегистрирован: 19.12.06
|
|
Отправлено: 16.02.07 15:04. Заголовок: Re:
Подробнее -имеется база данных и мемо файл в который программа на клиппере + ADS в мемо поле пишет массивы - при переводе этой программы на xharbour , драйвер DBFCDX корректно возвращает тип поля "A" и корректно восстанавливает массив, даже если он многомерный, драйвер ADS для harbour возвращает тип данных "C", бинарную строку , и если массив многомерный то выдрать из этой строки многомерный массив не представляется возможным. В исходниках DBFCDX явно видно что мемо поля могут иметь тип HB_IT_ARRAY, в исходниках RDDADS при обработке мемо полей массивы не обрабатываются вообще - все сводится к обработке типа ADS_VARCHAR, ADS_BINARY, ADS_IMAGE. В общем придется отказываться от массивов в мемо - полях - от ADS отказаться не могу. а разбираться в двоичных строках методом тыка времени нет. > А поподробнее нельзя, что делает ADS с массивом ?
|
|
|
|
| постоянный участник
|
Пост N: 112
Зарегистрирован: 09.10.06
|
|
Отправлено: 16.02.07 20:19. Заголовок: Re:
k_dima пишет: цитата: | В исходниках DBFCDX явно видно что мемо поля могут иметь тип HB_IT_ARRAY |
| Где именно ? (файл, строка)
|
|
|
Ответов - 22
, стр:
1
2
All
[только новые]
|
|