Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Чтение из файла по строкам [D5, XP]


RobinBad ©   (2006-07-20 15:59:00) 

Как присвоить переменной (типа String) значение, скажем из третьей строки открываемого файла в OpenDialog (*.txt)?


Германн   (2006-07-22 00:43:00) [1]

Короче, блин!
Используем формулировку АП [сам он придумал или содрал где, не знаю. :-) Но она, имхо, правильная]. Текстовый файл это устройство с "последовательным" доступом. А StringList - устройство с произвольным доступом. А дальше для выбора наилучшего алгоритма нужно "грамотно уяснить задачу", "выбрать решение" и "отдать громким командным голосом приказ" (как учили нас на военной кафедре :-).


Gydvin   (2006-07-22 00:41:00) [2]


> XeON ©   (22.07.06 00:20) [13]
>Ну вы блин даёте. Если файл не большого размера. Т.е. он не 20Мб, >например и тебе не надо из него вынуть строку №1 987 305 например, то вот >так:

У меня прям таки глаза открылись, до чего все просто  )))))


XeON   (2006-07-22 00:20:00) [3]

Ну вы блин даёте. Если файл не большого размера. Т.е. он не 20Мб, например и тебе не надо из него вынуть строку №1 987 305 например, то вот так:

var
S:String;
F: File of Text;
...
Begin
if OpenDialog1.Execute then
AssignFile(F,OpenDialog1.FileName);
Reset(F);
ReadLn(F,S); // Читаем строку №1 (и ничего с ней не делаем)
ReadLn(F,S); // Читаем строку №2, по аналогии
ReadLn(F,S); //Читаем строку №3...
...
end;

Вот теперь пременная в переменной S и будет лежат значение строки №3.

А можно ещё подготовить специальную функцию для етого. Надеюсь ты знаешь, куда функции втыкают и как ими пользоваться. Вот собественно она сама:
function StringN(FileName:String; StringNumber: Integer): String;
var
F:TextFile;
i:Integer;
S:String;

begin
i:=0;
AssignFile(F, FileName);
Reset(F);
While i<StringNumber do
begin
inc(i);
ReadLn(F,S);
end;
Result:=S;
end;

Для справки: функции и процедуры (в т.ч. данная функция) втыкаются в исходный код после вот таких вот строчек:
implementation

{$R *.dfm}


После чего можешь её использовать, напиример вот так, как я:
Делаешь кнопку, и в кнопке пишешь:
Form1.Caption:=StringN('C:\111.txt',7);
StringN - это собственно сама функция. ('C:\111.txt); - это имя файла, в котором тебе нада строку получить. А "7" - это номер строки в этом самом файле. Там ещё мона обрабоку сделать что бы ошибок небыло, если ты вдруг попросил строку в файле которой не существует. Это делается с помощью: EoF(End of File) - функция проверки, достигнут ли конец файла или с помощью обрабочика исключений можно Try Except.

Вот такая вот колбаса. Все благодарности, непристойности, оскорбления и всё остальное - пиши на мыло: wolf-alone@bk.ru. А так же на него можешь задавать любые вопросы по Delphi и C++. Овечаю почти моментально, т.к. под рукой КПК и сотовый. На сотовый получаю уведомление о пришедшей почте в течении 1мин. Как правило в течении 10мин. - отвечаю! Так-что пиши. Можешь так же задать любые вопросы нашей команде программистов. Её координаты ты так же можешь узнать, написав мне на мыло.


Gydvin   (2006-07-21 20:52:00) [4]

волшебное слово "Скажем"


Gydvin   (2006-07-21 20:51:00) [5]

ну что напали в сабже же сказано

>  скажем из третьей строки

а вообще это для общего случая. Я эти бааааалшой файл ковырял, довольнотаки работает шустро


Loginov Dmitry   (2006-07-21 20:13:00) [6]

> Gydvin ©   (21.07.06 17:05) [8]


Стока кода, чтобы 3-ю строчку выдрать? Однако мощно ;)


