よろしくお願い致します。
VC++.NETのMFCで行っております。
下記のようにtest.INX形式のファイルがございます。
AAA,20040806123834,ABC1,71,1,0,0
BBB,20040806124025,ABC1,72,1,1,28160
CCC,20040806124048,ABC1,73,1,1,7743
DDD,20040806144036,ABC1,74,1,0,0
EEE,20040806144114,ABC1,75,1,0,0
各行毎に取得して
AAAを000
BBBを111
CCCを222
DDDを333
EEEを444
と始めの部分だけ変更したいのですが
各行はどのように取得すればよろしいでしょうか?
CStdioFileを調べてみましょう :-)
CStdioFile InxFile(InxPath, CFile::modeRead | CFile::typeBinary);
while(InxFile.ReadString(get) != 0){
sprintf(pbuf,%s,get); //CString→char
tok=strtok(pbuf,,);
get =tok;
}
まで行きました。
あとは書き込みですね。
横槍失礼m(__
CString を使ってるのだから、
int nToken = 0;
CString tok = get.Tokenize(_T(,),nToken);
か
get.Replace(置換される文字列,置換する文字列);
のが楽のような??
おかげさまできれいなソースになりました。
CStdioFile InxFile(InxPath, CFile::modeReadWrite | CFile::typeBinary);
while(InxFile.ReadString(get) != 0){
tok = get.Tokenize(_T(,),nToken);
get.Replace(tok,000);
InxFile.WriteString(get);
}
試しに上記のように行ってみました。
getの中身がAAA,20040806123834,ABC1,71,1,0,0
から000,20040806123834,ABC1,71,1,0,0
となりました。
ただここで躓いたのですが、取得した行を書き換えする処理と
2行目がうまく取得できません。
お手数ですがよろしくお願い致します。
CStdioFile InxFile(InxPath, CFile::modeReadWrite | CFile::typeBinary);
while(InxFile.ReadString(get) != 0){
tok = get.Tokenize(_T(,),nToken);
get.Replace(tok,000);
InxFile.SeekToBegin(); →追加
InxFile.WriteString(get);
}
当たり前ですが
InxFile.SeekToBegin();
を追加しましたら、1行目だけ書き換わりました。
ですが、2行目をどう書き換えたらいいか・・・。
取得した文字数分を先頭からSeek(len,CStdioFile::current)
するのでしょうか?
CStdioFile InxFile(InxPath, CFile::modeReadWrite | CFile::typeBinary);
InxFile.SeekToBegin();
while(InxFile.ReadString(get) != 0){
int nToken = 0;
tok = get.Tokenize(_T(,),nToken);
get.Replace(tok,AAA);
int len = get.GetLength();
length = length + len + 1;
InxFile.Seek(length,CStdioFile::begin);
}
InxFile.Close();
すべてAAAに変換されますが、なんとか出来ました。
でももっときれいな書き方はあるのでしょうか?
何度も申し訳ございません。
CStdioFile InxFile(InxPath, CFile::modeReadWrite | CFile::typeBinary);
while(InxFile.ReadString(get) != 0){
int nToken = 0;
tok = get.Tokenize(_T(,),nToken);
get.Replace(tok,AAA);
InxFile.WriteString(get);//->???
int len = get.GetLength();
length = length + len + 1;
InxFile.Seek(length,CStdioFile::begin);
}
EEE,20040806144114,ABC1,75,1,0,0
の行で
InxFile.WriteString(get);//->???
でアクセス中にディスクがいっぱいになりましたと
起こられました。
なんでしょうか?
とりあえず、元ファイルをそのまま書き直すのはあまりお勧めできないかな~?
私なら、一旦テンポラリファイルに出力して、変換後リネームとかかな~
小さなファイルなら、メモリに変換しながらロードして、最後に一気に書き出すとか~
-----
#include atlfile.h
CStdioFile InxFile(InxPath, CFile::modeRead|CFile::typeText);
CAtlTemporaryFile tempxFile;
ATLVERIFY(tempxFile.Create(NULL,GENERIC_WRITE)==S_OK);
while(InxFile.ReadString(get)){
// ここで置換処理を行う
// ここから書き込み処理
int nWrite;
get += _T(\n); // <-改行消えてるので足す
tempxFile.Write(get.GetBuffer(),get.GetLength(),&nWrite);
}
InxFile.Close(); // <-閉じてしまう
// もしかしたら、元ファイルを一旦消さないとだめかも?
ATLVERIFY(tempxFile.Close(InxPath)==S_OK); // <-リネームコピーしてくれる
-----
とかかな~?
これはテンポラリファイル使う場合ね
# コンパイルしてないから通るかわからないけど・・・(^^;
あいるさんありがとうございます。
実は、マルチ投稿になっておりますので、続きの質問は下記に致します。
お手数ですが、お時間あれば下記の所をみていただけませんでしょうか?
VC++超初心者会議
http://www.interq.or.jp/gold/marken/bbs.htm
あいるさんの処理を参考に話を進めていきたいと思います。
ありがとうございました。