>例外処理をエラー処理として使用しちゃいけないでしょう。(C++では)
となると、try~catchって使わないってこと?
それと、ファイルオープンだけ例外が出るわけではないので、全体をtry~catchで囲った
わけなんですが、これも問題ありなんでしょうか?
ちなみに
>// エラー処理
と書いたのはエラー処理を行うというわけではなく、
エラーのときに行うときの処理を記述するという意味合いで書きました。
(たとえばメッセージボックスを出したり。)
try/catch はできる限り使わない、ということです。
ファイルオープンのエラー処理は if 文で解決できますよね。
例外処理は、 C++ では if 文に比べ数百倍遅くなるので
if 文で解決できるようなエラー処理に例外処理を使用してはいけません。
例外でしかエラーメッセージ取れない場合があったらしょうがないかもしれませんけど。
(.NET や Java なら例外処理は速いのでエラー処理として使用してもかまいません)
try/catch を極力使わないようにすれば、全体を try/catch で囲む
ということも少なくなり、より局所的になるでしょう。
このトピックで使われてる CStdioFile のメンバ関数で例外を投げるのは
コンストラクタと Seek くらいですしね。
基本方針という意味では概ね同意で、理解もしますが、
いけません、とか正しくない、はいいすぎな気がしますけど。
例えばこの部分で100ms遅くなったとしても、
それがどれほど致命的な箇所なのか?という話があって、
可読性が確保できるなら個人的にはこの程度はアリかなぁと。
これが組み込み開発やってて起動速度(やサイズ)の向上が最優先とか、
ここ自体が実行中にユーザの体感速度に直結するとかならわかるのですが、
どうもそうと断言するほどの情報は無いように思います。
C言語ライクに例外使わないなら使わないで統一ってのはまだいいとして、
「極めて局所的にtry/catchしてる」ソースって、すごく読みにくいのが
多いと個人的に思ってます。(大抵、外部モジュール都合?)
関数単位くらいでのtry/catchは可読性として悪くないと思いますが。
# 例外可能性をちゃんと考えずに書かれたコードがちょっと混じるだけで、
# すぐbad_allocの可能性とか出てきて結局全域的にtry/catchせざるを
# 得ないことも少なくないのが現実な気も…>PCアプリ。
>コンストラクタと Seek くらいですしね。
ReadStringやデストラクタでも例外返しませんか?
C++の例外処理機能ではなくてSEH使うほうが良いのですかね?
デストラクタで例外は勘弁して欲しい・・・そんなライブラリが合ったら即捨てだ
CStdioFile のデストラクタで例外は投げられないはずだ
SEH を使うなら SEH でのみ統一
C++ 例外を使うなら C++ 例外でのみ統一、だな
MFC は C++ 例外を投げるはず。C++ 例外機構で受け取るほうがいい
たしかに、「いけません」は言いすぎでした。
ですが、例外にかかるコストというのはよく考えなければならないことです。
例外を使用しなくてすむのであればそうしたほうがいいでしょう。
> 例えばこの部分で100ms遅くなったとしても
これも、コストをよく理解したうえで使用するならかまわないでしょうが
「最近のPCは早いから~」で作っていたらたちまちボトルネックになってしまうでしょ
う。
> # 例外可能性をちゃんと考えずに書かれたコードがちょっと混じるだけで、
> # すぐbad_allocの可能性とか出てきて結局全域的にtry/catchせざるを
どの関数が例外を投げる/投げないを調べたうえで使えばこれは問題にならないでしょ
う。
「例外を投げない」という強い保証がある関数にはそもそも例外可能性なんてものはない
ですから。
> ReadStringやデストラクタでも例外返しませんか?
投げませんよ。
http://msdn.microsoft.com/ja-jp/library/x5t0zfyf(VS.80).aspx
また、「デストラクタでは例外を投げてはいけない」という原則があります。
> try/catch はできる限り使わない、ということです。
> ファイルオープンのエラー処理は if 文で解決できますよね。
MFCのCFile系のクラスはC++のtry/catchに対応しているのでtry/catch
の文は使っています。
結果は利用してませんが..............
> try/catch を極力使わないようにすれば、全体を try/catch で囲む
> ということも少なくなり、より局所的になるでしょう。
MFCがtry/catchに対応している以上、try/catch文のルーチンは作ったほうが
いいと思います。
エラーは戻り値で判断すればいいだけですよね。
>> ReadStringやデストラクタでも例外返しませんか?
>投げませんよ。
CStdioFileはOpenとCStdioFile(構築)だけですね。
>CStdioFileはOpenとCStdioFile(構築)だけですね。
CStdioFileはOpenとCStdioFile(構築)だけではないみたいです。
CStdioFileのほかのクラスメンバーはないみたいです。
すいません。返信遅れました。
みなさん難しい話をされていますね~。
私には、ちょっと解らないですね。水を差す様で悪いんですが
ITOさんのMid関数使ってうまくいきました。ありがとうございます。
str[i] = strLine[i].Mid(14);使い方が簡単で助かりました。
すいません。少し戻るのですが、Seekの使い方について
今現在テキストの中は
----+--------+------------------------------------
1000|01-00-00|《aaaaa》
このようになってます。テキストが長いので区切りのために線等いれてます。
それを無理やりfInStream.Seek( 54, CFile::begin );
----+--------+------------------------------------の部分を飛ばしています。
聞きたいのは、こんな使い方でいいのでしょうか?
後、第一、第二、引数とかが知りたいです。
もしかしてmsdnに載っていますか?お願いします。
> こんな使い方でいいのでしょうか?
好ましくありません。'-'が一個でも増減したら即アウト。
一行まるっと読んで「'-'から始まってたら無視」の方が100倍マシ。
すいません。返信遅くなりました。
strtokを使ってテキストの-,+,|
飛ばしたいのですが、引数を調べるとchar *では、
ないといけないという事が分かったのですが
今CString型で文字列を取っているので、第一引数を
どうすればいいのか解らないです。
教えて頂けないでしょうか。お願いします。
char *ss;
while (fInStream.ReadString(strLine[i]))
{
ss = strLine[i];
strLine[i] = strtok(ss,-);
strLine[i] = strtok(ss,+);
strLine[i] = strtok(ss,|);
strLine[i] = strtok(ss, );
//str[i] = strLine[i].Mid(14);
m_HndTree[0] = m_tree.InsertItem(str[i],TVI_ROOT);
}
#include <afx.h>
#include <string.h>
#include <iostream>
using namespace std;
int main() {
CStdioFile fin;
if ( !fin.Open(test.txt, CFile::modeRead, NULL ) )
return -1;
CString line;
while ( fin.ReadString(line) != NULL ) {
int i = 0;
for ( const char* token = strtok(line.GetBuffer(line.GetLength()),+-|);
token != NULL;
token = strtok(0,+-|) ) {
cout << i++ << [ << token << ] ;
}
line.ReleaseBuffer(-1);
cout << endl;
}
}
-- test.txt --
1000|01-02-03|zero
2000|02-03-04|one
3000|03-04-05|two
4000|04-05-06|three
5000|05-06-07|four
6000|06-07-08|zero
-- 実行結果 --
0[1000] 1[01] 2[02] 3[03] 4[zero]
0[2000] 1[02] 2[03] 3[04] 4[one]
0[3000] 1[03] 2[04] 3[05] 4[two]
0[4000] 1[04] 2[05] 3[06] 4[three]
0[5000] 1[05] 2[06] 3[07] 4[four]
0[6000] 1[06] 2[07] 3[08] 4[zero]