2012-03-22 11 views
4

私は、(行ごとに)char、space、char、space、double値、endlineといった指定された構造のテキストファイルを持っています。たとえば、FreePascalでファイルを読む

q w 1.23 
e r 4.56 
t y 7.89 

Free Pascalでこれらの値を「抽出する」適切な方法はありますか?

答えて

2

TStringListクラスを使用してファイルをロードし、プロパティを使用して別のTStringListの値を分割し、その値をレコードに格納することができます。

チェックこのサンプル

{$mode objfpc}{$H+} 

uses 
    Classes, SysUtils; 

{$R *.res} 

type 
    TData=record 
    Val1: Char; 
    Val2: Char; 
    Val3: Double; 
    end; 

procedure ProcessFile; 
var 
    LFile : TStringList; 
    Line : TStringList; 
    i  : Integer; 
    LData : TData; 
    LFormat: TFormatSettings; 
begin 
    //set the propert format for the foat values 
    LFormat:=DefaultFormatSettings; 
    LFormat.DecimalSeparator:='.'; 

    LFile:=TStringList.Create; 
    Line :=TStringList.Create; 
    try 
    //load the file 
    LFile.LoadFromFile('C:\Bar\Foo\Data.txt'); 
    Line.Delimiter:=' '; 
    for i:=0 to LFile.Count-1 do 
    begin 
     //read the line and split the result 
     Line.DelimitedText:=LFile[i]; 
     //some basic check 
     if Line.Count <> 3 then raise Exception.Create('Wrong data length'); 

     //you can add additional check here  
     LData.Val1:=Line[0][3]; 
     LData.Val2:=Line[1][4]; 
     LData.Val3:=StrToFloat(Line[2],LFormat); 

     //do something with the data 
     WriteLn(LData.Val1); 
     WriteLn(LData.Val2); 
     WriteLn(LData.Val3); 
    end; 
    finally 
    Line.Free; 
    LFile.Free; 
    end; 
end; 

begin 
try 
    ProcessFile; 
except on E:Exception do Writeln(E.Classname, ':', E.Message); 
end; 
Writeln('Press Enter to exit'); 
Readln; 
end. 
4

FreePascalとはsysutilsの中の関数のsscanfを持っている(他の言語からの場合は、知っているかもしれません。)

私はそれを使用する方法を示すことRRUZの例を変更しました。

uses SysUtils; 

type 
    TData=object 
    Val1 , 
    Val2 : String; 
    Val3 : Double; 
    end; 

procedure ProcessFile(aFileName:String); 
var 
    F  : Text; 
    LData : TData; 
    Line : String; 
begin 
    DecimalSeparator:='.'; 
    AssignFile(F,aFileName); 
    Reset(F); 
    while not eof(F) do 
    begin 
    ReadLn(F,Line); 
    SScanf(Line,'%s %s %f',[@LData.Val1,@LData.Val2,@LData.Val3]); 

    //do something with the data 
    WriteLn(LData.Val1); 
    WriteLn(LData.Val2); 
    WriteLn(LData.Val3); 
    end; 
end; 

begin 
    ProcessFile('C:\Bar\Foo\Data.txt'); 
    Writeln('Press Enter to exit'); 
    Readln; 
end. 
+1

安全でない構文を使用します。 (たとえば、コンパイルしますが、stringがshortstringでない場合は失敗します)。これをお勧めしません(初心者や専門家の方) –

+1

@MarcovandeVoort SScanFを正しく使用する方法を教えてください。 – SOUser

1

のは、我々は文字の置換重みを含むスイッチの後のコマンドライン引数によって提供されるファイルを、読むことに興味を持っているとしましょう。より一般的な設定で

program WeightFileRead; 
uses SysUtils, StrUtils; 
var 
    MyFile : TextFile; 
    FirstChar, SecondChar, DummyChar : Char; 
    Weight : Double; 
begin 
    if GetCmdLineArg ('editweights', StdSwitchChars) = '' 
    then begin 
     WriteLn ('Syntax: WeightFileRead -editweights filename'); exit 
    end; 
    AssignFile (MyFile, GetCmdLineArg ('editweights', StdSwitchChars)); 
    Reset (MyFile); 
    try 
     while not EOF (MyFile) do 
     begin 
     ReadLn (MyFile, FirstChar, DummyChar, SecondChar, Weight); 
     WriteLn ('A: ', FirstChar, '; B: ', SecondChar, '; W: ', Weight:0:1); 
     end 
    finally 
     CloseFile (MyFile) 
    end 
end. 

最初の2つのエントリが長い文字列とすることができる場合、我々は、導入として一緒にいくつかの空白を扱う文字列でn番目の空白区切り単語を発見ExtractWord(又はExtractSubstrを使用することができ空の単語)、そして3番目の数字を数字に変換します。私はしたくないので、私は、[' ']はなくStdWordDelims使用

program WeightFileRead2; 
uses SysUtils, StrUtils; 
var 
    MyFile : TextFile; 
    FileLine : String; 
begin 
    if GetCmdLineArg ('editweights', StdSwitchChars) = '' 
    then begin 
     WriteLn ('Syntax: WeightFileRead -editweights filename'); exit 
    end; 
    AssignFile (MyFile, GetCmdLineArg ('editweights', StdSwitchChars)); 
    Reset (MyFile); 
    try 
     while not EOF (MyFile) do 
     begin 
     ReadLn (MyFile, FileLine); 
     WriteLn ('A: ', ExtractWord (1, FileLine, [' ']), 
        '; B: ', ExtractWord (2, FileLine, [' ']), 
        '; W: ', StrToFloat (ExtractWord (3, FileLine, [' '])):0:1); 
     end 
    finally 
     CloseFile (MyFile) 
    end 
end. 

注意。または、単語区切り文字にする。