Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2002.12.16;
Скачать: [xml.tar.bz2];

Вниз

Компоненты ADO в сервисе Win32   Найти похожие ветки 

 
iZEN   (2002-11-27 13:07) [40]

Было: AllNames: TStringList;
Стало: AllNames: array of String;


 
BlackTiger   (2002-11-27 13:09) [41]

Что-то странное в компонентах VCL все-таки есть. И это не глюки программиста. Я подозреваю, что Делфа проводит какую-то НЕЯВНУЮ инициализацию чего-то внутри и этой инициализации не происходит в таких специфичных приложениях как консольные и сервисы. При этом хелпы просто умалчивают про это (впрочем много о чем еще).
В книгах про ТАКИЕ вещи тоже не пишут, так как авторы зачастую сами ничего в этом не понимают. Ответ знают только борландовцы и люди, которые сами бились (и успешно!) с такими проблемами. Подход, который подходит (калабурчик-с) для разработки стандартных (оконных) приложений, абсолютно не применим при создании сервисов и консолей - тут надо копать глубже, но не всегда понятно в какую сторону.
Вот! Мое личное мнение.


 
Zelius   (2002-11-27 14:15) [42]

А у тебя не выскакивает ошибка типа "List index out of bounds" ?
Судя по коду, у тебя есть несколько потенциальных мест для возникновения ошибок.


 
iZEN   (2002-11-27 14:45) [43]

/**Zelius © (27.11.02 14:15)
А у тебя не выскакивает ошибка типа "List index out of bounds" ?
*/
Нет. Всё глухо. Отладчик не жалуется...


 
iZEN   (2002-11-27 14:51) [44]

Этот конструктор использует локальную функцию, которая читает файл в буфер. Представляет его как байтовый поток (Stream), из которого берутся строки длиной 20 символов (константа lenName = 20;).
Переполнения никакого быть не может: изначально вычисляется и устанавливается длина массива с "хвостиком" ( SetLength(AllNames, mis.Size div lenName + lenName);).
Это решает проблему выхода за границы массива.
Переменная j служит для подсчёта "полноценных" строк.


 
Zelius   (2002-11-27 14:58) [45]

Такой вопрос, тебе удалось полноценно пройтись отладчиком по этому коду? То есть я хочу сказать, что есть шанс, что какое-то исключение ты просто не увидел, иногда отладчик сразу убегает в другой кусок кода. Например, в первом варианте кода, ты забывал передать в AllNames тот кусок строки, который был последним в файле и не был кратным 20! Однако j у тебя указывал на то что она есть и при присвоенни в Names это последней строки вылезал эксепшн! Этот кусок кода я смоделировал у себя.


 
iZEN   (2002-11-27 15:09) [46]

Вы имеете ввиду строчку SetLength(Names, j+1);?
Здесь происходит задание длины массива на 2 элемента больше (! т.к. j увеличивается 2 раза: после Inc(j); и в этом месте).
Хотя действительно можно обойтись SetLength(Names, j-1); - по длине массива AllNames.
Или даже так:
SetLength(Names, High(AllNames) - Low(AllNames) + 1);
(Кстати, спасибо за намёк на уловку:), лишние два элемента массива надо бы исключить)
В любом случае, выход за границы не происходит, но количество элементов, естественно, выходит больше чем есть. "Лишние" элементы пустые. Я по шагам всё проверил.


 
Zelius   (2002-11-27 15:21) [47]

Попробуй, пожалуйста, такой код, в нем я постарался исключть по максимуму возможные подводные камни, хотя один там еще остался:

constructor TTSArchiv.Create(const NamesFileName, ValuesFileName: TFileName);
procedure FillNames();
//Запонение массива Именами ТС
var fis: TFileStream;
k: Integer;
s: AnsiString;
c: Byte;
AllNames: TStringList;
begin
fis := nil;
AllNames := nil;
try
fis := TFileStream.Create(NamesFileName, fmOpenRead or fmShareDenyNone);
AllNames := TStringList.Create();
fis.Position := 0;
while fis.Position < fis.Size do
begin
fis.Read( c, 1);
Inc(k);
if (c >= 32) then s := s + ANSI(c);
if (k = 20) and (s <> "") then
begin
AllNames.Add(s);
s := "";
k := 0;
end;
end;
if s <> "" then AllNames.Add(s);
SetLength( Names, AllNames.Count);
for i := 0 to AllNames.Count-1 do
Names[i] := AllNames[i];
finally
FreeAndNil(AllNames);
FreeAndNil(fis);
end;
end;
begin
inherited Create();
FillNames();
end;



 
iZEN   (2002-11-27 15:24) [48]

Вот так вернее (ошибся насчёт "задание длины массива на 2 элемента больше"):

