CFileでfgets?それともReadString?

[戻る]
かつみ 2003/12/05(金) 11:45:20
テキストファイル(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でやりたいのですが…。

回答のほう、宜しくお願いいたします。

επιστημη [E-Mail] [HomePage] 2003/12/05(金) 11:56:49
> fgets(buffer,30,FName);
> とすると、コンパイルエラーが出てしまいます。
> 「3番目の引数を'cahr'から'struct_iobuf*'に変換できません」
> となってしまいます

無茶苦茶です。 ファイル名 は ファイル ではありません。

FILE* fp = fopen(FName, "rt");
if ( fp ) { // open成功
  fgets(buffer, 30, fp);
  fclose(fp);
}

とかなんとか。

かつみ 2003/12/05(金) 12:38:09
ああ、やっぱり、fgetsを使うには、fopenを使わないとだめなんですね。

(むちゃくちゃなのは、実は、このプログラミングがVCの
 初めてのプログラミングなので、すいません)

ただ、わからないのが、
CFileでファイルをオープンして
WriteStringでファイルにCStringを書き込むというのは
出来たのに、ReadStringが出来ない、ということです。

これはなぜなのでしょうか?

επιστημη [E-Mail] [HomePage] 2003/12/05(金) 12:46:51
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;
}

ぴくしー 2003/12/05(金) 12:54:15
僕も実行済で成功です

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 );

tipe 2003/12/05(金) 13:27:19
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が呼ばれているだけなので
同じことだと思われます

かつみ 2003/12/05(金) 14:04:14
ありがとうございます。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行をコメントアウトして実行すると、ちゃんとダイアログが開いて、
動作します。

なぜでしょうか?

επιστημη [E-Mail] [HomePage] 2003/12/05(金) 14:07:42
読み込んだあと close してませんけど、それが原因かも。

dairygoods 2003/12/05(金) 14:32:33
アウトプットウィンドウに、
"Warning: Uncaught exception in WindowProc ..."
というのが出ていませんか?

try/catch で囲んでみるとエラーが分かると思います。

try {
  CStdioFile (...);
  ...
} catch (CFileException* e) {
  e->ReportError();
  e->Delete();
}

かつみ 2003/12/05(金) 15:01:04
ありがとうございます。レスがとても早いので、助かっています…。
#周りの人間に聞いても、わからないのです。

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++について初歩的な質問なのだろうと思うのですが、
コンパイラエラーが出ないのに実行時エラーが出てしまったりするのでしょう。

かつみ 2003/12/05(金) 15:07:05
dairygoods さんへ

アウトプットウィンドウには、たとえば今回の場合、
「例外処理(初回)はsmp1.exe(MFC42D.DLL)にあります: 0xC0000005:Access Violation。
 プログラム'smp1.exe'はコード 0 (0x0) で終了しました」
とかいう風にかかれています。

すいません。try/catchは私には敷居が高くて、ちょっと今は手が出せません…。

επιστημη [E-Mail] [HomePage] 2003/12/05(金) 15:15:30
> OnCreateの時点では、このような操作は出来ないのですか?

OnInitDialog でやってみてはいかがでしょ。

かつみ 2003/12/05(金) 16:13:22
[[解決]]
ファイルからの取得、および、書き込みを、すべてOnCreateに持っていって
問題解決できました!!

みなさん、本当にどうもありがとうございました!

これで、初めてのプログラムが出来上がった感じです。
またお世話になることがあると思いますが、そのときは宜しくお願いします。

かつみ 2003/12/05(金) 16:14:36
[[解決]]
あ、間違えている…。

正)OnCreateからOnInitDialogに持っていくことで

すいませんでした。

古いスレッドには追加発言できません。