VisualStudio2005, MFC, WinXP
以下の三行のテキストファイルのデータを画面に表示しています。(番号、名前、日付、
個数)
01田中08030511
02鈴木08030511
03山田08030522
行データの最後の個数が11なら99に上書きし、テキストファイルを書き替えたい。
void CXXXView::OnTest()
{
CString filename, textdata;
filename.Format(C:\\testdata\\test.txt);
CFileException e;
CStdioFile file;
file.Open(filename, CFile::modeRead|CFile::shareDenyNone, &e);
while(file.ReadString(textdata))//※
{
textdata.Replace(11, 99);//11を99に書き換え
file.WriteString(textdata);
file.Close();
}
}
実行するとエラーで落ちてしまいます。
ブレークポイント置いてみると、※の行でエラーになるようです。
元のテキストファイルのデータを上書きできるようにしたいのですが、よろしくお願い
します。
>file.Open(filename, CFile::modeRead|CFile::shareDenyNone, &e);
リードモードでは書き込みできませんよね?
file.Close();
をしているのにReadStringしているからでは?
2週目で落ちてそうな感じです。
ReadStringした時点でファイルポインタが
03山田08030522
→ココ
にきませんか?
うまく動作してもこれだと追記されるだけっぽいですけど。
Blueさん、
modeWriteに変更すれば大丈夫なのでしょうか。今は手元で動作確認できないので確認し
てみます。
とさん、
確かに二週目で落ちてました。追記ではなく上書きをしたいのですが。filecloseの位置
を変更すればですかね。
①追記・上書きとcloseの位置は関係ない。
closeすると読み書きできなくなるので、while(){}の外に。
②ReadStringは改行まですすむから、一回目の読み込みで
01田中08030511
(ココ)02鈴木08030511
03山田08030522
にきてるかと。
一行目を上書きするには「CStdioFile::Seek」で
一行文戻してから書き込めばいい
③おまけ
もし、3行以上に増やしていくことがあるなら
11佐藤08030522
がでてきたとき、、「11佐藤」を「99佐藤」にしちゃいそう
たまたま今回のデータは他の部分に11がないからこれでいけていますけれど、
本来ならちゃんと書き換えるべき部分を狙い撃ちで書き換えるべきでしょう。
なので、1行分のデータに対してReplaceで置き換えるのは方法としては良くない
と思います。ちゃんとやるなら一行分のデータから更新するべきところのみを
チェックして必要ならその部分を書き換えるようにするべきです。
折角、クラスを使っているんですから一行分のデータを展開して
それぞれを個別に取り扱えるクラスを設計してそれを通してやって見ては
どうでしょう。クラス設計の勉強にもなるし、面白いと思いますけれど。
うまく工夫するといろいろなケースにも対応できる仕組みが出来てくると思いますよ。
modeReadを、CFile::modeReadWriteで読み書き両用に変更し、
closeを、while(){}の外へ移動し、
file.Seek(-14, CFile::current);//前行へ戻る
file.WriteString(aaa);//書き込み
file.Seek(2, CFile::current);//次の行へ移動
のくり返しでOKでした。
3行以上に増やす場合は未確認です。
一行の中から該当箇所を見つけるようにして変更できるように改良して解決できまし
た。
ありがとうございました。