Значит так. Мне нужно написать следующую программу: небольшая формочка с тремя полями Memo, полем Label и двумя Батонами. Суть программы: есть 100 экз. билетов, в каждом из них по 3 вопроса. По нажатию на кнопку нужно вывести - в Label номер билета, в поля Memo вопросы из него. В программе, естественно использ. Random для выбора билета. Проблема моя в том, что я не знаю, как записать вопросы и билеты. Решил забить их в текстовый файл. В каждую строку по одному вопросу (то есть билет №1 - строки 1,2,3; билет №2 - строки 4,5,6) но как мне считать строки с определенными номерами и вывести их? Али может в какую-нить БД это все впендюрить? Правда ни разу не пользовал
AlienEmperor
16.06.2005 10:48
Как вариант: берешь поток, приделываешь вначале Header в котором содержится вся инфа (кол-во записей + массив размеров каждой записи) пишешь через Memo.Lines.SaveToStream (вроде так, посмотри сам) и все... Считываешь след. образом: выбираешь (случайно) запись, считываешь все размеры ДО нее, пропускаешь их в файле, читаешь нужную...
P.S. Еще вариант: сделать через типизированный файл (к примеру, 1000 байт на текст + номер билета) ==> скучно и не эффективно...
Jaxx
16.06.2005 12:01
Я тут другую систему придумал. Дело в том, что мне нужно все сделать максимально просто. Берем текстовый файл, пишем в него вопросы следующим образом:
Код
1Бла-бла-бла.... 1Снова бла-бла 1И еще раз бла 2Второй билет пошел 2В нем тоже бла-бла 2Но суть не в этом ... 100Бла-Бла 100Предпоследний Бла 100Бла-последний
Потом Random генерит любое число до 100, считываем из файла строки, и если в начале записано число равное сгенерированному, то выводим его в Memo. Ну как я?
AlienEmperor
16.06.2005 12:05
Тоже вариант... Простая разметка, тока вот что будет, если в билете 3 строки, а рэндом указал на 2-ую ? Или ты в любом случае весь файл сразу в память будешь читать ?
volvo
16.06.2005 12:07
Цитата(Jaxx @ 16.06.05 12:01)
<...>Потом Random генерит любое число до 100, считываем из файла строки, и если в начале записано число равное сгенерированному, то выводим его в Memo. Ну как я?
Орел !!! А вот у тебя 8 раз подряд сгенерируется число из последней десятки (90 .. 100) и будешь ты читать файл до посинения ... Оно тебе надо? Делай типизированный файл и не мучайся...
Guest
16.06.2005 12:19
Цитата(volvo @ 16.06.05 12:07)
А вот у тебя 8 раз подряд сгенерируется число из последней десятки (90 .. 100) и будешь ты читать файл до посинения ... Оно тебе надо?
А и нехай генерируется. Файл вообще-то не такой уж и большой. Если будет дмедленно работать, создастся видимость серьезной программы. А то - шух, и готово. Скучно. А насчет выбора Random-ом второй строки не совсем понял. Генерируется номер билета, а не строки из него. Например, сгенерилось "5", ищем строки с числом 5 в начале. Первую - в Memo1 (что-то у меня постоянно пишется Momo. К чему бы это?), вторую - в Memo2 и т.д.
AlienEmperor
16.06.2005 12:33
Цитата
А и нехай генерируется. Файл вообще-то не такой уж и большой. Если будет дмедленно работать, создастся видимость серьезной программы
Молодец! Вот это подход! Вам, батенька, тока в "мелкомягких" работать
Jaxx
16.06.2005 12:48
Цитата(AlienEmperor @ 16.06.05 12:33)
Молодец! Вот это подход! Вам, батенька, тока в "мелкомягких" работать
Не, меня туда не возьмут. Разве что посуду мыть. Теперь еще возник вопрос. Например, выпал по воле случая билет намбер 5. Значит, нужно найтить строки, начинающиеся с цифирки "5". Как нам это сделать? На Паскале понятно-
While not EOF(_file) do begin readln(f,stroka); if stroka[1]='5' then ....
А квак это делается в Delphi?
AlienEmperor
16.06.2005 13:21
И в чем проблема ?
Jaxx
16.06.2005 13:36
Ладно, пойдем другим путем. В прикрепленном файле - архив. Там лежит все, вместе с файлом вопросов (набирать запарился...). Гляньте, что я не так сделал. Почему я написал:
r:=random(73); While not eof(f) do begin readln(f,st); for i:=1 to length(st) do begin if StrToInt(st[i])=r then begin
где r-число, сгенерированное Random, f-файл, st-строка в которую считываем файл. А программка вылетает с ошибкой: 'И' is not a valid integer value. C какого перепугу оно буквы читает?
Jaxx
16.06.2005 13:43
Тьфу, млин. Понял, сам дурак. StrToInt для всех символов строки - это оригинально. Особенно для букевок. А по другому как сделать подскажите?
AlienEmperor
16.06.2005 13:50
Так, глянул я енту фигню... Мне нравится такой подход:
Memo1.Lines.Clear;
Memo1.Lines.Text:=st; ==> это вообще что такое ???
Вообще-то, у Memo есть такая фича как Memo1.Lines.Add ==> вот так надо, тогда строка создается,
Насчет intToStr ==> надо читать посимвольно, если символ <> '0'..'9' то дальше не читаем, а преобразовываем в число... (как вариант - писать всегда фиксированные числа вида 001, 010, 999...
А вообще, прога конечно ужас... Я бы советовал ее пристрелить...
AlienEmperor
16.06.2005 14:10
Блин, посмотрел я этот index.txt... Слушай, а у тебя что ВСЕ записи по три строки ? Тогда это вообще фигня, самому не допереть ? Берешь номер, умножаешь на три - получаешь номер строки, содержащий нужную запись, считываешь - это же вообще ерунда!!!
Jaxx
16.06.2005 14:23
Не надо ее стрелять. :nono: Пока что. Вот про умножить номер на 3 - это не совсем правильно. Первый вопрос билета №3 - это строка номер 7. А если умножить - то мы возымеем последнюю строку. Так что мораль: считать надо так: (номер*3)-2. Класс? В чем разница между Memo1.Lines.Text и Memo1.Lines.Add, если строка создается и так и так? А если числа записать в виде 001, 002 и т.д. то как вы мне предлагаете их Random-ить?
AlienEmperor
16.06.2005 14:32
Цитата
считать надо так: (номер*3)-2. Класс?
дааа... Долго думал ?
А зачем их рэндомить ??? Берется число, к примеру 15... Далее создается временная строка типа "015" и она ищется в файле... Если есть - то ок ==> получена требуемая запись...
Jaxx
16.06.2005 16:46
Ну, я вот тут подумал и решил. В самом деле, не стоит ставить цифры в строках. Это лишний г...рой. Цифры убрал. Выбор строки написал так:
procedure TForm1.Button1Click(Sender: TObject); var f:textfile; i,r:byte; s1,s2,s3:string; st:string; begin randomize; i:=0; assignfile(f,'index.txt'); reset(f); Memo1.Lines.Clear; Memo2.Lines.Clear; Memo3.Lines.Clear; st:=''; r:=random(73); Label2.Caption:=IntToStr®; for i:=1 to ((r-1)*3) do begin readln(f,st); Memo1.Lines.Text:=st; st:=''; readln(f,st); Memo2.Lines.Text:=st; st:=''; readln(f,st); Memo3.Lines.Text:=st; st:=''; end; i:=0; end;
Почему-то выбор строк происходит неправильно. Например, билет с номером 4 показывает строки начиная с 25, билет номер 5 - 34, второй билет кажет на 7 строку. В чем дело? А в половине нажатий в Memo вообще вылазиет не строка, а вертикальная черточка. Если пользовать Memo1.Lines.Add, то иногда в Memo остается часть другого текста.
Jaxx
22.06.2005 13:48
Ну так что, никто не хочет мне помочь? Я же знаю, что надоел уже. Ну что ж со мной поделаешь. Вот прикреплю все что написал. Попробуйте сами и подправьте что я накосячил.
volvo
22.06.2005 13:55
Смотри, что происходит:
r:=random(73); { Ок, берем случайное число ...} Label2.Caption:=IntToStr( R ); { ... заносим его в Label ... } for i:=1 to ((r-1)*3) do readln(f,st); { никаких Begin -ов } { в цикле - только пропускаем ненужные строки }
{ а уже ПОСЛЕ цикла - читаем следующие 3 строки... } Memo1.Lines.Text:=st; st:=''; readln(f,st); Memo2.Lines.Text:=st; st:=''; readln(f,st); Memo3.Lines.Text:=st; st:='';
i:=0;
попробуй, должно сработать... ;)
Jaxx
22.06.2005 14:02
Ух ты, блин! Сработало! Неужели я так лопухнулся... М-да, не зря Volvo считаются чрезвычайно надежными машинами. Только вот еще вопрос напоследок: Random генерирует все числа до 100 (у меня пока 73), в том числе и 0. Как сделать, чтобы числа генерились начиная с 1?
AlienEmperor
22.06.2005 14:19
Ну, человек, ты кадр... 1+Random(n) - всегда с единицы будет...
Jaxx
22.06.2005 14:35
Может и кадр. Ну не разбираюсь я в программировании. Зато в пиве разбираюсь.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.