![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Поиск заданного фрагмента в файле
Pretender © (2006-04-25 12:13:00)Всем здравствуйте! :)
ПОдскажите, пожалуйста, вот какую вещь: есть текстовый файл, содержащий строки вида
STR00234 6058 1 3 + 04.04.2006Бюро экспертизы проектов и смет
Необходимо организовать по ней поиск заданного значения, как: считать строку, если есть в строке '1' и '3' и '+', то увеличить значения переменных per1, per2, per3 на единицу, считать слледующую строку и т.д. Помогите разобраться, пожалуйста!
Вот что пока получилось:
procedure TForm1.Button1Click(Sender: TObject);
var
F: Textfile;
res, i, KolStr: integer;
answ : word;
mas: array of string[80];
st1: string;
begin
AssignFile(F, fname);
repeat
{$I-}
Reset(F);
{$I+}
res:=IOResult;
if res <> 0
then answ:=MessageDlg('Ошибка открытия '
+ fname + #13 + 'Повторить попытку?',mtWarning,[mbYes, mbNo],0);
until (res= 0) OR (answ = mrNo);
if res <> 0
then exit;
KolStr:=LinesCount(fname); //функция подсчёта количества строк в файле
SetLength(mas, KolStr); //создаю динамический массив
ListBox1.Items.Clear;
for i:=0 to KolStr do begin
Readln(F, St1);
mas[i]:=st1;
ListBox1.Items.Add(StrDosToWin(mas[i]));
end;
Label3.Caption := IntToStr(KolStr);
end;
function StrDosToWin(AString : string) : string;
begin
Result := AString;
OemToChar(Pointer(Result), Pointer(Result));
end;
Надо сказать, что все эти операции с массивом и листбоксом делались для проверки. Вообще же, я хотел разбить строку по элементам и каждый элемент занести в ячейку массива, а уж осуществить выборку по массиву будет проще простого. Вот только не знаю как это сделать, может будут какие предложения?
Gydvin (2006-04-26 00:46:00) [1]На email )))))
Pretender (2006-04-26 00:36:00) [2]:))) Спасибо огромоное Gydvin. С меня много пива!
Gydvin (2006-04-26 00:33:00) [3]Понятно, удачи
Pretender (2006-04-26 00:27:00) [4]Не по отдельности, а вместе. Сколько таких Н/К с признаком 1, Н/К с признаком 50 и Н/К без 1 и 50 - они одного вида, но разного типа, где тип определяется наличием/отсутствием у Н/К 1 или 50. Т.е.
Н/К без всего - столько то
Н/К с 1 - столько то
Н/К с 50 - столько то
Pretender (2006-04-26 00:26:00) [5]Не по отдельности, а вместе. Сколько таких Н/К с признаком 1, Н/К с признаком 50 и Н/К без 1 и 50 - они одного вида, но разного типа, где тип определяется наличием/отсутствием у Н/К 1 или 50.
Gydvin (2006-04-26 00:21:00) [6]
> С/В, ИЦ, VIP
а ну тады да, ну я думаю это особого труда не составит, дорожка накатаная
> А если мне нужно вывести
Думаю вьехал, это например подсчитать допустим сколько
н/к 1, н/к 2 по отдельности
Pretender (2006-04-26 00:19:00) [7]Да :) Только я уже один параметр удалил, ненужный он оказался :)
Gydvin (2006-04-26 00:17:00) [8]
> Понял я, что эта штука делает - раскладывает каждую строчку
> по полочкам
> (1, 0, 0, 0, 1)
не 5 а шесть. Отсчет идет с нуля до пяти.
(1, 0, 0, 0,0,1)
Pretender (2006-04-26 00:11:00) [9]Просто кроме Н/К в файле встречается С/В, ИЦ, VIP :) Соответственно это еще три переменных, причём ИЦ не учитывается, значит две. А если мне нужно вывести сколько у меня всего у меня локальных подключеных Н/К? Т.е. это те, у которых a=1,b,c=0,d=1.
Gydvin (2006-04-25 23:51:00) [10]
> И не массивы я должен определять, а просто задать ещё одну
> переменную ил несколько переменных в массиве r, а уже зная
> какой признак и где у меня сидит осуществлять подсчёт нужных
> мне элементов.
Ничего в r задавать не надо, это и так километр переменных, а подсчет уже реаллизован смотри [40]
Pretender (2006-04-25 23:44:00) [11]И не массивы я должен определять, а просто задать ещё одну переменную ил несколько переменных в массиве r, а уже зная какой признак и где у меня сидит осуществлять подсчёт нужных мне элементов.
Gydvin (2006-04-25 23:38:00) [12]
> Gydvin © (25.04.06 21:22) [34]
> for x:=0 to y-1 do begin
> if r[x,1]>0 then inc(a);
> if r[x,2]>0 then inc(b);
> if r[x,3]>0 then inc(c);
> if r[x,4]>0 then inc(d);
> if r[x,5]>0 then inc(e);
> end;
))))
Gydvin (2006-04-25 23:36:00) [13]
И так пять условий по остальным типам (соответственно с заданием своего массива). А вот это создаёт двумерный динамический массив?
setlength(r,y);
r[y-1,0]:=x;
Нет.
Вобще здесь используется двумерный массив, но он только на половину динамический так как: r:array of array[0..5]of integer;(полностью динамеческий двухмерный r:array of array of integer);
setlength(r,y);//это задает размер массива (для полностью setlength(r,1,1);)
r[y-1,0]:=xа вот сюда я на всякий случай положил номер строки (stringlist) в которой выполнились условия поиска, этот номер можно использовать в дальнейшем например
for x:=0 to y-1 do showmessage(list.Strings[r,y,0];
> Gydvin © (25.04.06 21:22) [34]
> Если массив, stringlist и y обьявишь глобально то сможешь
> использовать данные из любого участка твоей проги
>
Pretender (2006-04-25 23:31:00) [14]Понял я, что эта штука делает - раскладывает каждую строчку по полочкам
((1, 0, 0, 0, 1), (2, 0, 0, 1, 1), (3, 0, 0, 1, 1), (4, 0, 0, 0, 1), (5, 0, 1, 0, 1), (6, 0, 1, 0, 1), (7, 0, 1, 0, 1), (8, 1, 0, 0, 1), (9, 0, 1, 0, 1), (10, 1, 0, 0, 1), (11, 0, 1, 0, 1), (12, 0, 0, 1, 1), (13, 0, 1, 0, 1), (14, 0, 0, 0, 1), (15, 0, 0, 0, 1), (16, 0, 1, 0, 1))
Единственное теперь, что нужно сделать - это организовать выборку и посчёт по элементам массива.
Pretender (2006-04-25 23:00:00) [15]Ух ты! Да вы и впрям великий и могучий волшебник :) Да, мне до такого ещё далеко... :( Вообще я хотел так: каждая строка определяет тип дистрибутива - Н/В это некоммерческий, если нет это го признака в строке, то коммерческий. Если в этой же строке есть 1, то это сетевой однопользовательский, если 50 сетевой, а если нет, то локальный. Если в этой строке есть +, то эначит обслуживается, х значит не обслуживается и не учитывается. Значение 3 вообще не нужно. Значит r:array of array[0..4]of integer. В итоге по всему файлу должна получится таблица обслуживаемых программ
локальных = [количество]
сетевых однопользовательских = [количество]
сетевых = [количество]
Н/В локальных = [количество]
Н/В сетевых однопользовательских = [количество]
Н/В сетевых = [количество]
Только не подумайте, что сажусь на шею, дальше сам попробую, просто вот как я это хочу сделать:
if (a=0)and(b=0)and(c=0)and(d=1)then begin //это будет локальный
inc(y); //коммерческий обслуживаемый
setlength(r,y); //дистрибутив
r[y-1,0]:=x;
r[y-1,1]:=a;
r[y-1,2]:=b;
r[y-1,3]:=c;
r[y-1,4]:=d;
И так пять условий по остальным типам (соответственно с заданием своего массива). А вот это создаёт двумерный динамический массив?
setlength(r,y);
r[y-1,0]:=x;
SergP (2006-04-25 22:13:00) [16]
var
stroka:string;
str:string;
sizestr:integer;
...
atroka:='...';
with TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive) do
try
SizeStr := Size - Position;
SetString(Str, nil, SizeStr);
Read(Pointer(Str)^, SizeStr);
i:=pos(stroka,str);
if i>0 then ...
finally
Free;
end;
...
Gydvin (2006-04-25 21:53:00) [17]
if (a=1)or(b=1)or(c=1)or(d=1)then begin
inc(y);
setlength(r,y);
r[y-1,0]:=x;
r[y-1,1]:=a;
r[y-1,2]:=b;
r[y-1,3]:=c;
r[y-1,4]:=d;
r[y-1,5]:=e;
end;
ТО
if (a=1)or(b=1)or(c=1)or(d=1)or(e=1)then begin
inc(y);
setlength(r,y);
r[y-1,0]:=x;
r[y-1,1]:=a;
r[y-1,2]:=b;
r[y-1,3]:=c;
r[y-1,4]:=d;
r[y-1,5]:=e;
end;
Gydvin (2006-04-25 21:22:00) [18]
procedure TForm1.Button1Click(Sender: TObject);
var
list:tstringlist;
r:array of array[0..5]of integer;
x,y,a,b,c,d,e:integer;
s:string;
begin
if OpenDialog1.Execute and fileexists(OpenDialog1.FileName) then begin
list:=tstringlist.Create;
list.LoadFromFile(OpenDialog1.FileName);
y:=0;
setlength(r,y);
for x:=0 to list.Count-1 do begin
s:=list.Strings[x];
a:=0;
b:=0;
c:=0;
d:=0;
e:=0;
if copy(s,28,3)=' Н/В' then a:=1;
if copy(s,31,1)='1' then b:=1;
if copy(s,31,2)='50' then c:=1;
if copy(s,38,1)='+' then d:=1;
if copy(s,35,1)='3' then e:=1;
if (a=1)or(b=1)or(c=1)or(d=1)then begin
inc(y);
setlength(r,y);
r[y-1,0]:=x;
r[y-1,1]:=a;
r[y-1,2]:=b;
r[y-1,3]:=c;
r[y-1,4]:=d;
r[y-1,5]:=e;
end;
end;
a:=0;
b:=0;
c:=0;
d:=0;
e:=0;
for x:=0 to y-1 do begin
if r[x,1]>0 then inc(a);
if r[x,2]>0 then inc(b);
if r[x,3]>0 then inc(c);
if r[x,4]>0 then inc(d);
if r[x,5]>0 then inc(e);
end;
showmessage(' Н/В = '+inttostr(a)+#13#10+'1 = '+inttostr(b)+#13#10+'50 = '+inttostr(c)+#13#10+'+ = '+inttostr(d)+#13#10+'3 = '+inttostr(e));
list.Free;
setlength(r,0);
end;
end;
Если массив, stringlist и y обьявишь глобально то сможешь использовать данные из любого участка твоей проги
Pretender (2006-04-25 20:21:00) [19]1. Да, писал же - ts[j];
2. Одномерный, если это имеется в виду;
3. Создаётся динамический массив mas[i], сожержащий целые строки текстового файла, потом с помощью TrimRight(Copy(mas[i],1,6)) осуществляется выборка нужных элементов массива, которые и заносятся в ts[j]:
4. Другого метода я не придумал, в интернете смотрел процедуры по ключевым словам "поиск текста в текстовом файле", но не понял как они работают, поэтому остановился на своём. Если есть более простое решение, поделитесь :)
Инфа в исходном файле хранится так:
STR00123 23478 Н/В 3 + 15.03.2006Ивановск
STR00123 6734 1 3 + 14.02.2006Петровск
STR00123 2946 50 3 + 21.02.2006Сидоровск
.....
Позиции каждого значения фиксированиы, просто здесь почему-то так вставилось. Собственно интересуют элементы Н/В, 3, 1, 50, + - по ним будет осуществлятся выборка.
Gydvin (2006-04-25 19:54:00) [20]1. массив динамический?
2. массив трех уровневый?
3. каким образом туда загоняются значения из файла?
4. обязательно использовать массив как таковой (особенно три уровня, просто можно обойтись и более простым решением, а главное более быстрым)?
зы. я не увидел каким образом хранится инфа в файле (copy/paste)