...
finally
if (Assigned(AllNames)) then begin
SetLength(Names, j);
for i := Low(Names) to High(Names) do
Names[i] := AllNames[i];
...

Массив AllNames имеет длину, превышающую число значимых строк (j - счётчик строк).


 
iZEN   (2002-11-27 15:34) [49]

Для Zelius © (27.11.02 15:21).

Спасибо за код.
НО!
В консольном приложении: строчка s не заносится в AllNames.Add(s);. ХОТЬ ТРЕСНИ!!!
Под отладчиком в окне "Локальные переменные" видим:

...
AllNames: ();

НИЧЕГО НЕТ!
Хотя AllNames <> nil;


 
iZEN   (2002-11-27 15:38) [50]

Вот такие чудеса...однако.


 
iZEN   (2002-11-27 15:46) [51]

Дополнение к iZEN © (27.11.02 15:34).
s имеет допустимое значение на всех стадиях функции.


 
Zelius   (2002-11-27 15:50) [52]

Остается только одно, по Станиславскому - НЕ ВЕРЮ :))
Попробуй вставь в код дополнительные переменные простого типа и присвой их в интересующих тебя местах, типа после заполнения массива перед SetLength( Names, AllNames.Count); поставь k := AllNames.Count и s := Allnames.CommaText и помотри, что они буду значить...


 
Zelius   (2002-11-27 15:51) [53]

Должен заявить, что данный когд не имеет никакого отношения к консольности!!! Если что-то не работает, то надо искать причину в другом...


 
iZEN   (2002-11-27 15:55) [54]

Дополнение к iZEN © (27.11.02 15:34).
s имеет допустимое значение на всех стадиях функции.


 
iZEN   (2002-11-27 16:11) [55]

На Zelius © (27.11.02 15:50).

И это пробовал. Думаете я первый раз попадаю в "передряги"?
Непонятно одно: почему AllNames.Add(s); не отрабатывает, даже исключений нет.
Странно. Весма странно.

На Zelius © (27.11.02 15:51).
/**Должен заявить, что данный когд не имеет никакого отношения к консольности!!! Если что-то не работает, то надо искать причину в другом...*/

А к чему он имеет значение? В оконном прил. работает, в консольном не работает? Есть идеи?


 
iZEN   (2002-11-27 16:14) [56]

Попробовал бы я так в Java поставить вопрос - меня бы на смех подняли.
Ну нет там таких заморочек! Всё прозрачно, если используешь стандартные библиотечные объекты (да и свои тоже).


 
Zelius   (2002-11-27 17:04) [57]

а ты ставил на AllNames.Add(s) брякпойнт? Ты заходил в дебагере внутрь этого метода? если нет, то попробуй... и поставь брякпойнт в секции finally! Если код сразу перейдет туда, значит был эксепшн... Мне кажется, что возможное объяснение происходящего это эксепшн при открытии файла... Больше мыслей нет... Все должно работать...


 
iZEN   (2002-11-28 08:07) [58]

Для Zelius © (27.11.02 17:04).

Ну естественно, я же уже не мальчик.
В секцию finally переход осуществляется только после прочтения всего файла и "якобы-занесения" всех строк в AllNames.Add(s). То есть всё происходит без исключений и всё читается (это я вижу при пошаговой отладке), но AllNames оказывается пустым всегда, даже не nil!

Предположение: в Delphi в конструкторе объектов исключения не могут выбрасываться до завершения конструирования (проглатываются? тихие исключения?).

Вы-то сами можете попробовать: обычный текстовый файл, в котором число символов кратно 20. Есть собственная функция ANSI() (очень простая), переводящая чимвол кодировки DOS866 в WIN1251, но она Вам не нужна для эксперимента.

P.S. Задача вообще-то решена с использованием дин.массива. Так что проехали?


 
ЮЮ   (2002-11-28 09:09) [59]

>Под отладчиком в окне "Локальные переменные" видим:
AllNames: ();
НИЧЕГО НЕТ!
Хотя AllNames <> nil;

А AllNames[0], AllNames[AllNames.Count - 1] ??
Это у динамического массива в отладчике видно (("1")("2")), а StringList так не посмотришь



Страницы: 1 2 вся ветка

Форум: "Базы";
Текущий архив: 2002.12.16;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.007 c
14-51947
eugene_t
2002-11-26 08:05
2002.12.16
Аудио


1-51753
kingdom
2002-12-04 12:39
2002.12.16
Очень нужен LanManager.zip!!


14-51932
?????
2002-11-24 21:37
2002.12.16
<a href=


4-52017
cecist
2002-11-04 16:03
2002.12.16
праграммный ввод пароле в Windows2000


3-51561
Сергей Ч
2002-11-28 10:23
2002.12.16
Вывод данных на печать или в Excel из DecisionGrid





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский