Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.05.14;
Скачать: [xml.tar.bz2];

Вниз

Поиск заданного фрагмента в файле   Найти похожие ветки 

 
Pretender ©   (2006-04-25 12:13) [0]

Всем здравствуйте! :)

ПОдскажите, пожалуйста, вот какую вещь: есть текстовый файл, содержащий строки вида

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;

Надо сказать, что все эти операции с массивом и листбоксом делались для проверки. Вообще же, я хотел разбить строку по элементам и каждый элемент занести в ячейку массива, а уж осуществить выборку по массиву будет проще простого. Вот только не знаю как это сделать, может будут какие предложения?


 
Palladin ©   (2006-04-25 13:14) [1]

а строчка то чем нибудь разделена или фиксированное количество символов под каждую позицию определено?


 
Johnmen ©   (2006-04-25 13:22) [2]


> for i:=0 to KolStr do begin


Это ошибка. Элементом на 1 меньше...


 
Pretender ©   (2006-04-25 14:35) [3]


> а строчка то чем нибудь разделена или фиксированное количество
> символов под каждую позицию определено

Эта строчка выглядит так, как я привёл - разделена пробелами. По идее, наверно, нужно искать пробелы до тех пор, пока не встретится символ, а затем определять длину всего слова, заносить её в массиы и искать дальше. Я правильно думаю?

> Это ошибка. Элементом на 1 меньше...

Не ошибка. В динамических массивах нумерация идет с 0 (если не ошибаюсь). Если поставить 1, то приложение "вылетает".


 
MBo ©   (2006-04-25 14:45) [4]

>Не ошибка.
И всё-таки ошибка.

for i:=0 to KolStr - 1


 
Pretender ©   (2006-04-25 14:56) [5]


> for i:=0 to KolStr - 1

Согласен, сейчас попробовал - в листбоксе стало на одну строчку меньше, как в файле :) А по существу?


 
Джо ©   (2006-04-25 14:59) [6]

Каждое поле находится в фиксированной позиции строки? Или нет? Что выступает в качестве разделителя? Табуляторы или пробелы. В общем, нормально опиши формат файла.


 
Pretender ©   (2006-04-25 15:10) [7]


> Каждое поле находится в фиксированной позиции строки?

Вроде бы да. Если смотреть в фаре по F4 (редактирование), то поля фиксированы. Если по тому, как они в листбокс заносятся, то нет. В качестве разделителя выступает пробел, но не один, т.е. где-то один, а где-то нет. Если б мог, что приложил бы сам файл, но не знаю как тут аттачить.


 
Джо ©   (2006-04-25 15:16) [8]

Если позиции подстрок фиксирована, то можно воспользоваться функцией Copy. Т.е, например, если нужные значения находятся в позициях 1,10,15..., то получить второе значение можно так:
Copy (Исходная_строка,10,5) и обрезать лишний пробелы справа.


 
Джо ©   (2006-04-25 15:17) [9]

[8]
> позиции подстрок фиксирована

> обрезать лишний пробелы



Окончательно перешел на турецкий язык, к чему бы это? :*(


 
Pretender ©   (2006-04-25 15:22) [10]

А если не фиксирована?


 
Джо ©   (2006-04-25 15:26) [11]

> [10] Pretender ©   (25.04.06 15:22)
> А если не фиксирована?

Так она фиксирована или нет? Ты уж определись, пожалуйста. Вряд ли кто-то захочет писать тут тебе 15 вариант "на всякий случай" задаром.


 
Джо ©   (2006-04-25 15:27) [12]

Добавлю. Перед написанием программы разбора какого-то формата, ВСЕГДА следует досконально изучить входной формат. От и до.


 
Pretender ©   (2006-04-25 15:37) [13]

Так понимаешь, допустим все позиции, допустим, номера продукта, начинаются с одного значения, а длину могут иметь разную. Вот в чём дело. Т.е. получается, что длина у всех позиций не фиксирована, но начинается с определённой пизиции. Простите меня.


 
Джо ©   (2006-04-25 15:40) [14]

Прочитай, пожалуйста, еще раз мой пост [8]. Копируешь, начиная с определенной позиции по следующую позицию (кол-во = след.позиция - пред.позиция), затем обрезаешь справа пробелы.


 
Pretender ©   (2006-04-25 15:44) [15]


> затем обрезаешь справа пробелы

Если не трудно, то как? Я попробовал считать определённые строки, в разных местах - всё копируется. нормалёк. Я где-то в инете видел эту функцию с обрезкой, но можно здесь привести?


 
Джо ©   (2006-04-25 15:44) [16]

RTrim


 
Джо ©   (2006-04-25 15:45) [17]

Сорри, TrimRight.


 
Pretender ©   (2006-04-25 15:57) [18]

Спасибо, сейчас попробую - отпишусь.


 
Pretender ©   (2006-04-25 16:09) [19]

Джо, сделал ещё такой динамический массив

ts[j]:=TrimRight(Copy(mas[i],10,?));

что-то никак не допру, что в качестве 3-го рараметра указывается, Pos?


 
Джо ©   (2006-04-25 16:09) [20]

> что в качестве 3-го рараметра

Количество. У тебя что — справку враги украли? ;)


 
Pretender ©   (2006-04-25 16:17) [21]


> У тебя что — справку враги украли? ;)

Эти гады решили поиздеваться - TrimRight там нет, как много чего другого :) А количество чего (только сильно не пинай :))?


 
Джо ©   (2006-04-25 16:19) [22]

> А количество чего (только сильно не пинай :))?

