CStdioFileについて – 固定ページ 2 – プログラミング – Home

通知
すべてクリア

[解決済] CStdioFileについて

固定ページ 2 / 5

Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>例外処理をエラー処理として使用しちゃいけないでしょう。(C++では)
となると、try~catchって使わないってこと?

それと、ファイルオープンだけ例外が出るわけではないので、全体をtry~catchで囲った
わけなんですが、これも問題ありなんでしょうか?


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

ちなみに
>// エラー処理
と書いたのはエラー処理を行うというわけではなく、
エラーのときに行うときの処理を記述するという意味合いで書きました。
(たとえばメッセージボックスを出したり。)


返信引用
アキラ
 アキラ
(@アキラ)
ゲスト
結合: 23年前
投稿: 49
 

try/catch はできる限り使わない、ということです。
ファイルオープンのエラー処理は if 文で解決できますよね。

例外処理は、 C++ では if 文に比べ数百倍遅くなるので
if 文で解決できるようなエラー処理に例外処理を使用してはいけません。
例外でしかエラーメッセージ取れない場合があったらしょうがないかもしれませんけど。
(.NET や Java なら例外処理は速いのでエラー処理として使用してもかまいません)


返信引用
アキラ
 アキラ
(@アキラ)
ゲスト
結合: 23年前
投稿: 49
 

try/catch を極力使わないようにすれば、全体を try/catch で囲む
ということも少なくなり、より局所的になるでしょう。
このトピックで使われてる CStdioFile のメンバ関数で例外を投げるのは
コンストラクタと Seek くらいですしね。


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

基本方針という意味では概ね同意で、理解もしますが、
いけません、とか正しくない、はいいすぎな気がしますけど。

例えばこの部分で100ms遅くなったとしても、
それがどれほど致命的な箇所なのか?という話があって、
可読性が確保できるなら個人的にはこの程度はアリかなぁと。

これが組み込み開発やってて起動速度(やサイズ)の向上が最優先とか、
ここ自体が実行中にユーザの体感速度に直結するとかならわかるのですが、
どうもそうと断言するほどの情報は無いように思います。

C言語ライクに例外使わないなら使わないで統一ってのはまだいいとして、
「極めて局所的にtry/catchしてる」ソースって、すごく読みにくいのが
多いと個人的に思ってます。(大抵、外部モジュール都合?)
関数単位くらいでのtry/catchは可読性として悪くないと思いますが。

# 例外可能性をちゃんと考えずに書かれたコードがちょっと混じるだけで、
# すぐbad_allocの可能性とか出てきて結局全域的にtry/catchせざるを
# 得ないことも少なくないのが現実な気も…>PCアプリ。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>コンストラクタと Seek くらいですしね。
ReadStringやデストラクタでも例外返しませんか?


返信引用
かもねぎ
 かもねぎ
(@かもねぎ)
ゲスト
結合: 17年前
投稿: 61
 

C++の例外処理機能ではなくてSEH使うほうが良いのですかね?


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

デストラクタで例外は勘弁して欲しい・・・そんなライブラリが合ったら即捨てだ
CStdioFile のデストラクタで例外は投げられないはずだ

SEH を使うなら SEH でのみ統一
C++ 例外を使うなら C++ 例外でのみ統一、だな
MFC は C++ 例外を投げるはず。C++ 例外機構で受け取るほうがいい


返信引用
アキラ
 アキラ
(@アキラ)
ゲスト
結合: 23年前
投稿: 49
 

たしかに、「いけません」は言いすぎでした。
ですが、例外にかかるコストというのはよく考えなければならないことです。
例外を使用しなくてすむのであればそうしたほうがいいでしょう。

> 例えばこの部分で100ms遅くなったとしても
これも、コストをよく理解したうえで使用するならかまわないでしょうが
「最近のPCは早いから~」で作っていたらたちまちボトルネックになってしまうでしょ
う。

> # 例外可能性をちゃんと考えずに書かれたコードがちょっと混じるだけで、
> # すぐbad_allocの可能性とか出てきて結局全域的にtry/catchせざるを
どの関数が例外を投げる/投げないを調べたうえで使えばこれは問題にならないでしょ
う。
「例外を投げない」という強い保証がある関数にはそもそも例外可能性なんてものはない
ですから。

> ReadStringやデストラクタでも例外返しませんか?
投げませんよ。
http://msdn.microsoft.com/ja-jp/library/x5t0zfyf(VS.80).aspx

また、「デストラクタでは例外を投げてはいけない」という原則があります。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> try/catch はできる限り使わない、ということです。
> ファイルオープンのエラー処理は if 文で解決できますよね。
MFCのCFile系のクラスはC++のtry/catchに対応しているのでtry/catch
の文は使っています。
結果は利用してませんが..............
> try/catch を極力使わないようにすれば、全体を try/catch で囲む
> ということも少なくなり、より局所的になるでしょう。
 MFCがtry/catchに対応している以上、try/catch文のルーチンは作ったほうが
いいと思います。
 エラーは戻り値で判断すればいいだけですよね。
>> ReadStringやデストラクタでも例外返しませんか?
>投げませんよ。
CStdioFileはOpenとCStdioFile(構築)だけですね。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

>CStdioFileはOpenとCStdioFile(構築)だけですね。
CStdioFileはOpenとCStdioFile(構築)だけではないみたいです。
CStdioFileのほかのクラスメンバーはないみたいです。


返信引用
いけやん
 いけやん
(@いけやん)
ゲスト
結合: 16年前
投稿: 32
Topic starter  

すいません。返信遅れました。

みなさん難しい話をされていますね~。

私には、ちょっと解らないですね。水を差す様で悪いんですが

ITOさんのMid関数使ってうまくいきました。ありがとうございます。

str[i] = strLine[i].Mid(14);使い方が簡単で助かりました。

すいません。少し戻るのですが、Seekの使い方について

今現在テキストの中は

----+--------+------------------------------------
1000|01-00-00|《aaaaa》

このようになってます。テキストが長いので区切りのために線等いれてます。

それを無理やりfInStream.Seek( 54, CFile::begin );

----+--------+------------------------------------の部分を飛ばしています。

聞きたいのは、こんな使い方でいいのでしょうか?

後、第一、第二、引数とかが知りたいです。

もしかしてmsdnに載っていますか?お願いします。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> こんな使い方でいいのでしょうか?

好ましくありません。'-'が一個でも増減したら即アウト。
一行まるっと読んで「'-'から始まってたら無視」の方が100倍マシ。


返信引用
いけやん
 いけやん
(@いけやん)
ゲスト
結合: 16年前
投稿: 32
Topic starter  

すいません。返信遅くなりました。

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


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

#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]


返信引用
固定ページ 2 / 5

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました