Скачал, глянул исходник... Ну что я могу сказать... Реально жрёт всю доступную память... Сейчас объясню, почему, и как бороться.
Code
s:=mmo1.Text; //Текст для шифровки i:=Length(s); //Длина этого текста pass:=edt1.Text; //Ключевое слово - пароль j:=Length(pass); //Длина пароля h:=Round(i/j); //Делим длину текста на длину пароля for b:=1 to h do pass:=pass+pass; //Складываем наш пароль h раз
Теперь предположим следующее: мы ввели 100 символов для зашифровки (не важно, какие) и пароль в один символ (например, "ы"). Получаем h=100. Далее получается следующее: после первого входа в цикл - наш пароль в переменной pass равен "ыы"
...и так ещё 93 раза. Теперь понятно? То есть, чтобы сэкономить память, нам нужно вводить относительно - текст короче и пароль длиннее... Вот, поставил эксперимент, используя твою первую версию программы. Короче... 2003 символа осмысленного текста, и довольно длинный пароль в 140 символов. Конечно, шифровалось довольно долго, но результат был получен без ошибок - 2035 символов. Я не подбирал конкретные числа, просто взял кучку анекдотов, а пароль сходу придумал. А вот чтобы ошибка не появлялась... Тут можно либо отлавливать ошибку по ходу, либо вычислять вероятность её появления, исходя из памяти компьютера, длины текста и длины пароля. Проще всего - уже во время шифровки, но с точки зрения пользователя - это неудобно, ведь программа работает впустую. Вот вариант, как отловить ошибку во время выполнения:
Code
try //Блок "Попытаться сделать..." //Тут находится весь код TForm1.btn1Click, т.е. try идёт сразу после первого begin, хотя можно более локально организовать, но это надо искать проблемный участок except //Ошибка? //Тут можно написать on E:Класс_Ошибки do ... чтобы можно было бы получить дополнительную информацию об ошибке, но это сейчас нам не нужно... messagedlg('Не хватает памяти! Введите более длинный пароль или сократите шифруемый текст.',mtError,[mbOk],0); //Покажем сообщение end; //Этот end идёт перед end'ом процедуры
Тогда выведется наше сообщение об ошибке и всё, больше ничего. В принципе, можно обрабатывать эту ошибку не простым выводом сообщения о ней, но и, например, применением другого алгоритма шифрования. Или увеличением пароля дополнительными случайными буквами, с извещением пользователя об этом и перезапуском процедуры шифрования. Кстати, это сообщение генерируется не только циклом for, но и чем-то другим (далее по коду), но мне лень искать.
P.S. Вообще ты не очень хорошо всё сделал. Например, использовал две вкладки с абсолютно одинаковыми компонентами. Это лишняя нагрузка. Можно оформить всё проще и рациональнее в несколько раз. Также, обнуление данных в форме можно делать процедурой TMemo.Clear. И ещё: старайся делать отступы в, например, два пробела в коде, там где нужно - это повышает читабельность кода; ещё не забывай писать комментарии, чтобы не забыть, как и что тут работает; то же касается названий компонентов - их нужно называть по смыслу, например: usertext, password, textresult (поля ввода), analyse (кнопка) или start...
*** Вот, на всякий случай держи свой код. Это твой немного переделанный первый исходник. Только, чтобы увидеть моё сообщение, запускай не из Delphi, а прямо из Windows. Т.е. скомпилируй, найди *.exe и запускай. Я там "Нехватает" написал слитно... Не заметил сразу, а теперь лень перезаливать эти три с половиной килобайт...
*** Вообще непонятно, как такая простая ошибка может вызывать проблемы... Выучи сначала Паскаль, прежде чем браться за примеры из видеоуроков... А то ты ведь даже не понял, как это работает, хотя принцип прост, потому и обратился на форум за помощью...
Сообщение отредактировал TimKruz - Среда, 25 Января 2012, 17:56
Ну так я тебе и написал, как это сделать. Это не ошибка, а "исключение"...
Quote (kvestpro)
на видеоуроке человек пишет огромный текст и пароль "код!!!" и все работает
Эээ... Либо ты что-то не так напечатал (ну, ошибся где-то), либо у автора урока очень мощный компьютер. Попробуй посмотреть урок ещё раз, и проверь код.
Нет, писал же поправил. Запусти посмотри, еррора нет - шифрует коректно. Если не заметил что, вот:
Code
j:=Length(pass);<<-- j1:=1;<<-- for b:=1 to i do Begin if j1>j then j1:=1;<<-- if (ord(s[b])+ord(pass[j1]))>255 then mmo2.text:=mmo2.text+chr(ord(s[b])+ord(pass[j1])-255) else mmo2.text:=mmo2.text+chr(ord(s[b])+ord(pass[j1])) ; Inc(j1);<<-- end;
Рабочий исходник з пофиксиной траблой кинул еще в посте №19, но топик стартер проигнорил.