Копируемых символов.


 
Pretender ©   (2006-04-25 16:23) [23]

А если, допустим, у меня в одной строке 2 символа, а в следующей 1, то ножно указывать максимальное количество (в данном случае 2), а где один символ, то там пробел удалится?


 
Джо ©   (2006-04-25 16:28) [24]

> [23] Pretender ©   (25.04.06 16:23)
> А если, допустим, у меня в одной строке 2 символа, а в следующей
> 1, то ножно указывать максимальное количество (в данном
> случае 2), а где один символ, то там пробел удалится?

Слушай, ну что мы на одном месте топчемся-то? Если что-то непонятно, перечитай ветку еще раз, просто добавить уже нечего, я всё сказал, в том числе и на этот вопрос отвечал, два раза.


 
Pretender ©   (2006-04-25 16:31) [25]

Ясно, я уже из практики понял, что да. Спасибо.


 
Pretender ©   (2006-04-25 19:04) [26]

Вот теперь что я делаю: у меня есть текстовый файл с тремя строками - привет, 50 и пока. Я пытають из массива путём сравнения выявить совпадащие элементы, а затем увеличить счётчик k на единицу. Но программа "вылетает". Что не так? Видно в динамическом массиве что-то не то...

for i:=0 to KolStr do

begin

Readln(F, St1);
mas[i]:=st1;
ts[j]:=TrimRight(Copy(mas[i],1,6));

obr:="50";
if ts[j] = obr
then
k:=k+1
end;


 
Джо ©   (2006-04-25 19:15) [27]

Честно говоря, совсем не понял, какое отношение сабж имеет к файлу "с тремя строками - привет, 50 и пока". Ну да ладно.


> mas[i]:=st1;

Ты размер массива задаешь перед циклом?


 
Gydvin ©   (2006-04-25 19:16) [28]

Ниасилил.

Приведите несколько строчек из файла с выполняемыми условиями и не выполняемыми (соответсвенно указав какие из них какие) и какой необходимо получить результат. А то нифига не понятно


 
Pretender ©   (2006-04-25 19:30) [29]


> какое отношение сабж имеет к файлу

Ну это тестовый файл, для проверки. Размер не задаётся, а определяется уже до цикла следующим образом:

KolStr:=LinesCount(fname); //LinesCount-функция высчитывает количество    
                                       строк в файле
SetLength(mas,KolStr); //собственно сам массив, размерность 1хKolStr,
                                вообщем одномерный


> Приведите несколько строчек из файла с выполняемыми условиями
> и не выполняемыми

Я ж привёл выше, if ts[j] = obr, на нём прога и вылетает. Это я таким образом хочу путем сравнения найти в массиве элемент, который совпадает со стринговой переменной obr="50".


 
Gydvin ©   (2006-04-25 19:37) [30]

Сvотрите [28], ненадо кода, только задание и желаемый результат.

зы. Из всего вышеувиденого я увидел только белиберду


 
Pretender ©   (2006-04-25 19:47) [31]

А задание такое: есть у меня динамический массив ts[j], который заполняется в цикле и содержит некую последовательность элементов, например, ts["привет","50","пока"]. Желаемый результат: сделать так, чтобы в этом массиве искалось строковое значение 50 и по нахождению оного счётчик к увеличивался на единицу, а затем передавался дальше в программу, ну, например, Label1.Caption:=IntToStr(к). Вот что я хочу.


 
Gydvin ©   (2006-04-25 19:54) [32]

1. массив динамический?
2. массив трех уровневый?
3. каким образом туда загоняются значения из файла?
4. обязательно использовать массив как таковой (особенно три уровня, просто можно обойтись и более простым решением, а главное более быстрым)?

зы. я не увидел каким образом хранится инфа в файле (copy/paste)


 
Pretender ©   (2006-04-25 20:21) [33]

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 21:22) [34]

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 обьявишь глобально то сможешь использовать данные из любого участка твоей проги


 
Gydvin ©   (2006-04-25 21:53) [35]

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;


 
SergP ©   (2006-04-25 22:13) [36]


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;
...


 
Pretender ©   (2006-04-25 23:00) [37]

Ух ты! Да вы и впрям великий и могучий волшебник :) Да, мне до такого ещё далеко... :( Вообще я хотел так: каждая строка определяет тип дистрибутива - Н/В это некоммерческий, если нет это го признака в строке, то коммерческий. Если в этой же строке есть 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;


 
Pretender ©   (2006-04-25 23:31) [38]

Понял я, что эта штука делает - раскладывает каждую строчку по полочкам

((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))

Единственное теперь, что нужно сделать - это организовать выборку и посчёт по элементам массива.


 
Gydvin ©   (2006-04-25 23:36) [39]

И так пять условий по остальным типам (соответственно с заданием своего массива). А вот это создаёт двумерный динамический массив?
 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 обьявишь глобально то сможешь
> использовать данные из любого участка твоей проги
>


 
Gydvin ©   (2006-04-25 23:38) [40]


>  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;

))))



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2006.05.14;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.012 c
2-1146167624
Alecs
2006-04-27 23:53
2006.05.14
Excel Delphi работа с уже открытым файлом


2-1145971001
Ice [greensky]
2006-04-25 17:16
2006.05.14
Как изменить цвет ячейки в stringgrid?


6-1137715846
Yegorchic
2006-01-20 03:10
2006.05.14
TClientSocket


15-1145288708
TUser
2006-04-17 19:45
2006.05.14
Защита от паразита


2-1145789779
sysop
2006-04-23 14:56
2006.05.14
Выравнивание строки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский