テキストファイル(2行しか中身はありません)から1行ずつ読み込んで、ダイアログボックス
のエディットボックスに出力するプログラムを作っています。
char* FName=logtime.txt;
char buffer[30];
CString Last_Start_Time,Last_Shutdown_Time;
CStdioFile f(FName,CFile::modeRead|CFile::modeNotruncate);
f.ReadString(buffer,30);
Last_Start_Time = buffer;
~
というようなソースです。(これでだいたい何をするかわかってしまいますね;)
コンパイルすると、エラーは出ないのですが、実行すると、例外エラーになってしまいます。
ここで、
f.ReadString(buffer,30);
の代わりに
fgets(buffer,30,FName);
とすると、コンパイルエラーが出てしまいます。
「3番目の引数を'cahr'から'struct_iobuf*'に変換できません」
となってしまいます。
FNameをcharで宣言してるのが良くないのでしょうか?
CFileでオープンした場合、fgetsが使えないなんてことはないですよね?
出来れば、fgetsでやりたいのですが…。
回答のほう、宜しくお願いいたします。
> fgets(buffer,30,FName);
> とすると、コンパイルエラーが出てしまいます。
> 「3番目の引数を'cahr'から'struct_iobuf*'に変換できません」
> となってしまいます
無茶苦茶です。 ファイル名 は ファイル ではありません。
FILE* fp = fopen(FName, rt);
if ( fp ) { // open成功
fgets(buffer, 30, fp);
fclose(fp);
}
とかなんとか。
ああ、やっぱり、fgetsを使うには、fopenを使わないとだめなんですね。
(むちゃくちゃなのは、実は、このプログラミングがVCの
初めてのプログラミングなので、すいません)
ただ、わからないのが、
CFileでファイルをオープンして
WriteStringでファイルにCStringを書き込むというのは
出来たのに、ReadStringが出来ない、ということです。
これはなぜなのでしょうか?
ReadString できますけど?
// foo.cpp : 自分自身を読む
#include <afx.h>
#include <iostream>
int main() {
CStdioFile f(foo.cpp,CFile::modeRead|CFile::typeText);
CString line;
while ( f.ReadString(line) ) {
std::cout << static_cast<const char*>(line) << std::endl;
}
return 0;
}
僕も実行済で成功です
char* FName=C:\\log.txt;
char buffer[30];
CString Last_Start_Time,Last_Shutdown_Time;
CStdioFile f(FName,CFile::modeRead);
f.ReadString(buffer,30);
CString csData;
csData = buffer;
MessageBox( (LPCTSTR)csData );
MSDNで
CStdioFile::m_pStream
に
>m_pStream データ メンバは、C ランタイム関数 fopen が返すオープン済みファイルへのポ
インタを保持します。
とあるので
char* FName=logtime.txt;
char buffer[30];
CStdioFile f(FName,CFile::modeRead|CFile::modeNotruncate);
fgets(buffer, 30, f.m_pStream);
なんてことができますが、
ReadString内部でもfgetsが呼ばれているだけなので
同じことだと思われます
ありがとうございます。ReadStringは使えるのですね。
というか、いじっていたら、どうやら原因は別のところにありそうでした。
(このまま、このスレで書いていいのかわからないのですが)
ダイアログベースのプログラムなのですが、起動時にこの操作を行おうと
しています。
前回の起動時に、その時の、起動時間と終了時間をファイルに落としてあります。
2003/12/05/(Friday)/13:28:40
2003/12/05/(Friday)/13:28:44
の2行のテキストファイルです。
int CSmp1Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: この位置に固有の作成用コードを追加してください
//ファイルから前回の起動時間と、終了時間を取得して表示する
char* FName=logtime.txt;
char buffer[30];
CString Last_Start_Time,Last_Shutdown_Time;
→ CStdioFile f(FName,CFile::modeRead);
f.ReadString(buffer,30);
Last_Start_Time = buffer;
f.ReadString(buffer,30);
Last_Shutdown_Time = buffer;*/
//このプログラムが起動した時間をファイルに書き込む
CString Start_Time;
CTime theTime=CTime::GetCurrentTime();
Start_Time = theTime.Format(%Y/%m/%d/(%A)/%H:%M:%S);
CStdioFile ff(FName,CFile::modeCreate|CFile::modeWrite);
ff.WriteString(Start_Time+\n);
return 0;
}
どうもこの→の行があることによって(?)実行しても、ダイアログが開きません。
#コンパイルは出来ます。実行しても、エラーも発生しません。
この行以降があると、ダイアログが開かないのです。
何かおかしいことをしているのでしょうか?
みなさんのソースを見ても、特に問題があるようには思えないのですが…。
→の行から5行をコメントアウトして実行すると、ちゃんとダイアログが開いて、
動作します。
なぜでしょうか?
読み込んだあと close してませんけど、それが原因かも。
アウトプットウィンドウに、
Warning: Uncaught exception in WindowProc ...
というのが出ていませんか?
try/catch で囲んでみるとエラーが分かると思います。
try {
CStdioFile (...);
...
} catch (CFileException* e) {
e->ReportError();
e->Delete();
}
ありがとうございます。レスがとても早いので、助かっています…。
#周りの人間に聞いても、わからないのです。
f.Close();
の一行を加えたら、スルー出来ました。
今度は、この処理とファイル書き込みの間に
CEdit* myED2=(CEdit*)GetDlgItem(IDC_EDIT2);
CEdit* myED3=(CEdit*)GetDlgItem(IDC_EDIT3);
myED2->SetWindowText(Last_Start_Time);
myED3->SetWindowText(Last_Shutdown_Time);
というのを入れたら、これまた、コンパイルエラーにはならないけれども
実行時エラーになりました。
OnCreateの時点では、このような操作は出来ないのですか?
それと、非常にVC++について初歩的な質問なのだろうと思うのですが、
コンパイラエラーが出ないのに実行時エラーが出てしまったりするのでしょう。
dairygoods さんへ
アウトプットウィンドウには、たとえば今回の場合、
「例外処理(初回)はsmp1.exe(MFC42D.DLL)にあります: 0xC0000005:Access Violation。
プログラム'smp1.exe'はコード 0 (0x0) で終了しました」
とかいう風にかかれています。
すいません。try/catchは私には敷居が高くて、ちょっと今は手が出せません…。
> OnCreateの時点では、このような操作は出来ないのですか?
OnInitDialog でやってみてはいかがでしょ。
ファイルからの取得、および、書き込みを、すべてOnCreateに持っていって
問題解決できました!!
みなさん、本当にどうもありがとうございました!
これで、初めてのプログラムが出来上がった感じです。
またお世話になることがあると思いますが、そのときは宜しくお願いします。
あ、間違えている…。
正)OnCreateからOnInitDialogに持っていくことで
すいませんでした。