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

Вниз

Работа с файлами.   Найти похожие ветки 

 
Ольга   (2003-04-03 20:11) [0]

Есть файл в текстовом формате, представляющий собой три колонки чисел (количество цифр в каждом числе неодинаковое), этот файл получен из Excel"a, сохраненный в формате txt. Нужно выбрать из этого файла только средний столбец и записать его в отдельный файл. Как выбрать именно средний столбец?


 
Smashich   (2003-04-03 20:14) [1]

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


 
Palladin   (2003-04-03 20:35) [2]


function GetSubStr(sStr:string;sSep:char;n:integer):string;
var
i:integer;
begin
try
result:="";
for i:=1 to n-1 do sStr:=copy(sStr,pos(sSep,sStr)+1,length(sStr));
if pos(sSep,sStr)<>0 then result:=copy(sStr,1,pos(sSep,sStr)-1)
else result:=sStr;
except
raise ERangeError.Create("GetSubStr");
end;
end;

procedure ВыдратьСредницСтолбец;
var
СреднийСтолбец,
ТриСтолбца:TStringList;
i:integer;
begin
СреднийСтолбец:=TStringList.Create;
ТриСтолбца:=TStringList.Create;
ТриСтолбца.LoadFromFile("ТриСтолбца.txt");
for i:=0 to ТриСтолбца.Count-1 do
СреднийСтолбец.Add(GetSubStr(ТриСтолбца[i],#9,2));
ТриСтолбца.Free;
СреднийСтолбец.SaveToFile("СреднийСтолбец.txt");
СреднийСтолбец.Free;
end;

------
дерзайте


 
Mike Kouzmine   (2003-04-03 20:35) [3]

А ты сохрани его в дбф и среднее поле пиши в текстовый файл


 
Smashich   (2003-04-03 20:58) [4]

2 Mike Kouzmine © (03.04.03 20:35)

не отчаивайся!;)


 
Mike Kouzmine   (2003-04-03 21:09) [5]

Спасибо, друг.


 
panov   (2003-04-03 21:44) [6]

>Ольга
Аккуратнее в следующий раз.
вот ссылка на предыдущий постинг:
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1049298049&n=3

а вот еще одно довольно простое решение:

procedure TForm1.Button1Click(Sender: TObject);
var
tL,tL1: TStringList;
index: Integer;
begin
tL := TStringList.Create;
tL1 := TStringList.Create;
tL.LoadFromFile("3col.txt");
try
for index := 0 to tL.Count-1 do
begin
tL1.Text := StringReplace(tL[index],#9,#13#10,[rfReplaceAll]);
try
tL[index] := tL1[1];
except
end;
end;
finally
tL.SaveToFile("1col.txt");
tL.Free;
tL1.Free;
end;
end;



 
Palladin   (2003-04-03 21:52) [7]

решений много... главное подумать...
но вот только для чего это? неужели нельзя сразу сохранять среднюю?


 
Ольга   (2003-04-04 19:31) [8]

Спасибо за участие!
Вот только сразу сохранить среднюю, как предлагает Palladin, нельзя, файл формируется из трех колонок :-(


 
Palladin   (2003-04-04 19:38) [9]

вот ты... неразумная
в код вдумайся
я тебе не предлагал вообще ничего никуда сохранять...
я тебе пример для разборки написал...
делай ты с это колонкой средней что хочешь... хоть в paintbrush"е рисуй...

или объясняй конкретней задачу!
у тебя выходной файл с тремя колонками должен быть или на входе у тебя три колонки... и чем они вообще разделяются...

тут не телепаты...


 
Ольга   (2003-04-06 13:26) [10]

Извиняюсь!
Короче, на входе файл из трех колонок цифр, разделение между первой и второй колонкой - одинарная табуляция, а между второй и тетьей колонкой - двойная табуляция, строки разделены enter-ом. Но вот в чем проблема, не в каждой строчке в тертьем столбце есть цифра, то есть:
20 250 266
22 23 36,5
10 3
19 42 18,4
1 2
99999 999 100


и так далее, без какой либо системы чередования пустых мест в третьей колонке.
Так вот из этой галиматьи нужно выбрать именно второй столбик, и записать его нужно в один файл, а третий столбик - в другой файл.
И еще один момент, что такое TStringList , как его описать? и где это лежит?


 
Palladin   (2003-04-06 14:19) [11]

значит для второго столбца можешь использовать первое мое рещение или решение panov © (03.04.03 21:44)
для второго файла нужно немножко изменить первое решение


function GetSubStr(sStr:string;sSep:char;n:integer):string;
var
i:integer;
begin
try
result:="";
for i:=1 to n-1 do sStr:=copy(sStr,pos(sSep,sStr)+1,length(sStr));
if pos(sSep,sStr)<>0 then result:=copy(sStr,1,pos(sSep,sStr)-1)
else result:=sStr;
except
raise ERangeError.Create("GetSubStr");
end;
end;

procedure ВыдратьПоследнийСтолбец;
var
ПоследнийСтолбец,
ТриСтолбца:TStringList;
i:integer;
begin
СреднийСтолбец:=TStringList.Create;
ТриСтолбца:=TStringList.Create;
ТриСтолбца.LoadFromFile("ТриСтолбца.txt");
for i:=0 to ТриСтолбца.Count-1 do
if GetSubStr(ТриСтолбца[i],#9,3)<>"" then ПоследнийСтолбец.Add(GetSubStr(ТриСтолбца[i],#9,3));
ТриСтолбца.Free;
СреднийСтолбец.SaveToFile("ПоследнийСтолбец.txt");
СреднийСтолбец.Free;
end;


TStringGrid можно найти в справке (unit classes)
бери словарик и вперед...


 
Morfein   (2003-04-06 21:07) [12]

>> Ольга
А разделители в строке постоянные?
Т.е. всегда идёт посл. число-[TAB]-число-[TAB]-[TAB]-число?
Или вместе с [TAB] попадается ещё чё-нить?


 
Ольга   (2003-04-07 05:19) [13]

Разделителем является только ТАВ, один или два, причем, если в третьем столбике нет числа, табы все равно есть...


 
Ольга   (2003-04-10 20:28) [14]

Не получается, пишет в файл всяку-бяку, а не то, что нужно.
Что еще можно придумать?


 
Palladin   (2003-04-10 20:34) [15]

брось это грязное дело...


 
panov   (2003-04-10 21:46) [16]

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


procedure TForm1.Button1Click(Sender: TObject);
function ReplTab(const aStr: String): String;
var
i,EndPos: Integer;
begin
Result := "";
EndPos := 0;

for i := 1 to Length(aStr) do
begin
if aStr[i] = #9 then
begin
if (EndPos>0) and (Result[EndPos]<>#10) then
begin
Result := Result + #13#10;
Inc(EndPos,2);
end
else continue;
end
else
begin
Result := Result + aStr[i];
Inc(EndPos);
end;
end;
end;

var
tL,tL1: TStringList;
index: Integer;
begin
tL := TStringList.Create;
tL1 := TStringList.Create;
tL.LoadFromFile("3col.txt");
try
for index := 0 to tL.Count-1 do
begin
tL1.Text := ReplTab(tL[index]);
try
tL[index] := tL1[1];
except
end;
end;
finally
tL.SaveToFile("1col.txt");
tL.Free;
tL1.Free;
end;
end;


 
Fantasist.   (2003-04-11 22:27) [17]

Не! Надо писать как проффессионалы. :)



TFileNumParserTokenKinds=(tkNum,tkSpace, tkEol, tkEof);

TFileNumParser=class
private
fStream:TStream;
fChar:char;
fCurTokenKind:TFileNumParserTokenKinds;
public
fCurToken:string;
public
procedure LoadFromFile(FileName:string);
function getNext:TFileNumParserTokenKinds;
function getNum:integer;
function nextChar:char;
end;

implementation


procedure TFileNumParser.LoadFromFile(FileName:string);
begin
fStream:=TFileStream.Create(fileName,mfRead);
end;

function TFileNumParser.getNext:TFileNumParserTokenKinds;
var
c:char;

procedure RunSpace;
begin
while NextChar in [" ",#9] do;
fCurTokenKind:=tkSpace;
end;

procedure RunNumber;
begin
while NextChar in ["0".."9"] do;
fCurTokenKind:=tkNumber;
end;

procedure RunEol;
begin
while NextChar in [#10,#13] do;
fCurTokenKind:=tkEol;
end;

begin
fCurToken:="";
case fChar of
" ",#9: RunSpace;
"0".."9": RunNumber;
#13,#10: RunEol;
#0: fCurTokenKind:=tkEof;
else
raise Exception.Create("Unexpected symbol "+fChar)
end;
Result:=fCurTokenKind;
end;

function TFileNumParser.NextChar:char;
begin
//в конструкторе предпологается сделать fChar:=0; NextChar;
if fChar<>#0 then
fCurToken:=fCurToken+fChar;

if fStream.Position<fStream.Size then
fStream.ReadBuffer(Result,1)
else
fChar:=0;

fChar:=Result;
end;

procedure ProcessFile(FileName:string);
var
prs:TFileNumParser;
colNum:integer;
begin
colNum:=0;
with TFileNumParser.Create do
begin
try
repeat
case getNext of
tkEol: colNum:=0;
tkNumber:
begin
inc(colNum);
if colNum=2 then ProcessSecondRow(IntToStr(fCurToken));
end;
tkSpace:;
tkEof:exit;
end;
until false;
finally
Free;
end;
end;
end;



Ну надо, конечно, оптимизировать, доработать маленько.


 
AlexSV   (2003-04-12 11:08) [18]


> Ольга (07.04.03 05:19)
> Разделителем является только ТАВ, один или два, причем, если в третьем столбике нет числа, табы все равно есть


Рискну предлодить и свой скромный вариант:
procedure GetColFromList(InFile, OutFile: string; NeedCol: integer);
// InFile - файл с темя колонками
// OutFile - файл, куда пишем результат
// NeedCol - номер желаемой колонки
var
InFilesl, Rowsl, OutFilesl: TStringList;
RowCnt: integer;
tmpStr: string;
begin
InFilesl := TStringList.Create;
Rowsl := TStringList.Create;
OutFilesl := TStringList.Create;
try
InFilesl.LoadFromFile(InFile);
for RowCnt := 0 to InFilesl.Count - 1 do begin
tmpStr := InFilesl.Strings[RowCnt];
tmpStr := StringReplace(tmpStr, #9#9, "","", [rfReplaceAll]);
tmpStr := """ + StringReplace(tmpStr, #9, "","", [rfReplaceAll])+ """;
Rowsl.Clear;
Rowsl.CommaText := tmpStr;
OutFilesl.Add(Rowsl.Strings[NeedCol-1]);
end;
OutFilesl.SaveToFile(OutFile);
finally
InFilesl.Free;
Rowsl.Free;
OutFilesl.Free;
end;
end;

Как с этим работать:
procedure TForm1.Button1Click(Sender: TObject);
begin
GetColFromList("col3.txt", "Res.txt", 2);
end;



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

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

Наверх





Память: 0.5 MB
Время: 0.008 c
3-76845
td
2003-04-07 23:57
2003.04.24
запрос с условием


3-76752
Юный_программер
2003-04-04 10:53
2003.04.24
что значит ошибка: BOF или EOF имеет значение True, либо текущая


3-76851
Abrams
2003-04-08 09:10
2003.04.24
BDE


6-77057
AlexeyBykov
2003-02-27 20:08
2003.04.24
Организация многопотоковой докачки файлов по локальной сети


7-77200
Demon
2003-03-07 15:58
2003.04.24
Как выгрузить процесс?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский