Показать полную графическую версию : Обработчик строк из текстового файла
pageYK@fb
02-08-2016, 16:37
Есть файл с текстом формата(разделитель '|'):
1|325230ш5ш3|438|Лондон|ЛОНДОН, ВЕЛИКОБРИТАНИЯ|
2|32523лпукп4|22|Европа|ДУБЛИН, ИРЛАНДИЯ|
3|32епкупщ4пп|21|Венгрия|БУДАПЕШТ, ВЕНГРИЯ|
Нужно пропарсить его
(
1. Если в 3-ем числе >394, то вычитаем из него 394(строку дублируем),остаток оставляем новой строкой.(учесть, что операция должна быть циклична, т.к. встречаются числа больше 792)
2. Отсортировать строки по 3-ему числу. (1-ое число - счетчик)
)
, чтобы на выходе получилось это:
1|32епкупщ4пп|21|Венгрия|БУДАПЕШТ, ВЕНГРИЯ|
2|32523лпукп4|22|Европа|ДУБЛИН, ИРЛАНДИЯ|
3|325230ш5ш3|46|Лондон|ЛОНДОН, ВЕЛИКОБРИТАНИЯ|
4|325230ш5ш3|394|Лондон|ЛОНДОН, ВЕЛИКОБРИТАНИЯ|
pageYK@fb, в чем возникла проблема?
Где рассуждения?
lxa85, «рассуждения» были здесь: CMD/BAT - [решено] обработка в подстроке (http://forum.oszone.net/thread-317218.html).
pageYK@fb
03-08-2016, 17:47
lxa85, рассуждениями поделились ссылочкой выше.
А так затык, в основном, как в Delphi индентифицировать в строке это третье число, delimited опробовал, не зашло.
delimited опробовал, не зашло. »
Ну, так показывайте, как именно опробовали.
А так затык, в основном, как в Delphi индентифицировать в строке это третье число, delimited опробовал, не зашло. »
А что если написать функцию разделения строки по типу питоновской split или пхпшной explode? Примерно так:
function split(splitter: Char; str: String): TStringList;
var substr: String;
var parts: TStringList;
var i: Integer;
begin
parts := TStringList.Create;
for i := 1 to Length(str) do
begin
if str[i] = splitter then
begin
parts.add(substr);
substr := '';
end else
substr := substr + str[i];
end;
parts.add(substr);
result := parts;
end;
Соответственно, на выходе имеем TStringList, где третье число - parts[2]. Ну а дальше в Integer преобразовать проще простого:
var value: Integer;
...
value := StrToInt(parts[2]);
P.S. 100 лет не писал на Delphi, уж простите, если накосячил.
Вся "работа" вокруг анализа одной "колонки"... не нужно что-то выдумывать. Для выделения подстроки в Delphi все есть
const
str = '1|325230ш5ш3|438|Лондон|ЛОНДОН, ВЕЛИКОБРИТАНИЯ|'; // для примера одна строка
var
sl: TStringList;
begin
sl := TStringList.Create;
begin
try
ExtractStrings(['|', ','], [' '], str, sl); // Note: ExtractStrings does not add empty strings to the list.
ShowMessage(sl[2]);
finally
sl.Free;
end;
end;const
str = '1|325230ш5ш3|438|Лондон|ЛОНДОН, ВЕЛИКОБРИТАНИЯ|';
var
i: Integer;
begin
with TStringList.Create do
begin
Delimiter := '|';
StrictDelimiter := True;
DelimitedText := str;
{for i := 0 to Count - 1 do
ShowMessage(Strings[i]);}
ShowMessage(Strings[2]);
Free;
end;все остальные действия от обработки результата.
pageYK@fb
04-08-2016, 14:24
Из вышестоящего, собрал вот такой кусок:
var
i,l:integer;
ts:TStringList;
s: string;
begin
ts := TStringList.Create;
try
ts.LoadFromFile('1.txt');
Delimiter := '|';
StrictDelimiter := True;
DelimitedText := ts;
for l:=0 to ts.Count-1 do
begin
value := StrToInt(ts.Strings[2]);
while value>394 do
begin
value := value-394;
ts.Strings[2]:=IntToStr('394');
// Как передать обновленную строку в файл?
end;
ts.Strings[2]:=IntToStr(value);
// передача строки в файл с остатком.
end;
// сортировка
finally
ts.Free;
end;
end.
Как прописать запись строки в файл из цикла, через append?
Как прописать запись строки в файл из цикла, через append? »Разве методов TStringList (add, insert, delete и прочих, для выполнения задачи, не хватает? Вариантов много, можно вообще все сделать в TSL (например, копирование нужной строки в конец списка add() с заменой подстроки StringReplace) и сохранением в файл SavetoFile.
pageYK@fb
08-08-2016, 11:03
opel431, Методов хватает, работает не так как надо.
var
i,l,value:integer;
ts:TStringList;
s: string;
begin ts := TStringList.Create;
try
ts.LoadFromFile('1.txt');
ts.Delimiter := '|';
for l:=0 to ts.Count-1 do
begin
ts.DelimitedText := ts.Strings[l];
value := StrToInt(ts.Strings[2]);
while value>394 do
begin
value := value-394;
ts.Strings[2]:='394';
ts.SaveToFile('2.txt');
end;
end;
finally
ts.Free;
end;
SaveToFile по итогу, возвращает в файл текст уже разбитый на подстроки:
"1
325230ш5ш3
438
Лондон
ЛОНДОН,
ВЕЛИКОБРИТАНИЯ".
И как оперировать с несколькими строками для их сортировки так мне осталось неясным.
Методов хватает, работает не так как надо. »Инструментов под рукой нет, но на вскидку - вы же заперли сохранение в цикл вычислений
while value>394 do
begin
...
...
??? ts.SaveToFile('2.txt');
end;
да и никто вас не ограничивает работой с одним списком?
pageYK@fb
08-08-2016, 14:36
opel431,
Проблема заключается в том, что делиметр разделяет строку на подстроки, а как обратно конкатенировать для записи в файл непонятно.
pageYK@fb, есть строка, разбитая на под строки.
Что вам мешает собрать ее обратно?
Если у вас формат файла фиксирован, то и собирайте в цикле
str = "";
for i = 1 to n do
str = str+"|"+delimiters[i];
Соотв n - кол-во частей строк
delimiters - полученный "конструктор" подстрочек
str - результирующая строка
opel431, lxa85, а какого-нибудь аналога basic'овского «Join()» в Delphi нету разве?
pageYK@fb
08-08-2016, 15:58
lxa85, opel431,
Строки разбиваются (при delimiter = "|") на отделяемое запятыми тоже, поэтому обратно приведенным вами способом не соберешь.
Вот почему мне не нравится этот метод через делимитедтекст.
Поэтому прошу выкладывать решение, а не функцию которую можно применить.(уже n-раз выходит, что возникают только доп.вопросы)
Iska, честно, не знаю :)
pageYK@fb, что значит "не соберешь"?
Что отладчик говорит? Что говорят watchdog'и?
Что в полученных структурах, что на выходе?
Вы хоть какую-то информацию к размышлениям давайте.
Встроенного аналога, с параметром разделителя, не нашел (есть обычная Concat), заменяющая +. Так что, или ее или ручками.
pageYK@fb, нужно с интересом подходить к своей задаче. Поковыряюсь параллельно с вами.
Поставил триальный XE4, нашел в справочнике функцию SplitString (функция есть, как минимум с XE) и .... Для наглядность, применил TMemo.
pageYK@fb, дальнейшие "телодвижения" (сортировка, адаптация, оптимизация и все, что вам требуется, делайте сами).
......
var
Form1: TForm1;
ts: TStringList;
......
procedure TForm1.Button1Click(Sender: TObject);
var
i, n, value: integer;
begin
if FileExists(ExtractFilePath(Application.ExeName) + '1.txt') then
begin
ts := TStringList.Create;
try
ts.LoadFromFile(ExtractFilePath(Application.ExeName) +'1.txt');
for i := 0 to ts.Count - 1 do
begin
value := StrToInt((SplitString(ts.Strings[i], '|')[2]));
n := StrToInt(SplitString(ts.Strings[i], '|')[0]);
if value > 394 then
Memo1.Lines.Add(IntToStr(n) + '|' + (SplitString(ts.Strings[i], '|')[1])
+ '|' + IntToStr(value) + '|' + (SplitString(ts.Strings[i], '|')[3]) +
'|' + (SplitString(ts.Strings[i], '|')[4]) + '|');
while value > 394 do
begin
value := value - 394;
end;
n := StrToInt(SplitString(ts.Strings[i], '|')[0]) + 1;
Memo1.Lines.Add(IntToStr(n) + '|' + (SplitString(ts.Strings[i], '|')[1]) +
'|' + IntToStr(value) + '|' + (SplitString(ts.Strings[i], '|')[3]) + '|'
+ (SplitString(ts.Strings[i], '|')[4]) + '|');
end;
finally
Memo1.Lines.SaveToFile(ExtractFilePath(Application.ExeName) +'2.txt');
FreeAndNil(ts);
end;
end;
end;Результат
1|325230ш5ш3|438|Лондон|ЛОНДОН, ВЕЛИКОБРИТАНИЯ|
2|325230ш5ш3|44|Лондон|ЛОНДОН, ВЕЛИКОБРИТАНИЯ|
3|32523лпукп4|22|Европа|ДУБЛИН, ИРЛАНДИЯ|
4|32епкупщ4пп|21|Венгрия|БУДАПЕШТ, ВЕНГРИЯ|
pageYK@fb
11-08-2016, 12:22
opel431,
Спасибо за splitstring, а memo работает только на кнопке, была бы привязка к форме. Спасибо, и на этом.
а memo работает только на кнопке »Форма имеет достаточно обработчиков событий для решения ваших желаний.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.