- 1 名前:デフォルトの名無しさん [2007/06/25(月) 12:01:46 ]
- エスケープシーケンスやWin32APIなどの環境依存な物でもOK。
ただしその場合、質問者は必ず、環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.38【環境依存OK】 pc11.2ch.net/test/read.cgi/tech/1180877635/ 【アップローダー】(質問が長い時はココ使うと便利) kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
- 82 名前:デフォルトの名無しさん mailto:sage [2007/06/26(火) 14:05:12 ]
- std::fstream のコンストラクタに渡すファイル(パス)文字列って、
ネイティブなフォーマットのものなの?それとも POSIX 準拠じゃなきゃいけない?たとえば UNIX では /home/hoge/test.txt で Windows では C:\home\hoge\test.txt ? どういうフォーマットのパス文字列を取りうるかに関する 規約って定められてるの??
- 83 名前:デフォルトの名無しさん mailto:sage [2007/06/26(火) 14:39:34 ]
- POSIX かんけーねー。
処理系で好きに決めりゃいいべさ。
- 84 名前:デフォルトの名無しさん mailto:sage [2007/06/26(火) 14:48:09 ]
- そうか・・・標準の C++ のライブラリではそこまでは
決められていないんだね。 boost::filesystem では native/ portable が厳密に切り分けられていたので、 fopen や fstream でもそうなってるのかと思った。
- 85 名前:デフォルトの名無しさん mailto:sage [2007/06/26(火) 14:51:43 ]
- >>82
const char*なのが困り物 たとえばVC++8.0ではlocale依存の方法でUTF-16に変換する それ以前ではコードページ依存の方法でUTF-16に変換する いずれにせよ、NTFSのUTF-16なパスを正しく扱えるとは言いがたい UTF-16なパス名をちゃんと扱いたければ、fstreamを捨てて カスタムのストリームバッファを作れという話になるだろう
- 86 名前:デフォルトの名無しさん [2007/06/26(火) 21:17:53 ]
- ofstreamやifstreamでファイルを開くとき、
ios::binary指定というのは、意味があるのでしょうか? コンパイラはg++です。 いままでとくに指定してもしなくても結果は同じになりました。
- 87 名前:デフォルトの名無しさん mailto:sage [2007/06/26(火) 21:23:21 ]
- >>86
UNIX系は関係ない。 WIndowsはstd::endlや\nを書き込むと0x0d0x0aになって書き込まれ 読むときは0x0d0aが0x0aになる。
- 88 名前:デフォルトの名無しさん [2007/06/26(火) 21:26:02 ]
- ios::binaryしない奴は死ねっていつも思う。
- 89 名前:デフォルトの名無しさん mailto:sage [2007/06/26(火) 21:27:15 ]
- >>86
テキストファイルを特別扱いする(というよりC++としては特別扱いしなければならない)環境も結構ある 有名どころではDOS/Windows系のテキストファイルでは改行コードがCR+LFになっていることが挙げられる そういう環境では、テキストファイル特有の処理を行わせたくないときに、バイナリモードを指定する必要がある 逆にUnix関係では大抵違いがないが、移植性向上のために必要に応じバイナリモードを意識的に使うのは良いことだ Unixとかでもワイド文字ストリームなら、文字コード変換をどうするかで テキストモードとバイナリモードの違いが表れるはず
- 90 名前:デフォルトの名無しさん [2007/06/26(火) 23:37:20 ]
- while(!feof(fp1)){
ch = fgetc(fp1) if(!feof(fp1) fputc(ch,temp); } ファイルの中身を別のファイルにコピーする場合の例題に書かれていたコードなんですが whileの式で(!feof(fp1))と記述されているにもかかわらず何故さらにif(!feof(fp1)と書いているのは何故なんでしょうか? 何か意味があるんですか? whileの式でファイルの末端にきたらループ終了なのでifの式は必要ないように思えるんですが
- 91 名前:デフォルトの名無しさん mailto:sage [2007/06/26(火) 23:44:12 ]
- >>90
意味以前にその例題、コンパイルできるか?
- 92 名前:デフォルトの名無しさん mailto:sage [2007/06/26(火) 23:45:19 ]
- >>90
fgetc()で読みに行ってみないとEOFだとわからんことがあるから。 その場合、whileの条件式の時点ではEOFではないと判断して 読みに行ってみたらEOFだった(読めませんでした)というカタチになるので 下のチェックが要る。 だがこんなのは糞コード。 while ((ch = getc(fp)) != EOF) putc(ch, temp); とするがよい。
- 93 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 00:12:20 ]
- >>92
バイナリファイルを操作する場合は>>90の方がよい
- 94 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 00:13:20 ]
- >>93
なぜ?
- 95 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 00:16:51 ]
- >>94
int型と比較した時、EOFと同じ値のバイトが存在する可能性があるから
- 96 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 00:17:02 ]
- とても初歩的な質問ですが
short i; long k; float f; double d; としたときに @ (f+15)/(long)(d-15) A k+20.0 B (int)d/i の型(double,longなど…)はどうなるでしょうか? こういう場合は計算式の中でもっとも高精度な変数の型になると理解すればいいのでしょうか?
- 97 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 00:17:55 ]
- >>95
あ、chがcharだと仮定しているわけね。 それならば、単にint chと宣言して>>92のコードで良い。
- 98 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 00:21:04 ]
- >>96
整数拡張、型の昇格
- 99 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 00:23:00 ]
- というかgetc()の戻り値をcharで受け取る奴がアホ
- 100 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 02:13:04 ]
- C++でのバイナリファイルの読み書きは、ifstreamのreadとか、ofstreamのwriteを使うんですよね。
気になったのは、どちらも char * を指定するところです。freadは void * だったと思うんですが。。。 ifs.read(reinterpret_cast<char *>(&hoge), sizeof(unsigned)); という感じで、毎回キャストしないといけないんですか?
- 101 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 02:27:57 ]
- >>100
残念ながらキャストが必要。 毎回キャストするのが嫌なら、適当な関数で包め。
- 102 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 04:13:44 ]
- 別にfread使っても一向にかまわないわけだし。
適材適所。
- 103 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 09:36:59 ]
- freadはvoid*の代わりに、サイズと数の2つを指定するだろう
- 104 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 09:42:16 ]
- fread()/fwrite()は(Unixの)read()/write()のインタフェース
真似れば良かったのにな
- 105 名前:デフォルトの名無しさん [2007/06/27(水) 10:16:53 ]
- データがBIG ENDIANかLITTLE ENDIANのどちらかで
単純に&hogeで受け取れない場合もあるし。 つまり、CPUとデータの並びが逆の場合。 今回みたいに並びが合ってるのなら、union使えばいいんじゃないか?
- 106 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 10:26:23 ]
- ネットワークを跨ぐとか、別PCでもそのファイルを r/w するのならエンディアン気にするけど…
たかだか、同じPC内で完結するのならそのまま保存するよね?
- 107 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 10:41:33 ]
- そりゃファイル仕様に因るべさ。
- 108 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 10:49:46 ]
- ああ、先にファイル仕様があって(当然エンディアンも明示されてて)それを
読む→(なんかする)→(書く) なら、それに従うしかないね。
- 109 名前:デフォルトの名無しさん [2007/06/27(水) 12:14:06 ]
- >>87-89
なるほど、ではテキストでないときには、 ios::binaryを付けるようにします。
- 110 名前:デフォルトの名無しさん [2007/06/27(水) 14:39:49 ]
- 基底クラスのポインタを継承クラスの動的配列でオーバーライドすることはできませんか?
class Base{ public: Base(){val0=0;}; virtual ~Base(){}; virtual void show(void){cout << val0 << endl;} int val0; }; class Deriv:public Base{ public: Deriv(){val1 = 1;}; virtual ~Deriv(){}; virtual void show(void){cout << val1 << endl;} int val1; }; int main(int argc, char *argv[]) { Base *test; int num = 10; test = new Deriv[num]; for(int i=0;i<num;i++) test[i].show(); } を実行すると,main()の中のfor文2回目のループ(i=1)で 0x0041e12c でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x00000005 を読み込み中にアクセス違反が発生しました。 。 というエラーが出ます。 test[0]は無事Derivにオーバーライドできていますが,test[1]以降が不可能なようです。 何か良い方法はないでしょうか? 環境:WindowsXP + VisualC++ Ver.7
- 111 名前:110 [2007/06/27(水) 15:02:56 ]
- オーバーライドの意味間違ってますね。
何と呼んで良いのか分からないですが、領域確保? とにかくnewするという意味です。
- 112 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 15:11:45 ]
- >>110-111
BaseとDerivのメモリ上の大きさが違うのに、配列でどう動けと。
- 113 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 15:34:55 ]
- 無理するなら↓
((Deriv *)((char *)test + sizeof(Deriv) * i))->show(); もしくは↓ ((Deriv *)test)[i].show();
- 114 名前:110 [2007/06/27(水) 15:51:45 ]
- >>112,113
ありがとうございます。 なんとなく分かりました。 new Deriv[num]が失敗してるのではなく、 forループのなかでのindexの指定が間違ってるということですね。 *testがBase型のポインタなので test[i]はtest[0]からBaseを基準にアドレスを進めることになるのか。 >>113さんの方法で動きましたけど、 そもそもこういう状況が必要になる設計はまずいでしょうか?
- 115 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 16:28:34 ]
- >>114
一般的にはまずい。 でも、テンプレートを使って下のようにやればできないことはない。 template<class T> class poly_array { template<class U> poly_array(U *ptr, int array_size) : ptr_(ptr), size_(sizeof(U)) ... {...} T *get(int i) {return (T *)((char *)ptr_ + size_ * i); } private: T *ptr_; size_t ptr_size_; ... };
- 116 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 16:34:21 ]
- 基底クラスへのポインタの配列を作って、
それぞれに対してまたオブジェクトを作っていくのが、 まあ一番安全なのかね。 メモリ管理が複雑になるという点では、 安全とは言えんかもしれんが。 >>115 はちょっと感動したよ。
- 117 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 17:51:04 ]
- 下記を左側の数字のキー値で、ソートしたいです。
(8,x),(2,y),(3,z)・・・ ソートして、 (2,y),(3,z),(8,x)・・・ を出力。(int,std::string)の形です。 どういうデータで扱って、どのような方法がよいでしょうか。 mapとか自動でソートされるみたいですが、 自分で比較して並べ替えたいです。 よろしくお願いします。
- 118 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 17:58:37 ]
- int, std::string をメンバに持つ構造体の配列?
それなら構造体で < 演算子をオーバーロードするか 比較関数を定義するかすれば std::sort でソートできるけど。
- 119 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 18:00:21 ]
- >>117
つ[std::vector]
- 120 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 18:12:57 ]
- 訂正お願いします。
×キー値で、ソート ○キーでソート >>118 ごめんなさい。 「(int,std::string)」 これは、余計でした。(数字,文字列) なんです。 どのデータに入れて、どんな風に処理するのか知りたいです。 >>119 std::vectorに、キーを入れてソートするんでしょうか? 対応する値は、どうやって対応させて出力を。。。
- 121 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 18:19:20 ]
- 何がしたいのかよく分からない。
int 値はキーで、std::string はキーに対応する値? std::map を使うのがベストだと思うけど、 std::map を使わない理由は何かあるの?
- 122 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 18:22:08 ]
- >>117
とりあえず、すんごい単純で愚直な方法。 #include <iostream> #include <string> #include <vector> #include <utility> #include <algorithm> typedef std::pair<int,std::string> nspair; bool cmp(const nspair& a, const nspair& b) { return a.first < b.first; } int main() { int n; std::string s; std::vector<nspair> vec; while (std::cin >> n >> s) vec.push_back(nspair(n,s)); sort(vec.begin(), vec.end(), cmp); for (std::vector<nspair>::iterator i = vec.begin(); i != vec.end(); ++i) std::cout << '(' << i->first << ',' << i->second << ')' << std::endl; }
- 123 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 18:25:51 ]
- >>116
つboost::ptr_vector
- 124 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 18:41:02 ]
- >>121
(数字,文字列),,,, をキーでソートするんですが、どんなデータに格納して どんな処理をするのか知りたかったんです。 >>122 プログラムも、書いていただきありがとうございます。 数分しかたってないのに。(汗 中身がstd::pairのstd::vectorですか。 typedefの使い方もすごい勉強になります。 ありがとうございました。
- 125 名前:119 mailto:sage [2007/06/27(水) 19:10:32 ]
- ちっ、プログラムを書いてみたけどstd::pairとstructの違いだけで殆ど同じだから貼るのやめよ。
- 126 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 21:01:34 ]
- >>124
(数字,文字列) 全体がキーなの? じゃ、それに対応する値もあるの? それとも set みたいにキー=値なの? そして、数字が同じ時には文字列も比較するの? と、質問攻めになってしまった。
- 127 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 21:30:26 ]
- 結局ポインタって何に使うんですか?
違った名前の変数で同じ値を参照できるってことですか? でも同じアドレスの値を参照するだけならわざわざポインタの方の変数を作る必要は無い気が・・・・ ていうかそもそもいろんなソースコードを見ててもポインタを使ってるのはあまり見かけませんが・・・・
- 128 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 21:32:29 ]
- >>127
C はポインタが無ければ配列も関数に渡せない言語です。
- 129 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 21:34:24 ]
- ポインタ使いまくりw
ポインタを理解していないみたいだが君も知らない内に使ってるよ
- 130 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 22:04:33 ]
- >>127
scanfを使ったことはないのかい?
- 131 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 22:08:35 ]
- ポインタより似たような文法上の特徴を持つC++のイテレータの方から覚えた方がいいかもね
概念としては似たようなもんだし、イテレータ理解できるならポインタも理解できるようになるか どうしてもポインタが駄目ならC++でイテレータから入るのも十分ありだよ
- 132 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 22:54:19 ]
- ポインタの概念を理解できないレベルでイテレータを理解できるか疑問
- 133 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 23:05:18 ]
- イテレータ自体がデータをポインタライクに扱うようなもんだしなぁ
- 134 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 23:08:52 ]
- ポインタのノリでイテレータが使うとそれはそれでバグの元に・・・
- 135 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 23:10:27 ]
- アドレスがどうのという話が無いぶんイテレータの方が簡単だと思うな
概念的な話より、何が出来るかの方が理解しやすいだろう
- 136 名前:デフォルトの名無しさん mailto:sage [2007/06/27(水) 23:25:39 ]
- 抽象概念を理解できない香具師にはどっちみち理解できない罠。
- 137 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 00:07:25 ]
- ポインタがわからない→Javaへ行く
Javaのダメプログラマがまた一人。
- 138 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 00:17:46 ]
- >>127
a = 5; /* aに対応する箱に5を入れる */ b = a; /* bに対応する箱に、aに対応する箱から取り出した値を入れる */ おんなじaでも式の右辺と左辺ではぜんぜん意味が違うのだが、それを理解してるかな? 物を入れるには箱が必要で、Cで箱そのものを値として取り回すための 仕掛けがポインタだ。 どういう時に必要になるかはいずれ分かる。
- 139 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 00:47:44 ]
- Cでのポインタの必要性が特に大きいのは、配列や左辺値を渡す手段が
他に存在しないから。関数は全部値渡しだし。 参照渡しが存在するならポインタの必要性は大分減るが、リストや木のような 配列より複雑なデータ構造を扱うようになれば、ポインタの有用性が自然に 理解できるだろう。
- 140 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 01:14:41 ]
- >>127
関数とのデータ受け渡し時に構造体とかそのまま実体渡すとコピーされるのでメモリの無駄だし速度的にもデメリットがある それに不定なサイズのデータを扱おうと思ったらポインタ使うと思うが。
- 141 名前:デフォルトの名無しさん [2007/06/28(木) 14:42:29 ]
- vc++2005で警告レベルを/W4にした時、
stlのアルゴリズム使って代入処理とかイテレータを用いたコンテナの初期化とかすると > xutility(1685) : warning C4244: '+=' : '__int64' から '__w64 unsigned int' への変換です。 > データが失われる可能性があります。 とかコンパイラ様が仰られて出力窓がカオスになって困るのでこれをどうにかしたい訳ですが こういうのは#includeディレクティブの羅列全体に(つまりxutilityを使ってるライブラリ全体を) #pragma warning(disable:4244)と #pragma warning(default:4244)やpush, pop使って抑制を適用しちゃっていいんでしょうか? 一応、ライブラリ以外の部分ではちゃんと/W4で警告が行われますし問題ないと思うんですが なんか良い解決法ってございませんかね?
- 142 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 14:47:55 ]
- >>141
__w64 は 64 ビットにするんじゃなくて、 32 ビット環境でコンパイルする時にも もし 64 ビットにしたとしても整合性が取れるかチェックするだけ。 つまり、__w64 unsigned int は 32 ビット環境では 32 ビット符号無し整数型になる。 __int64 は 64 ビット符号付き整数型だから、 そこから 32 ビット符号無し整数型への暗黙変換で警告が出るのは当たり前。 それで本当に大丈夫なのかをまず確認した方がいい。
- 143 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 14:53:54 ]
- boost::serialization ってクロスプラットフォームで
使ってもおk?つまりできたファイルはプラットフォームを またいで移動してもおk?たとえば endian の異なる プラットフォームに持っていっても安全?
- 144 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 15:32:13 ]
- >>142
なるほど、助言をヒントに 使用するされているイテレータの差の型にsize_tを指定して定義すればあっさりと消えました どうもです><
- 145 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 17:04:11 ]
- >>144
> イテレータの差の型 difference_typeのことならstd::size_tよりも 符号付のstd::ptrdiff_tのほうがいい。 it = begin(); it2 = begin(); ++it2; このときit2 - itは1になるはずで、it - it2は-1になるべきだから。
- 146 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 17:25:10 ]
- >>143
あれの出力形式にはいろいろあって、 バイナリは知らないけど、xmlなら間違いなくできる。
- 147 名前:デフォルトの名無しさん [2007/06/28(木) 17:51:43 ]
- API の話ではないが、質問していいですか。
_tprintf(_T("あいう")); とするとコンソールに正常に表示されないのですが、 どのようにしたら正常に表示できるでしょうか?
- 148 名前:デフォルトの名無しさん [2007/06/28(木) 18:00:43 ]
- setlocale(LC_ALL, ""); でできた。
- 149 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 22:02:18 ]
- イテレータの差ならiterator_traits<hoge_iterator>::difference_typeだろ。
- 150 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 23:31:40 ]
- 板違いで流れてきましたw
01011010みたいに 日付が4桁4桁になってる 8桁の数字一覧の出力方法教えてください
- 151 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 00:53:49 ]
- >>128-140
関数内で宣言した変数はほかへは渡せないから、同じ中身を参照できるポインタを使って ほかの関数内でも関数内で変更した変数を渡せるようにするのがポインタですか? 自分で書いててわけがわからない文だな・・・・ とりあえずまだまだ自分は未熟なのがわかったのでまた最初から勉強しなおします!
- 152 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 07:50:22 ]
- >>150
それは、西暦101年10月10日か、01年1月10日10時なのか、1月1日10時10分なのか、101日目、10時10分なのか、 或いはそれ以外の表現なの? そもそも一覧とはなんなの?
- 153 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 09:46:27 ]
- お客様の中にESP能力者の方は・・
- 154 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 09:48:43 ]
- %04d%02d%02d
- 155 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 13:59:10 ]
- 同じ内容の関数を、マルチスレッドで動かして
ログファイルに処理内容を、追加書き込みで 書き出してます。 std::ofstream ofs( FileName.c_str(), std::ios::out|std::ios::app); ofs << message; 結構、同じタイミングで書き込むときあると思うのですが、 排他処理したほうがいいでしょうか? そもそも"ファイルが壊れる"っていうのは、どんな壊れ方があるのでしょうか? 真っ白になっちゃうのか、混ぜこぜで書き込みされる。などですか?
- 156 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:04:07 ]
- >>155
混ざります。しかも、通常バッファリングされるので行の途中でもお構いなしに混ざることになります。 運が悪いと、書き込んだ筈の分がロストしたり以前の分がロストしたりするかもしれません。
- 157 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:06:54 ]
- 俺の認識な。
ファイルが壊れる = ファイルアクセスに失敗してしまう。 居るように見えて実体が居なかったりする等 マルチスレッドのロギングで、同期取ってない場合 出力が途中で差し込まれたようなデータ列になる等、意図してないフォーマットで出力されてしまう
- 158 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:07:57 ]
- >>156
混ざるのは、構わないと思ってたのですが 無くなるときもあるんですか。 じゃあ、ファイルロックとかで、ロックするようにします。 ありがとうございました。
- 159 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:09:19 ]
- >>157
ふむふむです。勉強になります。 ありがとうございます。
- 160 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:12:02 ]
- >>157
もみもみです。あぁ〜ん♪ 感じちゃう?
- 161 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:24:45 ]
- >>155
使っているlibc++がマルチスレッド対応してるなら(今時なら普通してると思うが) istream/ostreamの関数呼び出しの単位で排他してくれてるはずだ。 つまり、例えばあるスレッドでoperator<<()が呼ばれた場合、その間は streambufがロックされるので、streambufの内部状態が壊されることが無い。 ヘルプなどのドキュメントに明記されていないなら、ソースを読むんだね。 ただ、排他はあくまで関数呼び出し単位なので、例えば ofs << n << ":" << s << endl; のようなことをやっているコードでは、operator<<()が4回呼ばれている間に 他のスレッドからの出力が割り込む可能性は当然あって、その場合は 出力がぐじゃぐじゃになる。 それを避けたければ、常に1行単位で出力関数を呼ぶようにするとよいだろう。 無論自前で排他をするという手もあるが。
- 162 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:25:36 ]
- バッファリングはどーなのよ
- 163 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:28:01 ]
- >>162
バッファリングを管理しているのはstreambufで、これがstdioのFILEの対応物。 i/ostreamはstreambufへのポインタを保持しており、排他はstreambuf自体を ロックするような形でやっていることが多いはずだ。 つかソース嫁よ。
- 164 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:31:06 ]
- 結局スレッドセーフなカスタムストリームを実装するしか無いなね…orz
- 165 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:35:55 ]
- 無いなね
- 166 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:36:41 ]
- OTL
- 167 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:51:26 ]
- >>163
別に聞いたわけじゃない。 >>161のように排他してもバッファリングしてたら意味無いだろ、と
- 168 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:56:17 ]
- アンダーバーで始まる関数
_stprintf_s みたいにアンダーバーで始まる関数があるのですが、 アンダーバーで始まる関数には何がしの意味があってアンダーバーをつけてるのですか? たとえば、MSによって拡張されたことを示すために付けられたとか
- 169 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 14:59:44 ]
- バッファへの操作込みで排他処理されてるんじゃないのか?
- 170 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:03:59 ]
- >>168
ttp://www.microsoft.com/japan/msdn/security/demo/runtime.aspx
- 171 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:05:18 ]
- って前の _ か
標準じゃないやつにつけるべ
- 172 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:07:11 ]
- MS は独自の拡張関数に _ つけるよね。
- 173 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:16:35 ]
- >>168
アンダーバーから始まる名前は処理系のために予約されている と規格で決められている
- 174 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:25:35 ]
- >>169
バッファリングされる場合、実際にファイルに書き出されるのはどのタイミングか判って言ってる?
- 175 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:31:43 ]
- それが何か関係あるの?
- 176 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:33:57 ]
- バッファ単位での実書き出し最中に、別スレッド側のバッファ操作はどうなるか
- 177 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:37:59 ]
- 失敗するー
だから入出力関数の戻り値は常にチェックしてけって話ですか?
- 178 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:39:21 ]
- 同じバッファ使って操作するわけじゃなくて、
別々のバッファで操作しようとしてるの?
- 179 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:47:23 ]
- そりゃ別スレッドなんだからバッファは違うだろう
- 180 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:49:43 ]
- 同じファイルに追記するだけなら、
別スレッドで同じオブジェクトを共有して 操作したんでいいんじゃないの?
- 181 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 15:58:37 ]
- OS管理下のファイル本体
↑↓ OS管理下のバッファ ↑↓ ライブラリ管理下のバッファ なんとなくライブラリ管理下のバッファの排他がかかってればうまくいきそうだが…
- 182 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 16:00:15 ]
- スレッドセーフ版のライブラリを名乗るからには
そうなってんじゃないの?
|

|