Помощь - Поиск - Пользователи - Календарь
Полная версия: Чтение текстового файла
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Delphi
Jaxx
Значит так. Мне нужно написать следующую программу: небольшая формочка с тремя полями Memo, полем Label и двумя Батонами. Суть программы: есть 100 экз. билетов, в каждом из них по 3 вопроса. По нажатию на кнопку нужно вывести - в Label номер билета, в поля Memo вопросы из него. В программе, естественно использ. Random для выбора билета. Проблема моя в том, что я не знаю, как записать вопросы и билеты. Решил забить их в текстовый файл. В каждую строку по одному вопросу (то есть билет №1 - строки 1,2,3; билет №2 - строки 4,5,6) но как мне считать строки с определенными номерами и вывести их? Али может в какую-нить БД это все впендюрить? Правда ни разу не пользовал sad.gif
AlienEmperor
Как вариант: берешь поток, приделываешь вначале Header в котором содержится вся инфа (кол-во записей + массив размеров каждой записи) пишешь через Memo.Lines.SaveToStream (вроде так, посмотри сам) и все... Считываешь след. образом: выбираешь (случайно) запись, считываешь все размеры ДО нее, пропускаешь их в файле, читаешь нужную...

P.S. Еще вариант: сделать через типизированный файл (к примеру, 1000 байт на текст + номер билета) ==> скучно и не эффективно...
Jaxx
Я тут другую систему придумал. Дело в том, что мне нужно все сделать максимально просто. Берем текстовый файл, пишем в него вопросы следующим образом:
Код

1Бла-бла-бла....
1Снова бла-бла
1И еще раз бла
2Второй билет пошел
2В нем тоже бла-бла
2Но суть не в этом
...
100Бла-Бла
100Предпоследний Бла
100Бла-последний

Потом Random генерит любое число до 100, считываем из файла строки, и если в начале записано число равное сгенерированному, то выводим его в Memo. Ну как я? rolleyes.gif
AlienEmperor
Тоже вариант... smile.gif Простая разметка, тока вот что будет, если в билете 3 строки, а рэндом указал на 2-ую ? Или ты в любом случае весь файл сразу в память будешь читать ?
volvo
Цитата(Jaxx @ 16.06.05 12:01)
<...>Потом Random генерит любое число до 100, считываем из файла строки, и если в начале записано число равное сгенерированному, то выводим его в Memo. Ну как я? rolleyes.gif

Орел !!! smile.gif А вот у тебя 8 раз подряд сгенерируется число из последней десятки (90 .. 100) и будешь ты читать файл до посинения ... Оно тебе надо? Делай типизированный файл и не мучайся...
Guest
Цитата(volvo @ 16.06.05 12:07)
А вот у тебя 8 раз подряд сгенерируется число из последней десятки (90 .. 100) и будешь ты читать файл до посинения ... Оно тебе надо?

А и нехай генерируется. Файл вообще-то не такой уж и большой. Если будет дмедленно работать, создастся видимость серьезной программы. А то - шух, и готово. Скучно. А насчет выбора Random-ом второй строки не совсем понял. Генерируется номер билета, а не строки из него. Например, сгенерилось "5", ищем строки с числом 5 в начале. Первую - в Memo1 (что-то у меня постоянно пишется Momo. К чему бы это?), вторую - в Memo2 и т.д.
AlienEmperor
Цитата
А и нехай генерируется. Файл вообще-то не такой уж и большой. Если будет дмедленно работать, создастся видимость серьезной программы


Молодец! Вот это подход! Вам, батенька, тока в "мелкомягких" работать smile.gif smile.gif smile.gif
Jaxx
Цитата(AlienEmperor @ 16.06.05 12:33)
Молодец! Вот это подход! Вам, батенька, тока в "мелкомягких" работать smile.gif smile.gif smile.gif

Не, меня туда не возьмут. Разве что посуду мыть. Теперь еще возник вопрос. Например, выпал по воле случая билет намбер 5. Значит, нужно найтить строки, начинающиеся с цифирки "5". Как нам это сделать? На Паскале понятно-

While not EOF(_file) do begin
readln(f,stroka);
if stroka[1]='5' then
....


А квак это делается в Delphi?
AlienEmperor
И в чем проблема ?
Jaxx
Ладно, пойдем другим путем. В прикрепленном файле - архив. Там лежит все, вместе с файлом вопросов (набирать запарился...). Гляньте, что я не так сделал.
Почему я написал:

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
Тьфу, млин. Понял, сам дурак. StrToInt для всех символов строки - это оригинально. Особенно для букевок. А по другому как сделать подскажите?
AlienEmperor
Так, глянул я енту фигню... Мне нравится такой подход:

Memo1.Lines.Clear;

Memo1.Lines.Text:=st; ==> это вообще что такое ???

Вообще-то, у Memo есть такая фича как Memo1.Lines.Add ==> вот так надо, тогда строка создается,

Насчет intToStr ==> надо читать посимвольно, если символ <> '0'..'9' то дальше не читаем, а преобразовываем в число... (как вариант - писать всегда фиксированные числа вида 001, 010, 999...

А вообще, прога конечно ужас... Я бы советовал ее пристрелить...
AlienEmperor
Блин, посмотрел я этот index.txt... Слушай, а у тебя что ВСЕ записи по три строки ?
Тогда это вообще фигня, самому не допереть ? Берешь номер, умножаешь на три - получаешь номер строки, содержащий нужную запись, считываешь - это же вообще ерунда!!!
Jaxx
Не надо ее стрелять. :nono: Пока что. Вот про умножить номер на 3 - это не совсем правильно. Первый вопрос билета №3 - это строка номер 7. А если умножить - то мы возымеем последнюю строку. Так что мораль: считать надо так: (номер*3)-2. Класс? smile.gif В чем разница между Memo1.Lines.Text и Memo1.Lines.Add, если строка создается и так и так? А если числа записать в виде 001, 002 и т.д. то как вы мне предлагаете их Random-ить?
AlienEmperor
Цитата
считать надо так: (номер*3)-2. Класс?


дааа... Долго думал ? smile.gif smile.gif smile.gif

А зачем их рэндомить ???
Берется число, к примеру 15... Далее создается временная строка типа "015" и она ищется в файле... Если есть - то ок ==> получена требуемая запись...
Jaxx
Ну, я вот тут подумал и решил. В самом деле, не стоит ставить цифры в строках. Это лишний г...рой. Цифры убрал. Выбор строки написал так:

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
Ну так что, никто не хочет мне помочь? Я же знаю, что надоел уже. smile.gif Ну что ж со мной поделаешь. Вот прикреплю все что написал. Попробуйте сами и подправьте что я накосячил.
volvo
Смотри, что происходит:
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
Ух ты, блин! Сработало! Неужели я так лопухнулся... М-да, не зря Volvo считаются чрезвычайно надежными машинами. Только вот еще вопрос напоследок: Random генерирует все числа до 100 (у меня пока 73), в том числе и 0. Как сделать, чтобы числа генерились начиная с 1?
AlienEmperor
Ну, человек, ты кадр... 1+Random(n) - всегда с единицы будет...
Jaxx
Может и кадр. Ну не разбираюсь я в программировании. Зато в пиве разбираюсь. rolleyes.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.