Amoeba   (2006-07-21 17:46:00) [7]


> Gydvin ©   (21.07.06 17:05) [8]

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


Gydvin   (2006-07-21 17:05:00) [8]

Где-то выдрал

function GrabLine(const AFileName: string; ALine: Integer): string;
var
  fs: TFileStream;
  buf: packed array[0..4095] of Char;
  bufRead: Integer;
  bufPos: PChar;
  lineStart: PChar;
  tmp: string;
begin
  fs := TFileStream.Create(AFileName, fmOpenRead);
  try
    Dec(ALine);
    bufRead := 0;
    bufPos := nil;

    { read the first line specially }
    if ALine = 0 then
    begin
      bufRead := fs.Read(buf, SizeOf(buf));
           if bufRead = 0 then
        raise Exception.Create('Толковый словарь испорчен!'+#13#10+' Переустановите приложение.');
      bufPos := buf;
    end else
      while ALine > 0 do
      begin
        { read in a buffer }
        bufRead := fs.Read(buf, SizeOf(buf));
        if bufRead = 0 then
          raise Exception.Create('Line not found');
        bufPos := buf;
        while (bufRead > 0) and (ALine > 0) do
        begin
          if bufPos^ = #10 then
            Dec(ALine);
            Inc(bufPos);
            Dec(bufRead);
        end;
      end;
    { Found the beginning of the line at bufPos... scan for end.
     2 cases:
       1) we'll find it before the end of this buffer
       2) it'll go beyond this buffer and into n more buffers }
    lineStart := bufPos;
    while (bufRead > 0) and (bufPos^ <> #10) do
    begin
      Inc(bufPos);
      Dec(bufRead);
    end;
    { if bufRead is positive, we'll have found the end and we can leave. }
    SetString(Result, lineStart, bufPos - lineStart);
    { determine if there are more buffers to process }
    while bufRead = 0 do
    begin
      bufRead := fs.Read(buf, SizeOf(buf));
      lineStart := buf;
      bufPos := buf;
      while (bufRead > 0) and (bufPos^ <> #10) do
      begin
        Inc(bufPos);
        Dec(bufRead);
      end;
      SetString(tmp, lineStart, bufPos - lineStart);
      Result := Result + tmp;
    end;
  finally
    fs.Free;

  end;
  delete(Result,length(Result),1);
end;


Amoeba   (2006-07-21 11:32:00) [9]


> Германн ©   (20.07.06 17:26) [6]
>
> > Для небольших файлов годится, но если файл большой, то
> предпочтительнее/экономичнее
> > для данной задачи будет [1].
>
>
> Это если нужно 3-ью, а не 3-ью с конца. И если только одну
> и один раз.

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


Германн   (2006-07-20 17:26:00) [10]


> Для небольших файлов годится, но если файл большой, то предпочтительнее/экономичнее
> для данной задачи будет [1].


Это если нужно 3-ью, а не 3-ью с конца. И если только одну и один раз.


Amoeba   (2006-07-20 17:21:00) [11]


> Loginov Dmitry ©   (20.07.06 17:09) [4]

Для небольших файлов годится, но если файл большой, то предпочтительнее/экономичнее для данной задачи будет [1].


Loginov Dmitry   (2006-07-20 17:09:00) [12]

Как вариант:
with TStringList.Create do
try
 LoadFromFile(AFileName);
 S := Strings[N - 1]; // N = 3
finally
 Free;
end;


Amoeba   (2006-07-20 16:21:00) [13]


> Elen ©   (20.07.06 16:13) [2]
> P.S. или через TFileStream

Не  стоит. Выигрыш отрицательный. Зачем так сильно усложнять себе работу в случае текстового файла?


Elen   (2006-07-20 16:13:00) [14]

P.S. или через TFileStream


Elen   (2006-07-20 16:12:00) [15]


assignFile(f,opendialog1.filename);
reset(f);
for i:=1 to 3 do readln(f,a);

где a - строка


Наверх

Титульная страница Поиск, карта сайта Написать письмо