スレッド内でのCStdioFileの使用

[戻る]
うちだ 2005/03/12(土) 10:17:46
スレッド内で、処理内容をファイルを生成してテキストで書こうと思っています
そこで以下のようなコードを書きました
class CTestThread : public CWinThread
{
public:
            ・
            ・
    CString m_FileName;
    CString m_Str;
};

int CTestThread::Run() 
{
    CStdioFile file;
    CString fileName = "c:\\testWork\\";
    fileName += this->m_FileName + ".txt";
    if(TRUE == file.Open(fileName, CFile::modeWrite | CFile::modeCreate |
CFile::typeText )){
        for(int i = 0; i < 1000; i++){//テスト的に負荷をかけたいのでループを回している
だけなので特に意味はない
            file.ReadString(this->m_Str);
        }
        file.Close();
    }
    return CWinThread::Run();
}

すると、ReadString()で落ちてしまいます
これをCFileに代えて

int CTestThread::Run() 
{
    CFile file;
    CString fileName = "c:\\testWork\\";
    fileName += this->m_FileName + ".txt";
    if(TRUE == file.Open(fileName, CFile::modeWrite | CFile::modeCreate )){
        for(int i = 0; i < 1000; i++){
            file.Write(this->m_Str, 10);
        }
        file.Close();
    }
    return CWinThread::Run();
}
とすると期待通りの動作が行えます
これは、なぜでしょうか???
あるいは、CFileでもたまたま動いているだけで問題があるのでしょうか?

VC++6.0 SP4
WinXP SP1

Ban 2005/03/12(土) 11:53:57
# 回答ではありません。

> if(TRUE == 

C/C++ において TRUE と比較することは、一般的に危険なこととして忌避されます。
比較するなら FALSE(というか 0)とするのが普通です。

ちなみに、CStdioFile::Open の戻り値は以下。
<MSDN>
ファイルが正常に開いた場合は 0 以外を返します。それ以外の場合は 0 を返します。パ
ラメータ pError は、0 が返されたときだけ使用されます。
</MSDN>

Windows における FALSE は 0 ですが、成功時に TRUE(1) だけを返すとは
どこにも書かれていません。

RAPT 2005/03/12(土) 12:36:39
> すると、ReadString()で落ちてしまいます
コールスタックなどで原因を探れませんか?

> これをCFileに代えて
日本語の問題。漢字によって、意味が変わります。
# 最初、何を言っているのか理解できませんでした。
CFileに代えて→CFileから何かに変更する事
CFileに変えて→何かからCFileに変更する事

> CStdioFile file;
> file.ReadString(this->m_Str);
  ↓
> CFile file;
> file.Write(this->m_Str, 10);
変更しすぎです。処理内容が違う訳ですから、単純に比較できません。
比較する場合、処理内容は変えないようにしないと、比較できません。

> if(TRUE ==
MSが用意した関数で、BOOL型の関数なのに、0,1以外を返す関数も実存します。
# だったら、BOOL型じゃなく、int/INT型とかにしてくれっ! って言いたい。

RAPT 2005/03/12(土) 12:39:05
追加。
個人的には、this-> はあまり多用しない方が見やすいです。
というか、通常は省略します。

# メンバ変数の定義が記載されているので、説明用といっても筋が通らない気が。
# ま、言語仕様上の問題ではありませんが。

Blue 2005/03/12(土) 13:20:33
>    if(TRUE == file.Open(fileName, CFile::modeWrite | CFile::modeCreate )){
>           file.ReadString(this->m_Str);
書き込みモードで開いているのに読み込めるのかなぁ。

一応自分のとこで try〜catch したら ReadString で 例外発生しました。
(m_cause は CFileException::generic でした。)

ファイル処理とかは try〜catch処理をしたほうがいい気がします。

# 私は this-> つけます。
# メンバ変数は m_ で判断するとしても、
# メンバ関数には付けないと、どの関数なのかわからないですから。
# (グローバルな関数かメンバ関数かはたまた私のシラナイAPIとか)

うちだ 2005/03/12(土) 14:13:41
[[解決]]
皆さんアドバイスありがとうございました
マルチレスで失礼します

原因は

>    if(TRUE == file.Open(fileName, CFile::modeWrite | CFile::modeCreate )){
>           file.ReadString(this->m_Str

でした
ファイルに書きたいのにReadString()使っていたなんて・・・
しょぼしょぼな問題ですいません
初めてのマルチスレッドプログラムで焦ってました

>個人的には、this-> はあまり多用しない方が見やすいです

これは当社のコーディング規約です
私もVC++を使うとコンボが出てくれるので使いやすいのと、メンバであることが即座に分
かるので気に入ってます

>C/C++ において TRUE と比較することは、一般的に危険なこととして忌避されます。
比較するなら FALSE(というか 0)とするのが普通です

知りませんでした。関数の戻りが、BOOLだったので気にせずに使っていました
どうもありがとうございます

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