stringlistでのテキストファイル処理について

解決


なっちん  2013-04-25 14:31:01  No: 44450  IP: 192.*.*.*

var
  slst : TStringList;
  i : Integer;
  s : String;
begin
  slst := TStringList.Create;
  slst.LoadFormFile('処理するファイルパス');

  for i := 0 to slst.Count -1 do begin
    s := slst[i];
    {sの処理}
  end;

  slst.Free;
end;

上記のようにstringlistにテキストファイルを読み込ませてます。
テキストファイルは固定長のファイルです。
最終行まで問題なく書込がされているファイルでしたら、
全く問題ないのですが、

内容最終行に1行余計な行がプラスされている状態(1バイトスペース)で
読み込むと、
なぜか3万数行あるはずが168行しか読み込みません。
件数はstringlist.countです。

回避方法があれば教えていただきたくお願いします。

ちなみに
AssignFile(tf, '処理するファイルパス');
Reset(tf);
の方法でしたら、問題なく読込出来ました。

編集 削除
なっちん  2013-04-25 15:29:19  No: 44451  IP: 192.*.*.*

1バイトスペースと書きましたが、最終行に改行コードのみ入ってました。

編集 削除
なっちん  2013-04-25 18:54:13  No: 44453  IP: 192.*.*.*

もな様

ご確認ありがとうございました。

ファイルを見てましたら、'#0'というコードがございまして、
SQLでInsertしているのですが、クエリの中がシングルクォーテーションが入っているために、クエリが正常ではなくなっていたようです。

ステップ実行で見てみると
「あい'#0'&あい」という具合です。文字化けによるものかもしれません。

とりあえず、'#0'を取りたいのですが、これはこれで悩んでます。

編集 削除
もな  2013-04-26 10:43:04  No: 44454  IP: 192.*.*.*

こんな感じでどうでしょうか?
ですが、本来なら何故そこに'#0'が入っているのかを調べたほうが良いと思います。
'&'が制御文字なんですかね?にしても'#0'をその前に入れるもんなのか?
DB関連は全くの素人なのでそのへん私ではフォローしかねます。

procedure CharReplace(var aSrcStr:string; const aOldChar,aNewChar:Char);
var
  aPChar: PChar;
  i,aLen: Integer;
begin
  aLen := Length(aSrcStr);
  if aLen=0 then Exit;
  aPChar := @aSrcStr[1];
  for i := 1 to aLen-1 do
  begin
    if aPChar^ = aOldChar then
      aPChar^ := aNewChar;
    inc(aPChar);
  end;
  if aPChar^ = aOldChar then
    aPChar^ := aNewChar;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  aStr:string;
begin
  aStr := '0123'+#0+'456';

  ShowMessage(aStr);
  ShowMessage(Format('長さ:%d',[Length(aStr)]));

  //aStr := StringReplace(aStr,#0,'?',[rfReplaceAll]);
  CharReplace(aStr,#0,'?');
  ShowMessage(aStr);
  ShowMessage(Format('長さ:%d',[Length(aStr)]));

end;

編集 削除
もな  2013-04-26 11:08:07  No: 44455  IP: 192.*.*.*

先程の関数を少し書きなおししました。
よろしければ参考にどうぞ。

procedure CharReplace(var aSrcStr:string; const aOldChar,aNewChar:Char);
var
  aPChar: PChar;
  i,aLen: Integer;
begin
  aLen := Length(aSrcStr);
  if aLen=0 then Exit;
  aPChar := @aSrcStr[1];
  for i := 1 to aLen-1 do
  begin
    if aPChar^ = aOldChar then
      aPChar^ := aNewChar;
    inc(aPChar);
  end;
  if aPChar^ = aOldChar then
    aPChar^ := aNewChar;
end;

procedure CharReplaceS(var aSrcStr:string; const aOldChar,aNewChar:Char);
var
  i,aLen: Integer;
begin
  aLen := Length(aSrcStr);
  if aLen=0 then Exit;
  for i := 1 to aLen do
  begin
    if aSrcStr[i] = aOldChar then
      aSrcStr[i] := aNewChar;
  end;
end;

function CharRemove(const aSrcStr:string; const aOldChar:Char):string;
var
  aPSrc,aPDst: PChar;
  i,c,aLen: Integer;
begin
  aLen := Length(aSrcStr);
  SetLength(Result,aLen);
  if aLen=0 then Exit;
  aPSrc := @aSrcStr[1];
  aPDst := @Result[1];
  c := 0;
  for i := 1 to aLen-1 do
  begin
    if aPSrc^ <> aOldChar then
    begin
      aPDst^ := aPSrc^;
      inc(aPDst);
      inc(c);
    end;
    inc(aPSrc);
  end;
  if aPSrc^ <> aOldChar then
    inc(c);
  SetLength(Result,c);
end;

function CharRemoveS(const aSrcStr:string; const aOldChar:Char):string;
var
  i,c,aLen: Integer;
begin
  aLen := Length(aSrcStr);
  SetLength(Result,aLen);
  if aLen=0 then Exit;
  c := 0;
  for i := 1 to aLen do
  begin
    if aSrcStr[i] <> aOldChar then
    begin
      c := c+1;
      Result[c] := aSrcStr[i];
    end;
  end;
  SetLength(Result,c);
end;

編集 削除
なっちん  2013-04-26 13:28:33  No: 44456  IP: 192.*.*.*

もな様

ソースありがとうございました!
問題なく変換できました。ありがとうございます。

@aSrcStrのあたりの手法は、今まで書いたことがないので、
この機会に勉強させて頂きます。

元々のテキストファイルは、
NECのオフコンのデータベースをツールを使用して作成されたものです。
私はオフコンには詳しくないので、
開発者に聞いてみても、
なぜそんな風に落ちてくるのかわからない、との回答でした。
たぶん外字ではないか、とかです。

何から何までありがとうございました。

編集 削除
なっちん  2013-04-26 14:35:04  No: 44457  IP: 192.*.*.*

解決忘れてました。

編集 削除
管理人(papy)  2013-04-26 18:00:00  No: 44452  IP: 192.*.*.*

★★★ 管理人よりお知らせ ★★★

大変、申し訳ありません。
「掲示板あらし」の修正作業で誤ってこの部分の書き込みを削除してしまいました。
バックアップがありませんので復旧不可能となります。すみませんです><。

以後、慎重に修正致します。

編集 削除