私は、(行ごとに)char、space、char、space、double値、endlineといった指定された構造のテキストファイルを持っています。たとえば、FreePascalでファイルを読む
q w 1.23
e r 4.56
t y 7.89
Free Pascalでこれらの値を「抽出する」適切な方法はありますか?
私は、(行ごとに)char、space、char、space、double値、endlineといった指定された構造のテキストファイルを持っています。たとえば、FreePascalでファイルを読む
q w 1.23
e r 4.56
t y 7.89
Free Pascalでこれらの値を「抽出する」適切な方法はありますか?
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.
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.
のは、我々は文字の置換重みを含むスイッチの後のコマンドライン引数によって提供されるファイルを、読むことに興味を持っているとしましょう。より一般的な設定で
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.
注意。または、単語区切り文字にする。
安全でない構文を使用します。 (たとえば、コンパイルしますが、stringがshortstringでない場合は失敗します)。これをお勧めしません(初心者や専門家の方) –
@MarcovandeVoort SScanFを正しく使用する方法を教えてください。 – SOUser