IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> Анализ log-файла..., программа обработки огромного лог файла
сообщение
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 15
Пол: Мужской
Реальное имя: Роман

Репутация: -  0  +


Собственно вот задание: Написать программу по разбивке и анализу содержимого файла отчета работы ПО (log-файла).
Необходимо проанализаровать и подсчитать запросы, а также вывести их в алфавитном порядке с подсчетом колическтва повторений.

Программа должна выдавать отчет о своей работе в виде:

Дата Запросы
25.04.2002 - 12
26.04.2002 - 10
27.04.2002 - 5
...

Всего было сделано (запросов) - 1679

Сортировка запросов:

Бухгалтерский учет - 25
Бухгалтерский журнал - 30
Экономика Томска - 6
Экономика Якутии - 1
...

Пример файла отчета работы программы wslog.txt
Сортировку запросов необходимо проводить по CGI-переменным
S21STR=
S21ALL=
Проблема в том что у меня во второй части программы (подсчет и сортировка самих текстовых запросов) переполняется массив... а вот как сделать без массива не пойму...


program Laba_2;
uses crt;
var
s2:string;
f,f1:text;
g:char;
a,x,i,j,q,p:integer;
zap,m:string;
n:array [1..1000] of byte;
zn:array [1..1000]of string[40];
s,s1:string[10];
begin
clrscr;
assign(f,'wslog.txt');
assign(f1,'output.txt');
reset(f);
rewrite(f1);
x:=0;
a:=0;
q:=0;
Readln(f,s1);
Repeat
Readln(f,s);
if (s<>s1) and (s1<>'') then {если строки не одинаковы,то считает кол-во запросов в день}
begin
Writeln(f1,s1,' - ',a);
x:=x+a;
a:=0;
s1:=s;
end
else a:=a+1;{иначе суммирует кол-во одинаковых строк}
until eof(f);
Writeln(f1,' vsego zaprosov :');
Writeln(f1,x);
Reset(f);
{S21STR}
Repeat
Readln(f,s2);
a:=pos('S21STR=',s2);
if a<>0 then
begin
a:=a+7;
zap:='';
if S2[a]='' then q:=q+1 else
Repeat
zap:=zap+s2[a]; {считывает послед.символы после 'S21STR=' до &}
a:=a+1;
Until s2[a]='&';
for i:=1 to 1000 do
begin
if zap=zn[i] then begin n[i]:=n[i]+1; break; end;
if zn[i]='' then begin zn[i]:=zap; inc(n[i]); break;
{считает кол-во запросов}
end;
end;
end;
until eof(f);

{S21ALL аналогично}

Repeat
Readln(f,s2);
a:=pos('S21ALL=',s2);
if a<>0 then
begin
a:=a+7;
zap:='';
if s2[a]='' then q:=q+1 else
Repeat
zap:=zap+s2[a];
a:=a+1;
Until s2[a]='&';
for i:=1 to 1000 do
begin
if zap=zn[i] then begin n[i]:=n[i]+1; break; end;
if zn[i]='' then begin zn[i]:=zap; inc(n[i]); break; end;
end;
end;
until eof(f);
{сортирует строки}
for i:=1000 downto 1 do
for j:=1 to i-1 do
if zn[j]>zn[j+1] then
begin {}
m:=zn[j+1]; p:=n[j+1];
zn[j+1]:=zn[j]; n[j+1]:=n[j];
zn[j]:=m; n[j]:=p;
end;
{выводит рез-ты в файл}
writeln(f1,' ',' ',q);{выводит кол-во пустых запрсов}
for i:=1 to 1000 do
if zn[i]<>'' then
writeln(f1,zn[i],' ',n[i]);
close(f);
close(f1);
end.


Прикрепленный файл  wslog.txt ( 408.21 килобайт ) Кол-во скачиваний: 544
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Да, я именно его имел в виду. Перекомпилируй свою программу в FPC с ключом {$H+} и увеличенным размером массивов (я сделал
const maxsize = 2000;
// ...
n:array [1..maxsize] of byte;
zn:array [1..maxsize]of string[40];
// и ниже по тексту все 1000 заменил на maxsize

), и чуть-чуть поправь вот этот цикл:

   a:=pos('S21ALL=',s2);
if a<>0 then
begin
a:=a+7;
zap:='';
if s2[a]='' then q:=q+1 else
Repeat
zap:=zap+s2[a];
a:=a+1;
Until s2[a]='&'; // <--- Вот это очень нехорошо...
, если в строке после S21STR не будет амперсанда - будет вылет опять же (такая строка - под номером 205 в твоем файле). Надо в Until добавить условие, чтоб проверялся конец строки:

   Until (a > length(s2)) or (s2[a]='&');
Ну, или запоминать в целочисленной переменной длину строки (чтоб каждый раз ее не вычислять), и сравнивать со значением этой переменной...

Убедись, что программа работает и выдает правильный результат. И когда результат будет правильным, таким, который тебе нужен, замени этот ужасный массив из нескольких тысяч элементов на что-нибудь типа TStringList, там тебе не придется бегать туда-сюда самописными циклами и проверять, есть ли "оно" уже в списке (для этого существуют специальные методы), и занимать это будет ровно столько места, сколько нужно, а не "с огромным запасом".

Хотя, по хорошему, и искать Pos-ом строки в FPC не нужно. Есть регулярные выражения, вытягивать из строки можно что хочешь и как хочешь.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 7.06.2024 20:18
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name