【初心者歓迎】C/C++室 Ver.54【環境依存OK】
1 :
デフォルトの名無しさん :
2008/05/14(水) 01:00:02
前スレ
>>996 はstringstreamやstringの代わりに
(あるなら)wstringstreamとかwstringを使えって意味ね
お、995はstringとstringstreamなのか。 wstringとwstringstreamだと思い込んでいた。
STLをwstringstreamとwstringに変えてLPWSTRをLPCWSTRに変えたら出来ました。 本当にありがとうございました。 int i = 123; std::wstringstream ss; ss << i; std::wstring mes = ss.str(); LPCWSTR omes = (LPCWSTR)mes.c_str(); MessageBoxW(0, omes, L"型変換", MB_OK);
その場合キャストは要らないはず、というか キャストでなんとかするってのは、はじめのころは あんまし感心しないコードになることが多い気がする。
◆6月にマネージャパン、月刊アスキー、週刊アスキーの3誌が賞金総額2000万円の「シストレFXグランプリ」を開催
http://system-trading.jp/news/index.php?cID=3 5月22日より登録受付開始、6月2日よりグランプリ開始の予定。賞金総額2000万円。
デモトレードの優勝者には賞金三百万円がプレゼントされます。
▼トレード部門
初期資産500万円で、デモ取引のトレード収益を競っていただきます。
http://www.fx-gp.com/about/ ▼賞金総額
■社長特別賞(シストレソフト買取価格) 10,000,000円
●シストレソフト部門賞 1位300万円 2位100万円 3位50万円
●トレード部門賞 1位300万円 2位100万円 3位50万円
●前期MVP賞 50万円
●後期MVP賞 50万円
7 :
デフォルトの名無しさん :2008/05/14(水) 15:04:43
どこにも情報が無いのでこちらで質問をさせていただきます。 eVC++4.0 にて組み込み開発を行っているのですがどうしても下記のwarningが出てしまいます。 class 'Hogehoge' needs to have dll-interface to be used by clients of class 'Foo' 上記エラーが発生した原因はメンバインスタンス変数を static に変更し、かつ、ポインタ ではなく実体を持つように修正したからだと思われます。 class Foo { public: Hogehoge *hogehoge; }; ↓ class Foo { public: static Hogehoge hogehoge; }; warningの意味は何なのか? 原因は何なのか? また、解決方法のご存知の方、回答お願いします。
strncpy, snprintf, memcpy などの関数でサイズ引数を0にした場合の挙動って定義されてるんでしょうか? やっぱり自分でチェックした方が無難?
>>7 そのメッセージの前に警告番号とか出なかった?
あと警告やエラーはそれのみ?
>>8 それぞれの関数の仕様を確認すること。
「など」に対しては定義されてないので。
未定義や不定の条件に書いて無ければ、サイズ0もOK。
ただしサイズが負の数みたいな、
有り得ない値は逆に、何も書いてなければNG。
size_tだから負の値はない。 それでももちろんsize_tで表現できる最大値とか明らかにおかしいだろって値は存在するけど。
>>7 Hogeは具体的に何のクラス?
デフォルトコンストラクタがないとか値として持てないクラスじゃね?
>>8 ありがとうございます。WG14/N843というのを拾ってきたので読んでみました。
snprintf() についてはサイズ0を指定してもよくて、その場合書き込み先バッファはNULLでもいいみたいです。
strncpy()とmemcpy()ではサイズ0の場合については何も書かれてないので、サイズ0もOKみたいですね。
サイズ0のときにバッファをNULLにしてもいいのかどうかまではちょっとわかりませんでしたが…。
あと、サイズはだいたいsize_tで指定するので負になるという心配はあまりなさそうです。
>>12 サイズ0のときはNULLにして良いよ。
サイズ0なら、指定したバッファのアドレス自体にもアクセスしてはいけないから、
アクセスしたら関数側のバグになる。
何も書かれてないということは、未定義動作じゃないのかね?
派生クラスのコンストラクタから、 初期化リスト?経由で基底クラスのコンストラクタ を呼び、 そこから派生クラスで実装されている純粋仮想関数を呼びたいのですが、不可能でしょうか? これが出来ると基底クラスのコンストラクタを再利用出来るし、違う処理(初期化)が必要な部分は 仮想関数の実装を変えるだけでいいので便利だと思ったのですが。
>>15 できません
基底クラスのコンストラクタ実行中は派生クラスは未構築だからです
>>16 やはりダメですか・・・
うーん。自分の設計が悪いせいか、基底クラスのコンストラクタ今一役立たずだな・・・
>>7 >warningの意味は何なのか? 原因は何なのか? また、解決方法のご存知の方、回答お願いします。
英文のままですね。英文の意味が判らないのなら鼬害でしょう。
まぁ、静的なメンバ変数は明示的に実体化しないといけないので普通の環境でもリンクエラーになるわけですが。
>>17 簡略化した例を示せば賢い人が答えてくれるかも
多分C++ではそういうときにはテンプレートの出番になると思うけど
>>14 >何も書かれてないということは
いや、書かれていることになる
上の例で出ている関数などでバッファポインタとバッファサイズを取るものは、
[buf, buf+size) の範囲内がアクセス可能ということを要件としているので、
size==0のときはbufのアドレスが何であれ要件を満たすことになる
>>15 似たようなことをする方法はいくつかある
・仮想関数をvfuncとして、基底クラスにinit()などを用意して、
派生クラスのコンストラクタから呼ぶ
※ 基底ctor -> 派生ctor -> 基底init() -> 派生vfunc()
・基底コンストラクタに関数ポインタ類を渡す
・templateクラスにして継承関係を逆にする
※ template<class T> class base : T {};
ostringstreamクラスに、 ostringstreamオブジェクトの先頭に任意の文字列を追加できる関数ってありますでしょうか?? 探しても見つからなかったのですが。
>>21 こんなことならできる
int main()
{
using namespace std;
string t("abc");
ostringstream s;
s << "xyz";
s.seekp(0);
s << t + s.str();
cout << s.str() << endl;
return 0;
}
>>21 一応ストリームなんだから、そういう操作は仮に出来ても勧められないな・・・
前後だけで良いならfront側とback側にstringstreamを持ってstr()時に
結合するラッパーを作るという手はある
超手抜きで書くと
struct {
ostringstream front;
ostringstream back;
string str(){return front.str() + back.str();}
};
またはstd::list<std::string>で構築して、必要になった際に全結合するなど
24 :
23 :2008/05/15(木) 00:10:53
リロードしてなかった
>>22 が手軽で良いかもな
それと
>>23 のfront云々のところは素でボケてたので無かったことに・・・
>>19-20 レスありがとうございます。
なるほど、テンプレートや関数ポインタですか。
しかしC++は奥が深そうですね・・・
Yo Yo俺ニート!
27 :
7 :2008/05/15(木) 12:11:02
>>9 質問するのに肝心な部分を書いてませんでした。
warning C4251 がエラー番号に該当すると思います。
>>11 規約としてデフォルトコンストラクタ、デストラクタは定義
しなければならないのでその点は問題ありません。
>>18 >まぁ、静的なメンバ変数は明示的に実体化しないといけないので普通の環境でもリンクエラーになるわけですが
cppファイル内で実体化させているのか、という意味ならば実体化させているので
その点は問題ないように思います。
試しにstaticをはずしてみたのですが、同様のエラーでした。
NULLチェックやdelete処理などが面倒なので実体を持つようにし、かつ、1つのシステム内で
唯一1つのインスタンスしか使用しないのでstaticで良いじゃないか?
staticにするとわざわざどこかのクラスから参照やポインタで辿っていかなくても Foo::hogehoge
とアクセスできるから楽じゃないか?
と安易に思ったのが失敗だったんでしょう。
C4251 だけ書いて内容書かないのは、こっちで調べろってこと?
29 :
7 :2008/05/15(木) 12:30:25
>>28 言っている意味がわからないのですが、こちらでどう調査しても
warning C4251: 'hogehoge : 'class 'Hogehoge' needs to have dll-interface to be used by clients of class 'Foo'
しかわからない
上記warningが発生した原因は特定インスタンスメンバをポインタではなく、static かつ 実体として持つようにした
というのは 7 で書いたつもりです。
言葉足らずのところはこちらのミスですので謝りますが。
エラー番号ではなく警告番号でしたが、どう調査してもC4251しかわかりません。
>>29 Hohehogeの宣言を晒してくれなきゃワカンネ。
エラーが起こる最小のコードをup
31 :
デフォルトの名無しさん :2008/05/15(木) 12:46:16
>>31 sort()とやらはgccの拡張機能である、関数内関数定義を行っているだけで呼び出していないから。
他にもいろいろ突っ込みどころだらけだが……
なんか、ロジックをいろいろ寄せ集めただけっぽいな。 ソートを自分で書くのが目的なら、渡すデータ型に注意だ。
34 :
7 :2008/05/15(木) 13:00:59
>>30 そういうことですか!!
確かに質問するにあたって情報が足りなかったですね。
warningが発生するHogehoge最小ソースは
class Hogehoge
{
public:
Hogehoge(){};
virtual ~Hogehoge(){};
};
です。
35 :
31 :2008/05/15(木) 13:05:37
>>32 main関数の前に
void sort(int *p,int n);
を付け加えました。
他に間違ってるところってどこですか?
>他に間違ってるところってどこですか? たくさん。あり過ぎて指摘する気にもならん。 まぁ、作った関数は呼ばなきゃ意味がないことくらいは判るだろうから、 後はコンパイラのエラーメッセージをよく読んで順に潰せ。 そうそう、gccを使っているだろうから、gcc file.c -ansi -Wall -pedanticすることをお勧め。
37 :
32 :2008/05/15(木) 13:10:43
>>35 私の指摘をちゃんと読んでますか? 「関数呼び出し」って、理解できますか?
class HogeHoge { public: HogeHoge(){}; virtual ~HogeHoge(){}; }; class Foo { public: static HogeHoge hogehoge; }; int main () { Foo myClass; return 0; } 問題なく通るけど…
39 :
38 :2008/05/15(木) 13:14:35
VC++2005EE
40 :
32 :2008/05/15(木) 13:15:08
>>34 >38だとhogehogeの実体を参照しないからエラーにならないかと。
Hogehogeだけ抜き出さずに、実際にそのエラーが出るソースを作って貼ってみては?
41 :
7 :2008/05/15(木) 14:08:53
さらに色々調査してみたところ、ソースコードというよりも環境が怪しい気が してきました。 もう少し調べてみます。
もうこなくていいよ
> HogeHoge(){}; > virtual ~HogeHoge(){}; セミコロン要らないだろ
struct point{ double x; double y; }; struct point q[200]; memcpy(q,p,(n+1)*sizeof(struct point)); これってどういう事をやってるんですか?
pが指す所から(n+1)*sizeof(struct point)バイトqの所にコピーしてる
>>45 恐らくはstruct point * pがあるとして、
先ずはpoint構造体の要素数200の配列qを宣言している。
続いてその配列qに、point構造体(n+1)個分のデータを配列pからコピーしている。
この部分は、for (int ic = 0; ic < n + 1; ++ic) q[ic] = p[ic];とほぼ同等。
すいません。 int func(int n,struct point p[],double d){ struct point q[200]; ; memcpy(q,p,(n+1)*sizeof(struct point)); } みたいに構造体が引数で渡されています。
>>48 「構造体」ではなく、「構造体へのポインタ」ね。つまりは、>47。
なるほどわかりました。 実際のpの大きさがソースを書くときには不定なので、 for文での代入をしていないってことでしょうか?
>>50 いや違う。pの大きさは、常に一定だ。何故ならpはポインタ変数だからだ。
pが指す領域のサイズについてはnに依存するわけだが、forループでも勿論巧くコピーできる。
では何故memcpy()を使うかというと、保守性よりも(見かけ上の)効率を優先したか、単に習慣か、
書いた人間にでも聞かないと判らないだろう。
for文で1個ずつでもいいけど、丸ごと全部いっぺんにやったほうが早いべ
いいえ、一概には言えません。まともなコンパイラにまともに最適化させてやれば恐らくは、目に見える速度差はないでしょう。
書く量だって少ないし、コーディングも早いだろ。
55 :
45 :2008/05/15(木) 18:49:17
いろいろ教えていただきありがとうございました。
>>54 >memcpy(q,p,(n+1)*sizeof(struct point));
39文字
>for(int i=0;i<n+1;++i)q[i]=p[i];
32文字
VC++でインラインアセンブリを使うとき、 疑似命令によくある、生データを直接コードに埋め込む事って、どのようにすればいいのですか? テーブル参照のようなことを仕様と思ったのですが、やり方がよくわからなくて…
>>53 逆に言えば
memcpyみたいな動作をする命令があるから、
まともでない(古い)コンパイラだとfor使うより遙かに速く動作する
そういう意味では書く人の習慣の影響が強いが
だんだんコンパイル速度が遅くなってきたので、参照箇所の 多いクラスにPimplを導入しようかと思ってるのですが、Pimplに すると問題のあるケースなんてのもあるんでしょうか?
>>56 >memcpy(q,p,(n+1)*sizeof(*p));
29文字
std::copy(p,p+n+1,q); 21文字
>>59 pimplを経由することによる性能上のオーバーヘッド
>>59 メモリ確保のオーバーヘッドと、メモリ確保に失敗する可能性の増加。
>>62 ,63
なるほど。速度が重要な物や大量に生成される物には
避けた方が良さそうなんですね。
>>59 仮にPimplによる問題が出ても、
大した手間無く対処出来るから気にする必要無いよ。
>>59 相互参照の必要な場合が多いとソースが汚く見えるようになる。
すいません、質問お願いします。 独習Cで勉強しているのですが、月での実効体重だす問題で関数を作ったのですが float moon(void) { float weight; printf("体重を入力してください:"); scanf("%f",&weight); return weight*(17/100); } という関数を作った時に 「return weight*17/100」や「return weight*0.17」時は正しい値を返してくれるのですが、 自分が分かりやすいように式を()で囲うと正しい値を返してくれずに0.00000という値が返ってきます。 理由がわからないのですが、どなたか分かる方教えて下さい。
すいません、
>>67 ですが、環境はDev−C++です。
intをintで割ったときでも値はint。つまり(17/100)は小数点以下が切り捨てられて0になる。 (17.0/100)とかならOK
>>67 17と100が整数だから、17 / 100の結果も整数(切り捨てで0)になってしまう。
weight * 17 / 100と書いたときには、(weight * 17) / 100と扱われ、
weight * 17がfloat型で結果を返し、それに整数100を掛けても
やっぱりfloat型になるのでうまくいくという具合。
逆にいえば、17などをfloat型にすればいいわけで、
return weight * (17.0f / 100.0f);とすればうまくいく。
>>69 >>70 なるほど、型が大きいほうに合わせられるっていうのは数値だけの計算にも当てはまるんですね。
変数だけしかそういう風にならないと勘違いしていました。
非常に分かりやすい説明ありがとうございました。勉強になりました。
直書きの数値にも型はあるんだぞ
リテラルと言いましょう
すまん、用語には疎いもんで・・・
>>20 >・templateクラスにして継承関係を逆にする
> ※ template<class T> class base : T {};
これ、よく分からないので具体例あげてくれるとありがたい。
struct A { A() { f(); } virtual void f() = 0; }; struct B { virtual void f(){} }; を template<class T> struct X : T { X() { f(); } }; struct Y { void f() {} }; typedef X<Y> Z;
修正 > X() { f(); } X() { T::f(); }
質問です 先日基底クラスのデストラクタを仮想にし忘れ、メモリーリークというお約束のミスをやってしまいました。 この手のミスを無くしたいのですが、warningを出させる方法や、チェックツールなどはないでしょうか? 環境はVS6.0です。 仮想関数テーブルへのアクセスによるオーバーヘッドは現状気にしていないので、全てのクラス関数を仮想にしたいのですが、たまにつけわすれてしまうのです。
初心者です。 C++を学ぼうと思ってるんですが良い参考書orWebページはありますか?
80 :
75 :2008/05/17(土) 10:09:49
>>76-77 ありがとう。
ただこの方法だと元々の継承関係が失われないかい?
(76はミスタイプと思うが、元々はstruct A : B)
質問者は継承関係は維持したいと思うけど。
81 :
75 :2008/05/17(土) 10:13:13
>>80 というか継承と同じことをテンプレートで実現するってことかな。あってる?
>>78 「メモリリーク 検出」とかでググれば解説してるサイトがいっぱいでてくる
>>78 デストラクタを仮想にした基底クラスを作って、クラスを作るときに必ずそれを派生して使うようにすれば忘れることはない。
>>83 それを忘れないようにするためって話じゃないのか?w
>>83 はルート基底クラス(C#とかのObject)を用意することで、
個別にvirtualを書かなくて済むようにした方が良い、って意味なのでは?
でもそしたら今度は、それ継承するのを忘れない方法は?
って話になりそうだけど。
クラスを定義するときに専用のマクロを使うことにするとか
>>87 それを忘れないようにするためって話じゃないのか?w
コピペ煽りに律儀に答えなくても
class NewClass : public Object の : public Objectを書かなかったらやっぱりバグるわけだしなー それじゃ意味ないだろう 継承しなければコンパイルエラーになるようにできるなら、別だが。
なんでループしてんの?
struct Object{virtual ~Object(){};}; #define STD_STRUCT(NAME) struct NAME : public virtual Object #define STD_CLASS(NAME) class NAME : public virtual Object STD_CLASS(ClassA) { public: ~ClassA(){std::cout << "~ClassA" << std::endl;} }; STD_CLASS(ClassB), public ClassA { public: ~ClassB(){std::cout << "~ClassB" << std::endl;} }; void f() { ClassA* p = new ClassB(); delete p; }
そしてそのマクロを使うのをつい忘れるわけですね、わかります
いや、お前ら質問者の意図無視しすぎだろw
ツールでなんとかしたいと言ってる人間に、忘れないようにマクロを使いましょうってどんな返事なんだ 俺は必要としたことないから知らんが、書式チェックツールくらいないのか?
virtual忘れをチェックしてくれるツールくらい自分作ればいいんじゃね デストラクタは先頭に ~ が付いててわかりやすいから、 その前にvirtualが付いてるかどうかくらい簡単に判定できそう そもそもデストラクタを書いてない場合は役に立たないが・・・
>>96 >>78 を読む限り、まずミスを無くしたい、という目的があって、
その方法として警告、チェックツール「など」、
と手段の例を挙げているので、
同じく、ミスを無くす/減らす方法を書いてるレスが
意図を無視してるようには見えないけど?
とりあえず、抽象型へのアップキャストは極力控えて、 総称型プログラミングを覚えた方がいいと思った。
>>100 実行時ポリモーフィズムが必要な場合はどうするの。
だから極力控えて、って・・・。
静的な方が安全というのは分かるが、 export のない C++ でジェネリックばっかやってると コンパイルが重くて現実的じゃない事も。
>>98 そしてそのツールでチェックするのをつい忘れるわけですね、わかります。
>>104 make使うならMakefileに組み込めばおk。
総合環境なら・・・ カスタムビルドステップ?
>>104 最悪、考え方としてはおかしくなったときにチェックすればいいわけだし。
あれ?ちょっとずれるが なんかの統合環境で、virtualな関数をオーバーライドする時にvirtualつけておかないとワーニング出すって設定できたよな? これはvirtualですよー、わかってますかー?って意味合いで
微妙に宣言間違えて、いつの間にか別の仮想関数が作られちゃうのを防ぐ方法ってないかな。 delphiならviryualで新しく作って、overrideでオーバーライドするから間違えたらエラーになるんだがなぁ
virtualだな
override は最近の言語によく取り入れられているね。 あれはいい仕様だと思う。
>>107 それは余計なお世話な気もするな。コーディング規約レベルだと思う。
いんや。 仮想関数じゃないつもりで関数追加して泣きを見るのを防止できる。
なんにしろON/OFFできりゃいいんだよな overrideはいい仕様だ
Java みたいに問答無用で仮想関数にする言語は typo で泣くことになる。
そうした事もあって、C#では明示的にoverrideする必要になりましたとさ
それにならって、javaもoverrideをチェックする アノテーションが用意されました。
そしてC++はほったらかしと。
C++ は互換性を異常に気にするからな。
override付きのときだけチェックしてくれれば良いんだけどなぁ。その他(virtual付き/何もなし)の時は今まで通りで。
それはあんまり override の価値がない気が
override が無い時に警告出してくれるならいいけど
本に Num = rand() % 100; で、0から99までの範囲に含まれる値を取得できる と書いてあるんですが、 どうやったらこうなるんですか?
どうって見たまんまとしか答えようが… rand() → ランダムな整数を取得 % 100 → 100で割った余り
■■■■■■■■■■■■■■■■ ■ ■ 違う板にコピペすると、四角の枠の中に ■ ■ メッセージとURLが現れる不思議な絵。 ■ ■ ■ (´?ω?`) ■ (その仕組みがリンク先に書いてある) ■ ■ ■ ■ この原理を応用すると、まったく新しい ■ ■ コピペが作れる予感。 ■■■■■■■■■■■■■■■■
てst
■■■■■■■■■■■■■■■■
■ ■ 違う板にコピペすると、四角の枠の中に
■ ■ メッセージとURLが現れる不思議な絵。
■ ■
■ (´・ω・`) ■ (その仕組みがリンク先に書いてある)
■
http://kat.cc/19b06f .■
■ ■ この原理を応用すると、まったく新しい
■ ■ コピペが作れる予感。
■■■■■■■■■■■■■■■■
std::listのイテレータって、リストに追加や削除といった操作をしても 取得しなおさなくて使えますか?前にvectorで痛い目見たもんで・・・
>>127 すまん勘違いした。
listでのinsertは全てのイテレータを無効にしない。
eraseは対象イテレータのみ無効になる。
つまり、大丈夫。
1クラスにつき1ヘッダ(全定義)+1ソース(全実体) ↑のやり方でやっていたのですが、どうも拙いと気付きました 巧いファイル構成を身に付けたいのですが、中々しっくり来る資料が…orz コレ読んどけよって書籍やソースなどあればご指導願いします
A L L h p p
133 :
131 :2008/05/19(月) 22:32:00
すみませんでした。出直してきます
134 :
デフォルトの名無しさん :2008/05/19(月) 23:42:52
質問です。VC++2008を使用しています。 以下のリソースファイルをプロジェクトに加えてコンパイルすると Visual Studioが強制終了してしまいます。なぜでしょうか? //--- menu.rc--- #include <windows.h> #define MENU_NEW 2000 #define MENU_OPEN 2001 SAMPLE03 MENU DISCARDABLE { POPUP L"ファイル" { MENUITEM L"新規作成",MENU_NEW MENUITEM L"読み込み",MENU_OPEN } }
Lokiライブラリに小規模アロケートに特化したアロケータがあったと思うんですけど、Lokiのライブラリよりもメジャーなもので 同じニーズに応えたライブラリはありませんか?
>>131 そのやりかたで何が拙いと思ったのか気になる。
>>135 Loki のやつは知らないけど、たぶん segregated strage だろうってことで boost::pool でいいかな?
138 :
デフォルトの名無しさん :2008/05/20(火) 11:45:17
とりあえずSTARTUPINFOにパイプを入れて子プロセスと繋ぐ事はできましたのですが、 すでに開いてるコマンドプロンプトの標準入出力を別のパイプに繋ぐことってできますか?
>>122 でもそうやって乱数を取得しないほうがいいんだよ。
C/C++ で、右シフト、左シフトを行う ">>" , "<<" はあるのですが、アセンブリで言うところの ROL (ローテート) に相当する演算子は C/C++ では用意されてないのでしょうか?
ありません。
>>141 そうですか。どうもありがとうございました。
_rotl
>>143 なるほど、そんな関数があるんですね。教えてくださってどうもありがとうございました。
童貞力に相当する演算子もないな。
ひょっとして、 _rotl なんかの代わりに int a; a=0x0000000f; _asm{ MOV EBX,a ROL EBX,2 MOV a,EBX } なんて書くのもアリだったりする?それとも、こういう実装の仕方は普通はしない?
しないわ ビット演算組み合わせるとか
>>147 なるほど、分りました。お答えくださってどうもありがとうございました。
gccなら
w = w<<s | w>>(32-s)
みたいにするとrotlにしてくれる場合がある。
確実にしたければ以下のようなインライン関数を作って呼び出せばOK
static inline uint32_t rotl(uint32_t src, uint8_t n) {
__asm__("roll %2,%1"
: "=r"(src)
: "0"(src), "cI"(n));
return src;
}
gccはインラインアセンブラも最適化の対象になるので、
単純に
>>146 みたいにするとおかしなことになるかも?
確実にrolにならないといけないような場合はともかく、 それ以外の場合で環境依存を強めるのは止めようぜ・・・。
151 :
デフォルトの名無しさん :2008/05/20(火) 22:54:25
質問です。 環境 VC6.0 / Windows2000 において、以下のコードで i=m_NoList.begin()実行後に、 アクセスバイオレーションエラーが発生します。 デバッグでは、begin→STLのソース NEXT (_HEAD)・・・という箇所で 不正アドレスを参照しているように見えますが、原因が特定できません。 腑に落ちないのは、 if(m_NoList.size()>0)で要素があるにもかかわらず、 beginを実行するとエラーが発生するという点です。 使い方が間違っているのかもしれませんが、 ご見識のある方がいらしましたら、アドバイスお願いします m(__)m Mutex.get(); ←ミューテックスでロックする std::list<ListNo>::iterator i; if(m_NoList.size()>0) { for ( i=m_NoList.begin(); i!=m_NoList.end();i++ ){ ←beginでエラー発生 if ( (*i) == No ) { Mutex.release(); ←ミューテックスを開放する return true; } } Mutex.release(); ←ミューテックスを開放する }
Mutexとやらを外しても同じエラーなの? ListNoの型は何?
質問です。以下のプログラムの最終的な出力が7になるのがどうしても理解できません。 最初の*&x=,x=が2,2になるのはわかるんですが、2度目の*&x=が5になるのがわからなくて・・・ もし*&x=5なら最後の出力は10になる気がするのですが。 #include <stdio.h> int x=1; void f(int *p){ *p+=x; } int main(void){ int y; f(&x); printf("*&x=%d,x=%d\n",*&x,x); { int x=5; printf("*&x=%d,x=%d\n",*&x,x); f(&x); y=x; } x=y; printf("%d\n",x); return 0; }
グローバル変数よりローカル変数の方が優先されるんだよ でも二回目に表示されるxはスコープをy=xを終えた後 スコープを抜けて無効になるから結果が7になる
日本語が… >二回目に表示されるxはy=xを終えた後 の間違いでした
>>153 *&xはいつもxと同じ、わざわざxと並べる意味はない。
外のxと中のxを別の変数だと思えば、理解しやすいと思う。
int グローバルなx=1;
void f(int *p) {
*p+=グローバルなx;
}
int main(void) {
int y;
f(&グローバルなx);
printf("*&x=%d,x=%d\n",*&グローバルなx,グローバルなx);
{
int ローカルなx=5;
printf("*&x=%d,x=%d\n",*&ローカルなx,ローカルなx);
f(&ローカルなx);
y=ローカルなx;
}
グローバルなx=y;
printf("%d\n",グローバルなx);
return 0;
}
C++の継承について質問させてください。 class AAA class BBB : public AAA class CCC : public BBB という継承しているクラスがあった時に、 AAA *pA; BBB *pB; CCC C, *pC; pA = &C; pB = &C; pC = &C; と書く事ができるのですが、 pA = &C; pB = &C; は、何でコンパイラに怒られないんでしょうか? 継承というのは、継承したクラスとしての扱いもできる、というような イメージでいいんでしょうか?
同じクラスから派生した物だったら大体似たようなもの筈だから 全部同じポインタ変数で扱えて便利なことも多い
159 :
153 :2008/05/21(水) 01:07:19
>>154-156 解答ありがとうございました。
よく考えてみれば、int x=5;は代入ではなく変数の宣言でしたね…
ということは、最初のf(&x)でグローバルxにグローバルx+グローバルx(1+1=2)が代入されて、
次のf(&x)ではローカルxにローカルx+グローバルx(5+2=7)が代入され、
最後にローカルx→y→グローバルx(出力)という考え方でよいのでしょうか。
そうそう
161 :
157 :2008/05/21(水) 01:25:15
>>158 さん
レスありがとうございます。
> 同じクラスから派生した物だったら大体似たようなもの筈だから
とありますが、構造体の場合は、
中身が全く一緒だとしてもコンパイルでエラーが出ますよね?
struct AA
struct BB
AA *p, A;
BB B;
p = &A;
p = &B; ←キャスト違い
p = (AA*)(&B)
上のようにキャストを変更してあげればコンパイルは通りますが、
継承したクラスの場合は、勝手にこのような処理をしてくれているのでしょうか?
何でクラスの継承の場合は問題なくコンパイルが通るのかが気になってしまって…。
そうしてくれるようにしないと継承というシステムの本領が発揮できないから つまりそうなるようにわざわざ作った
派生クラスってのは基底クラスのオブジェクトでもあるってのが言語上の仕様だからな
別々のモノを中身が全く一緒だと知ってるのは人間だけだもんなー
Cの構造体的な発想では 基底クラス←派生クラス っていうポインタの代入はダウンキャストだもんな。 そこがいまだにしっくり来ない。
166 :
157 :2008/05/21(水) 01:46:32
皆様ありがとうございます。 継承したクラスとしての扱いもできるのは とりあえずそういう仕様だという事なのですね。 おかげさまで勉強になりました。 ありがとうございました!
#include <stdio.h> int main(void){ int a[]={0,0,0,0}; int k=1; a[k]=1; a[a[k]]=2; printf("%d\n",a[a[k]]); return 0; } で、出力が2ではなく0になるのですがどうしてでしょうか。 ご教授のほどよろしくお願いします。
#include <stdio.h> int main(void){ int a[]={0,0,0,0}; int k=1; a[k]=1; a[a[k]]=2; ←ここで a[a[k]]→a[a[1]]→a[1]=2になってる printf("%d\n",a[a[k]]); ←つまりここでは a[a[k]]→a[a[1]]→a[2]なので0のまま return 0; }
>>167 #include <stdio.h>
int main(void){
int a[]={0,0,0,0};
int k=1;
a[k]=1; // a[k] == a[1]
a[a[k]]=2; // a[a[k]] == a[a[1]] == a[1]
printf("%d\n",a[a[k]]); // a[a[k]] == a[a[1]] == a[2]
return 0;
}
ついでにご教授じゃなくてご教示な
そんな漢字の細かい事どうでもいいんじゃい ボケ 教えて感がでてればええんじゃい
正しい日本語を使おうぜ。 170が丁寧に教えてくれただけでもありがたいと思わないと。
>>171 漢字が違うのではなく、言葉が違うのです。
自分の間違いをできる限り「小さくてどうでもいいこと」と思いたい雑魚特有の気持ちはわかりますが、
たった2文字でも十分過ぎるほど馬鹿さが滲み出てしまう、割と致命的なことですので、
二度と間違えないよう気をつけることをおすすめします。
>>136 大規模にするにつれてヘッダの量に煩わしさを感じたのですが
普通は纏めないほうが修正が容易で良いと評価されるのでしょうか?
175 :
デフォルトの名無しさん :2008/05/21(水) 07:28:12
ヘッダのヘッダをつくる
.hと.cpp/.c一対で動くようにしておいた方が デバッグが楽だと思うんだけど
>>174 ヘッダを纏めるなんてとんでもない。無駄に依存関係が膨らむだけだろ。
>>161 たまたま同じ構成だっただけで目的が同じとは限らないからな。3次元の座標の構造体が、3原色を表す構造体にコピーできたら困る品。
A.hpp class A {}; UseA.hpp #inlcude "A.hpp" class UseA { A m_obj; }; main.cpp #include "UseA.h" とするとmain.cppでA.hppまでインクルードされてしまい、回避するにはUseA.hppにて class A; UseA { A* m_p; } とするくらいしか思いつかないのですが、もっと単純な方法ってありますか? 具体的には、main.cppからはclass Aのインスタンスが作成できないようにしたい、ということです。
日本語で書き直してください。
>>179 無理です。名前空間で工夫してください。
namespace detail { class A{...}; } とか。
わかりました、ありがとうございます!
>>179 class UseA;
class A { friend UseA; ... };
サーバに送るデータをUTF-8に統一しようと思ったんですが、 sizeof(wchar_t) == 2ならUTF-16、 sizeof(wchar_t) == 4ならUCS4 って考えて実用上は問題ないでしょうか (Linux||Mac)&gcc、Win&(VC++||bcc)あたりで動けばいいかなと思ってるんですが ICU使うほどの処理でもないような気がするんです
wcrtombとか使えば、wchar_tの実装気にしなくていいと思うが
186 :
デフォルトの名無しさん :2008/05/23(金) 00:58:08
ベクトルについての質問です。 初心者ながら調べまわったのですがここにたどり着きました。 お願いします。 ベクトルの要素削除eraseは引数にイテレータを入れますが 要素参照のatのように添字を使用して要素を削除することはできないのでしょうか?
187 :
デフォルトの名無しさん :2008/05/23(金) 00:59:45
ベクターです
>>186 erase()ではできませんが、advance()辺りでIteratorを作ればできなくはありません。
x.erase(x.begin() + 1); こういうノリでいける気がするけどどうなんだか
>>184 Windowsのwchar_tはUTF-16で問題ないと思う。
Linuxのglibcのwchar_tはUCS4で問題ないと思う。
Mac OS X では wchar_tはサポートされていない。
それ以外のUNIXではwchar_tの中身はUnicodeではないことが多い。
>>189 いけるね。
v[3]とv.begin()+3は結局同じ要素をさしているけど
後者はイテレータとして扱われる。
Accelerated C++でもそういう例が出てくる。
質問です 型の詳細がわからないオブジェクト同士の比較(メンバ変数の比較) をするのにいい関数ってありますか?
「型の詳細がわからないオブジェクト」とは、具体的にどういう状態なのか。 「比較」というのは、どういう比較をしたいのか。この場合の「いい」とは何を指すのか。 現状も願望も曖昧に書かれているから、答えようが無い。
>>189 細かいことを言うと、あとでvectorをやっぱりlistにしたい
何てことになったときに書き直さなきゃならなくなる。
なのでadvanceで書いておいたほうが良いかも知れない。
advance() は変数用意しないと使えないのがウザイ。 そこで boost::next() ですよ。
196 :
デフォルトの名無しさん :2008/05/23(金) 12:13:17
ベクトルの質問をした者です。
advance()とイテレータの加算で解決できました。
ありがとうございました。
>>195 boostというライブラリさえ知りませんでした
おかげで知識の幅が広がりました
良かったね。その調子で終わらないboostの勉強をしよう。
char型の配列って、初期化の際に char ch [4] = { 0x10, 0x11, 0x12, 0x00} みたいに値を代入できますが、 char ch [4]; char ch = { 0x10, 0x11, 0x12, 0x00}; みたいに、一旦宣言だけしておいて代入、みたいなことはできませんよね。 では、クラスのchar型のデータメンバをコンストラクタで初期化する時に char ch [4] = { 0x10, 0x11, 0x12, 0x00} みたいに格納したいときはどうすればよいでしょうか?? strcpy()は使えないですよね??
char ch [4]; char ch = { 0x10, 0x11, 0x12, 0x00}; 2行目、先頭のcharが余計でした。
>>198 ch[0] = 0x10;
ch[1] = 0x11;
ch[2] = 0x12;
ch[3] = 0x00;
ありがとうございます。 やっぱりコンストラクタでやる場合はそれしかない感じでしょうか。 あとはstaticメンバにしてグローバル領域で初期化ぐらいでしょうか・・
static const char InitVal[4];なメンバを作っておいて、コンストラクタ内で複製すればいいんじゃないかな
代入できるところならstrcpyもできるよ。コンストラクタ内でも。
using namespace boost::assign; vector<int> v, v2; v = list_of(1)(2)(3); // v = { v2 = list_of(0).range(v).range(v.begin(),v.end())(4); // v2 = [0,1,2,3,1,2,3,4]
ミスッた boostにこんなのもある。 生配列に使えたか分からんけど using namespace boost::assign; vector<int> v, v2; v = list_of(1)(2)(3); // v = {1,2,3} v2 = list_of(0).range(v).range(v.begin(),v.end())(4); // v2 = [0,1,2,3,1,2,3,4]
それくらいなら軽ーく自分でもかけるんじゃないか? boostが使えなくてもoperator()()で糖衣構文が作れるから忘れないでいて欲しい。
char input[255] , output[255]; scanf("%s",input); scanfで読み込んだファイル名をhoge.txtとして outfileにhogehoge_hoge.txtと代入するにはどうしたらいいですか?
fopenを使えばいいよ
使い方がわからないです
ぐぐぐぐぐぐぐぐぐぐぐぐぐぐぐれかす
グーグルになぜかアク禁くらってるんっす
212 :
デフォルトの名無しさん :2008/05/23(金) 19:14:09
ならやふれ。げいつれ。ぐーれ。いんふぉしーくれ。
stringstream ss; ss << "abcdefghijklmn"; ss.str().replace(2,1,1,'x'); fout << ss.str(); みたいなことをしたいのですが、文字列が"abcdefghijklmn"のまま出力されます。 こういうことはできないのでしょうか??
>>214 stringstream ss;
ss << "abcdefghijklmn";
string str(ss.str());
str.replace(2,1,1,'x');
fout << str;
std::stringstream::str()は呼ばれるたび一時オブジェクトを生成して返すから文字が変更されない、気がした。
詳しくはC++の仕様書なりライブラリドキュメントを参照すべし。
あれ? const string &str(ss.str().replace(2,1,1,'x')); の方が無駄なインスタンス作らないかも。
Cで趣味でゲーム作ってたりするのですが、 プログラミング大会とかゲームコンテストってあるのですか? できれば高校在学中にどうにかして成果をあげたいので・・・ ゲームの作り込みとかもあるんだろうけど、 意見ある方や知ってる方などいたら教えてくださいな
>>216 マイク、replaceの戻り値はstring&だから、それヤバイよ。
219 :
デフォルトの名無しさん :2008/05/23(金) 22:55:59
>>219 HSPコンテストは出しましたw
1次予選は受かったものの賞はもらえませんでしたが・・・
HSPでゲームやツールを作ったくらいでは成果にならない、
ということも耳にします。
221 :
デフォルトの名無しさん :2008/05/23(金) 22:59:53
ハル研究所 プログラミングコンテスト2008
と、いうかCでつくってもそれは同じことだよ
223 :
デフォルトの名無しさん :2008/05/23(金) 23:02:18
プログラムと、ゲーム作りは別だろう。たとえば軽量で速いプログラムが作れても 面白いゲームが作れるかは別。
224 :
デフォルトの名無しさん :2008/05/23(金) 23:04:30
プログラムが出来なくても、ドラクエの堀井裕二とかいるし、絵や音楽が上手ければ ゲームの一部の開発は出来る。ゲームが作りたいの?
よく
>>224 という話を見るが堀井雄二は昔は自分で作っていました
論旨はわかるけど、別の人を例に出したほうが良いでしょう
俺はHSPコンテストで賞もらったなぁ。 丁度ばら撒くように賞を出してた頃だったからあれはあれで結構ショックだった。 でもあんなもの何の役にもたたんよ。同人だからな。どうせ219はネタのつもりで書いたんだろう。
まて、質問者は 「ゲームやツール」 と言ってるのに 何でゲーム限定になってるんだ?w
ツールの大会ってあんの? 競いようがない気がするw
>>225 堀井は言うほど作れなかったよ。
某雑誌の投稿者管理のプログラムを作るのが関の山。
それも、データを変換するとか圧縮するとかいう発想がないために
オンメモリでしか処理できなくて最後は破綻していた希ガス。
>>217 コンテストもいいのですが、オープンソースの世界にとびこむのはどうでしょうか。
時代遅れの資格試験・どこの馬の骨ともわからないコンテストよりは、はるかに「実績」「キャリア」となり、多くの人に評価されると思います。
Vine Linux のメンテなどは、非常にありがたがられるでしょうね。
年をとると、いろいろなしがらみがあって、こういった方面に手を伸ばすリソースがないのです。
232 :
デフォルトの名無しさん :2008/05/23(金) 23:42:45
そのエネルギーを仕事に注いだほうがより評価されるという。
stringstream ss; ss << "abcdefghijklmn"; fout << ss.str().replace(2,1,1,'x');
>>233 おい
const string& を std::replaceするのか
strは std::string std::stringstream::str() const; だよ。
236 :
233 :2008/05/23(金) 23:58:09
>>234 string stringstream::str( ) const;
()の後のconstは、メンバ変数をいじらないと保証できるからconstなインスタンスでもアクセスできるメンバ関数であることの宣言 何か日本語的におかしいかな?
>>237 そこじゃなくて、戻り値がstd::stringだろうと。
値返しでしょ?
なんという糞な実装\(^o^)/ 1GBのstr()があったら丸々コピーするのか
コピーしなかったら、stringstream のインスタンスの変更に依存しちゃうじゃん。
至極まともな実装だと思うが。
書いてる本人らは分かってるだろうけど、
初心者スレなので、初心者のために説明書いておくてst
>>215 は問題ない実装。
ただし、ss.str()でインスタンスが作られて、
string strでもう一つインスタンスが作られるので、
ほんの僅かの無駄がある。でも通常気にすることは無いレベル。
>>216 は、その僅かな無駄も無くそうとしていて、
const参照による一時オブジェクトの束縛を利用しようとした。
しかし、replaceの戻り値が一時オブジェクトでないので、
束縛出来ず消えてしまい、&strは不正な領域を指してしまう。
>>233 は関数から戻るまで、その引数が生存することを利用してる。
str()で作られたインスタンスが、replaceで変更され、
「<<」で出力された後に消える。一番無駄の無い実装。
>>239 そういう場合、普通はstr()などせずにストリームアルゴリズムで扱う。
>>240 データはstringstreamが握ってるんだから、
std::stringのdata()やc_str()のように、データへの参照を返す手段も
あったほうが良かったよねってことじゃないの
>>243 string::c_str()の存在だって本当は褒められたもんじゃない。
>>244 const参照は一時オブジェクトを束縛できるよ。
オブジェクトの寿命が参照のスコープまで延命される。
248 :
244 :2008/05/24(土) 00:57:35
>>246 , 247
うぉ、マジだ。初めて知ったよ、サンクス。
>>230 別にプログラマとして「凄腕だった」わけじゃないけど、
一応テニスゲームが入選したことでエニックス(現スクウェア・エニックス)と縁できた人なわけで、
投稿者管理のプログラムが関の山っていうのは、えらく誤解を招く表現だと思うけど。
いずれにせよ、「プログラミングという行為のリアリティ」を経験した上でゲームデザインやってる、
というのは大きいね。
そのフィーリングをまるで知らず、何か肝心のところでピント外れのSEや文系上司、多いものな。
ポートピアシリーズの最終作にあたる 軽井沢誘拐案内までは シナリオ・音楽・グラフィックに加えて プログラムも組んでたとおもたけど。
251 :
217 :2008/05/24(土) 01:48:53
たくさんのレスをいただきましたが、質問要項に関わるレスだけレスします
みなさんありがとうございます
軽い処理、ゲームを作るのはプログラマの永遠の課題ですねw
自分のゲーム重いので・・
>>221 HALってこんなこともやっていたのですね・・初耳でした
参考にさせていただきます
>>228 おお このようなものまで
多少調べたのですが出てきませんでした
ありがとうございます、参考にさせていただきます
VC 2005で #include <iostream> #include <string> int main(){ std::wcout << L"あ" << std::endl; return 0; } 何も表示されません。どうすれば良いんですか。
自己解決です。 std::wcout.imbue(std::locale("japanese")); したら使えるようになりました。ありがとうございました。
ファイルの入力で質問です。 内部でwchar_tを使用しているので、バイナリファイルの読み込み にwfstreamを使用しようと思ったのですが、read()のバッファの引数 がwchar_tになってしまうので、このままではwchar_tからcharに変換 するためにコストがかかってしまいます。 C++の標準ライブラリの範囲内で、ファイル名にwchar_tを使いつつ、 char形式のプレーンなバイト列を読み込む方法はありませんでしょうか? よろしくお願いします。
すいませんボケてました、 wfstreamでもファイル名はwchar_tではなくてcharですね… 標準ライブラリの範囲内ではファイル名にwchar_tは使えないのでしょうか…
すいませんちゃんと調べるべきでした。 fstreamのコンストラクタの引数で、wchar_tも取るんですね。 どうもwfstreamでないとwchar_tを取らないと思い込んでいました。 失礼しました。
fstreamにワイド文字のファイル名を渡せるのは、VC8以降のMS独自拡張じゃないか? 移植性は無いように思う
260 :
214 :2008/05/24(土) 18:33:32
こんなレスが付くとは。ありがとうございました。 なんだか色々複雑なんですね・・。とても参考になりましたm(_ _)m
>>258 それはVisual C++など一部処理系の独自拡張。
一般には(現行規格では)、ファイル名の引数の型は
const char*であるものしか存在しない。
もし仮にBoostを使って良ければ、Filesystemのfstreamが使える。
こいつは、ワイド文字列でもファイル名を指定できるようになっていて、
ワイド文字列でファイル名を指定できない環境では、
マルチバイト文字列に変換して開くようになっている。
vc8を使っているんですが、 #include <fstream> std::fstream f(L"test.txt", std::ios::out); f << L"テスト"; としても何も書かれていないtest.txtが出力されるだけでうまく行きません。
#include <fstream> #include <locale> int main() { std::wfstream f(L"test.txt", std::ios::out); f.imbue(std::locale("")); f << L"テスト"; } 一応、元と合わせておいたけど、 出力だけならofstream/wofstreamで十分。
unicodeは内部で、unicodeで処理したいときだけ使う 入出力は、8ビットのやつにしとけ
VC2005EEって、テンプレートの特殊化できる? 自作クラス用にstd::swapを特殊化しようとして上手くいかないんだけど……。
特殊化も部分特殊化も出来るよ。
267 :
265 :2008/05/25(日) 12:23:23
ごめん、俺のミスだった。ちゃんとビルドできました。
http://www.geocities.jp/ky_webid/cpp/language/038.html ここに書かれてあるようにcとc++を同時に使うには、はじめに何を宣言したらいいですか?
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "math.h"
#include "time.h"
#include "sift.h"
#include "imgfeatures.h"
#include "kdtree.h"
#include "utils.h"
#include "xform.h"
#include "cv.h"
#include "highgui.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
こんな宣言したらエラーがでたんですが…
そのページは読めば extern "C" の説明だと分かるだろうけど、 何がしたくて、そういう宣言(というかinclude)したんだ? それとエラーメッセージくらい書かないと、 ここにエスパーは居ないよ。
何を使うことになっても良いように 最初から全部宣言してしまえ。と考えるからそうなる 必要になったら追加するように
>>268 #include <stdio>
これだけ
272 :
268 :2008/05/25(日) 13:07:57
1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2143: 構文エラー : '{' が ':' の前にありません。 1>c:\program files\microsoft visual studio 8\vc\include\cstdio(25) : error C2059: 構文エラー : ':' >c:\program files\microsoft visual studio 8\vc\include\cstdlib(18) : error C2143: 構文エラー : '{' が ':' の前にありません。 1>c:\program files\microsoft visual studio 8\vc\include\cstdlib(18) : error C2059: 構文エラー : ':' というエラーがだーーーーっとでます。
ソースファイルの名前は
>>272 で、それはCなのかC++なのかはっきりしてもらわないと困る。
>271 #include <stdio> これだけだとエラーでまっせ
環境もなー
>>276 環境はvisualstudio2005です
Cの関数を定義しているヘッダを extern "C" { #include "C_function.h" } って囲めばいいよ
ソースファイルの名前はなんなんだよ #include <iostream> はC++のヘッダーだから、 .cのソースファイルには使えないぞ。
class のインスタンスにsizeofを使うとデータメンバだけのサイズが返されますが、たとえば class Hoge { float f; }; float f[10]; Hoge hoge[10]; memcpy(f, hoge, sizeof(f)); とするとfにはHogeのfが順番に格納される、という理解は合っているでしょうか。
そのコードは多分多くの環境で期待した通りに動くが、クラスのメンバをそのようにコピーしてはいけない。 >>class のインスタンスにsizeofを使うとデータメンバだけのサイズが返されますが そうとは限らないから。
CHogeが仮想関数テーブルもってたりするとずれるしな floatは4バイトだから32bit環境では期待どおり動くかもしれないが 仮にそれがcharだったら動かないし、64bit環境でコンパイルしたらずれる可能性もある。
#include <iostream> using namespace std; int main() { cout << "test" << endl; return 0; } 268はこれでエラーがでるん?
285 :
281 :2008/05/25(日) 13:44:22
早いご返答を、ありがとうございました。
>>282 281のHogeはPODになっているから
どんな環境でも問題ないぜ。
>>286 そうかもしれんがPODでなくなる可能性を考えると
やめたほうがいい。
Win32APIの構造体など、PODであることが将来的にある程度保証された場合しか使わない方がいいと思うんだよね。
wfstreamではoperator>>もしくはgetlineで改行までの文字列を取得できますが、 これを改行ではなく任意の文字で行うにはどうすれば良いんでしょうか?
全部読んでから自分で着る
delimを指定する。
マクロを展開する際に 単純に{ }でくくるのではなくて以下のように do{ }while(0) でくくっているのがありますが どういう意図ですか? do { } while (0);
#define HOGE() {}だと、次のようなときにうまくいかない。 if (...) HOGE(); else //... ifとelseの間に{}と;の2文現れるのでコンパイルエラーになる。
strcpy, strcatとかが、dstのポインタを返すのは何故ですか?
戻り値を、文字列を引数とする関数に直接渡せると便利だから。
297 :
291 :2008/05/26(月) 01:22:44
stringオブジェクトに特定の文字列がいくつ入っているか調べたいのですが、それ用の関数ってないのでしょうか?? 調べてみたのですが出てきませんでした。
forとifで出来る。 一つ一つカウントするか、配列にcharを整数とみなしてカウントしていく。
quick searchでぐっぐれ
301 :
298 :2008/05/26(月) 15:40:33
ありがとうございます!なんとかなりました。
mingwでICU(
ttp://www.icu-project.org/ )を使おうとしているのですが、うまくリンクができません。
gccのバージョンは3.4.5、ICUは4.8です。
icu::UnicodeString us(s.c_str(), "utf8");
というだけのコードに
g++ -LC:\Lib\icu\lib -otext.exe text.o -licuuc -licudt
で
undefined reference to `_imp___ZN7icu_3_813UnicodeStringC1EPKcS2_'
undefined reference to `icu_3_8::UnicodeString::~UnicodeString()'
undefined reference to `icu_3_8::UnicodeString::~UnicodeString()'
というエラーがでます。
他にも
icu/lib/*.lib を icu/lib/lib_a/lib*.a にリネームして
g++ -LC:\Lib\icu\lib\lib_a -otext.exe text.o -licuuc -licudt
としたり、
g++ -LC:\Lib\icu\bin -otext.exe text.o -licuuc38 -licudt38
としたりしたのですが、同じエラーがでます。
どうしたらよいのでしょうか?
よろしくお願いします。
303 :
302 :2008/05/26(月) 19:12:14
連続投稿すみません。 他にも g++ -LC:\Lib\icu\lib -otext.exe text.o -licuuc -licudt・・・・・ g++ -LC:\Lib\icu\lib\lib_a -otext.exe text.o -licuuc -licudt・・・・・ g++ -LC:\Lib\icu\bin -otext.exe text.o -licuuc38 -licudt38・・・・・ と全てのライブラリをリンクするのも試しましたが、同じエラーがでました。
VC++用のライブラリをgccで使おうとしてるんなら諦めろ C++はコンパイラが違うと名前マングリングみたいなABIが違うんで ライブラリのバイナリ互換性は無い
305 :
302 :2008/05/26(月) 19:51:10
>>304 レスありがとうございます。
その点は考えていませんでした。HPを見ても確かにVC++中心のようです。
でも、検索するとCygwinで使っている人もいるようです。
それならgccから使えるように思うのですが、出来ないのでしょうか?
ソースコードが置いてある
307 :
302 :2008/05/26(月) 19:56:45
>>306 レスありがとうございます。
バイナリがVC++用かもしれないから、自分のコンパイラでgcc用にコンパイルしてみろって事ですよね?
やってみます。
>>216 え?
ss.str()で値返しされたオブジェクトの参照のconst参照で寿命延長じゃなかったっけ・・・。
あれ・・・そういえばストラウストラップのC++第三版でこんな感じの注意を読んだような読まないような・・・。
スレ汚し失礼した。
309 :
302 :2008/05/26(月) 21:05:19
やってみたのですが、うまく行かないようです。 一応結果を書いておきます。 まずreadmeを見たところ、 Cygwinを使った場合には出来上がったライブラリがCygwinに依存するようです。 これは避けたかったので、適当にmingw環境でほぼ丸ごとコンパイルしてみたのですが、 大量の未define・未定義エラーが出ました。 とりあえず適当にdefineはしたのですが、やはりうまく行かないようです。 かなり難しいようなので、他のライブラリを使うなりしようと思います。 結局出来ませんでしたが、ともかくありがとうございました。
>>308 replaceが無かったら寿命延長される。
>>307 あ?ほんとに分かってんのか?
「はい」ってのはな「はい、わかりました」を略して「はい」なんだよ
頭だけでわかったって言わねんだぞ?学校の勉強じゃねえんだから
社会では?お?実際に出来て初めて「わかった」言うんだ
出来もしねえ奴が軽々しくはいなんて言うんじゃねえよ
すいませんじゃねえよこら。お?申し訳ありませんじゃねえんだよ。
申し訳ありませんってのは本当に反省した奴だけが言える事だろうが。
反省してるって事は今度は必ず出来るって事だ。
お前今できんのかよ。今日のお前は出来てたのかよ?お?
出来もしねえ癖に口だけ一丁前な事言うんじゃねえよ。
お?聴こえてんのかよコラ?あ?
やる気がねえんだったら来なくていいぞ?
お前ナメてんだろコラ?
仕事中だと思って優しく口で言ってりゃ調子に乗ってんじゃねえぞコラ?お?
外で遭ってたら今頃カタワだぞお前?とっくに?あ?
>>311 それマジで言ったん?ソースあんならすぐ出せ
マジなら2ちゃんねら総力を上げて潰すが
いや俺は手伝わんぞ
315 :
デフォルトの名無しさん :2008/05/27(火) 12:34:20
char Description[64]; を m_combbox.AddString(Description[64]); で使えるように LPCTSTR型に変更するにはどうすればいいですか?
>>312 見たいな事言われたらどう返したらいいんだろう
返事しないとしないで怒られるし・・・
もう怒られるのがデフォってぐらいに思ってればいいのかな
>>315 ふつーに
m_combbox.AddString(Description);
でいいんじゃないかい。Unicodeビルドだと一手間必要になるが。
318 :
デフォルトの名無しさん :2008/05/27(火) 12:53:02
>>316 上司が基地外の場合、上司の上司と手をつなぐしかないだろう。
これはたいていうまくいく。
うまくいかない場合、自分が基地外の可能性を疑え。
>>315 なんだそれ、MFCか?
最近のVC++ならatlconv.hあたりをインクルードしてCA2T
昔のならUSES_CONVERSIONとかいう呪文を唱えてマクロかな
>>316 ただのコピペだから、「それ懐かしいな」とか「ひさびさに見た」
とか「総力www」とかそんなレスしとけばいいよ
323 :
デフォルトの名無しさん :2008/05/27(火) 17:08:31
DLLとそのヘッダーファイルがあるんですが、ヘッダーファイルをプロジェクトに追加してDLLはどこに配置すればいいんですか? ***.DLLの記述がヘッダーファイルにもないしどのDLLを使うかはどこで指定してるんですか? それらしき文は #ifndef XXX_H #define XXX_H ・ ・ ・ #ifdef XXX_EXPORTS #define XXX_API __declspec(dllexport) #else #define XXX_API __declspec(dllimport) #endif ぐらいです
DLLは実行時に必要で、ビルド時にはいらん。 インポートライブラリ(.lib)は無いのか?
エラーメッセージの書き方に悩んでいます。 よくある小さなサンプルプログラムでは、エラー処理の箇所に直接文字列リテラルを書きこんでありますが、 大きなプログラムになると、リテラルの保守性の悪さが出てきそうな気がします。 かといって、変数にするとなるとエラーメッセージ1つ1つに変数名をつけるのが大変だし、 "○○がありません。"のように、エラーメッセージに変数を含む場合も困る気がします。 一般的にはどのように実装しているのですか?
先ずこんな感じにエラー番号を決めておく。 enum ErrorNos {ErrorMisc, ErrorFileOpenError, ...}; 例えばこんな処理があったとして。 FILE * fp = fopen(fileName, "r"); エラー処理関数をそのエラー番号でこんな感じに呼ぶ。 if (fp == NULL) errorProc(ErrorFileOpenError, fileName); 変数がある場合に備えて、幾つかオプション引数を取れるようにしておくこともよくある。 或いは、エラー文字列配列をこんな形で作ってもいい。 const char * const errorStrings[] = {"Undocumented error.", "File(%s) is not found.", ...}; この場合はこんな感じにそれぞれで出力ロジックを用意しなければならないのでお勧めはしない。 if (fp == NULL) fprintf(stderr, errorStrings[ErrorFileOpenError], fileName);
>>325 UNIX方面ではgettextというライブラリが一般的。
「メッセージカタログ」という用語でいろいろ調べてみるといいかと思う。
328 :
デフォルトの名無しさん :2008/05/27(火) 18:59:39
http://wisdom.sakura.ne.jp/system/winapi/index.html Win32 API入門のサンプルはどうしてVC++だとエラーになるんだろうか?Cだとコンパイルできる
CとC++は互換性があるはずなのに
#include<windows.h>
int WINAPI WinMain(
HINSTANCE hInstance ,
HINSTANCE hPrevInstance ,
PSTR lpCmdLine ,
int nCmdShow ) {
HWND hwnd = CreateWindow(
TEXT("STATIC") , TEXT("Kitty on your lap") ,
WS_CAPTION ,
100 , 100 , 200 , 200 , NULL , NULL ,
hInstance , NULL
);
if (hwnd == NULL) return 0;
ShowWindow(hwnd , SW_SHOW);
MessageBox(NULL , TEXT("Kitty on your lap") ,
TEXT("Kitty") , MB_ICONINFORMATION);
return 0;
}
どういうエラーだよ
331 :
デフォルトの名無しさん :2008/05/27(火) 20:57:41
std::wcout.imbue(std::locale("japanese")); std::wcout << L"森鷗外" << std::endl; wchar_t 文字列1[] = L"森鷗外"; std::wcout << 文字列1 << std::endl; LPWSTR 文字列2 = L"森鷗外"; std::wcout << 文字列2 << std::endl; 何れのwcoutも正常に表示されません。 MessageBoxなら MessageBoxW(0, 文字列1, L"", MB_OK); MessageBoxW(0, 文字列2, L"", MB_OK); できちんと表示されますが、何が原因なのでしょうか。
>>331 wchar_tのUTF-16って鷗(!= 鴎)もちゃんと表示してくれるの?
333 :
デフォルトの名無しさん :2008/05/27(火) 21:15:35
>>332 wchar_t 文字列1[] = L"森鷗外";
MessageBoxW(0, 文字列1, L"", MB_OK);
でダイアログにきちんと「森鷗外」と表示されます。
>>331 それは文字列を表示してるコンソールの問題じゃないのか。
335 :
デフォルトの名無しさん :2008/05/27(火) 21:39:28
>>334 そうなんですか?
コマンドプロンプトの扱いに不慣れで正直良く分りません。
wcoutを使うのは諦めてWin32APIを使う事にしました。
本当にありがとうございました。
wchar_t 文字列1[] = L"森鷗外";
int lpNumberOfCharsWritten = 0;
HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleW(hConsoleOutput, 文字列1, lstrlen(文字列1), (LPDWORD)lpNumberOfCharsWritten, NULL);
うちはimbueでもsetlocaleでも表示されたけどな…
VC8はlocale::globalを設定するとwcoutのlocaleが効かなくなるバグがあるよ。
>>331 正常じゃないってどんな状態?数字が出るとか?
コンパイラは何?
>>331 CとC++のワイド入出力は、
外ではマルチバイト文字を使い、入出力時に変換するというモデルになっている。
Windowsで日本語なら外部の文字コードとはCP932 (Shift_JIS)になる。
当然、そこに含まれない文字の表示・入力はできないというわけ。
340 :
325 :2008/05/27(火) 23:01:21
レスthx
>>326 なるほど。
しかし、引数を取る時はやはりめんどくさいそうですね。
>>327 初めて知りました。
googleで検索したところ、まとまった解説サイトみたいなのがあまり充実してないのがつらいところです。
試してみる。 俺がmutex取ったからな!
スレ立てサンクス
クラスの静的メンバ変数は、外部で実体を定義しないと使えませんか
メンバ変数で、static const int x=10; とすると実体なしで。コンパイルが通ります。間違えですか?
間違えではありません。
>>346 基本的にはそう。
>>347 それだけで定数式としては使える。
でも const int& r = C::x とかするとリンクエラーになるから、
広く使うクラスなら定義も作っといたほうがいい。(その場合は初期化部分は無し)
サンクス
環境はvc2005です。 こんなエラーが出ます。 1>main.obj : error LNK2019: 未解決の外部シンボル "__declspec(dllimport) public: void __thiscall ANNkd_tree::annkPriSearch(double *,int,int *,double *,double)" (__imp_?annkPriSearch@ANNkd_tree@@QAEXPANHPAH0N@Z) が関数 "int __cdecl findmatch(int)" (?findmatch@@YAHH@Z) で参照されました。 1>main.obj : error LNK2019: 未解決の外部シンボル "__declspec(dllimport) public: __thiscall ANNkd_tree::ANNkd_tree(double * *,int,int,int,enum ANNsplitRule)" (__imp_??0ANNkd_tree@@QAE@PAPANHHHW4ANNsplitRule@@@Z) が関数 "int __cdecl findmatch(int)" (?findmatch@@YAHH@Z) で参照されました。 1>main.obj : error LNK2001: 外部シンボル ""public: virtual void __thiscall ANNkd_tree::annkSearch(double *,int,int *,double *,double)" (?annkSearch@ANNkd_tree@@UAEXPANHPAH0N@Z)" は未解決です。 1>main.obj : error LNK2001: 外部シンボル ""public: virtual int __thiscall ANNkd_tree::annkFRSearch(double *,double,int,int *,double *,double)" (?annkFRSearch@ANNkd_tree@@UAEHPANNHPAH0N@Z)" は未解決です。 1>main.obj : error LNK2001: 外部シンボル ""public: virtual int __thiscall ANNkd_tree::theDim(void)" (?theDim@ANNkd_tree@@UAEHXZ)" は未解決です。 1>main.obj : error LNK2001: 外部シンボル ""public: virtual double * * __thiscall ANNkd_tree::thePoints(void)" (?thePoints@ANNkd_tree@@UAEPAPANXZ)" は未解決です。 1>main.obj : error LNK2019: 未解決の外部シンボル "__declspec(dllimport) public: virtual __thiscall ANNkd_tree::~ANNkd_tree(void)" (__imp_??1ANNkd_tree@@UAE@XZ) が関数 "public: virtual void * __thiscall ANNkd_tree::`scalar deleting destructor'(unsigned int)" (??_GANNkd_tree@@UAEPAXI@Z) で参照されました。 c++ と c を合わせて使おうとしているのですが、いたるところでエラーがでています。 このエラーはなぜ起こるのでしょうか
>>351 必要なライブラリをリンクしていないからだと思うよ
extern "C" が抜けてるとか 名前マングリング でぐぐってみるとよかれ
RemoveDirectoryがディレクトリが失敗します。テンポラリフォルダとファイルを生成して最後に それらを消したいのですが、ファイルは成功しますが、フォルダが無理です。 プログラムを終了して次回に消すと平気です。 なぜでしょうか? ファイルにロックがかかっていれば当然無理ですが、ファイルの削除だけは成功してます。
エラーコードくらい調べては
調べました。 32: ファイルが別の処理で使われているため、アクセスできません。 でした。 ソース見直してみます。サンクス
カレントディレクトリでもないし、空フォルダだし、中のファイルはちゃんとCloseHandleしてるのに原因わかりません。
ファイルを作らずフォルダだけ作って消そうとしたらどうなるか?
つかんでるのは自分自身だろうしなあ カレントディレクトリはどうなってる?
VC++6で、メンバ関数でテンプレート使うとエラーになります。 どうすれば良くなりますでしょうか? template < class C > int write(string x, C y) {省略} : error C2059: 構文エラー : '<' : error C2334: '{' の前に予期しないトークンがありました。関数の本体は無視されます。
自己解決しました。
363 :
デフォルトの名無しさん :2008/05/28(水) 20:53:00
以下をコンパイルしようとするとエラーになります。どうしてでしょうか? #include <iostream> class test {}; int main() { const test aa; return 0; } エラー $ g++ -Wall samp80.cpp test.cpp: In function 'int main()': test.cpp:4: error: uninitialized const 'aa' test.cpp:4: warning: unused variable 'aa'
constしてるのに初期化してないからじゃない
366 :
デフォルトの名無しさん :2008/05/28(水) 21:02:51
>>364-365 ありがとうです。でも初期化のやりようがないと思うんですが、、、
class test {}; ってconstタイプのオブジェクトは作成できないんですか?
じゃあconstにするなよ
const test aa = {};
>>366 constメンバを含んでいてもコンストラクタで初期化は出来る
テンプレートってコンパイラが勝手に型解決するのはいいんだけど、 なんかVBっぽくて気持ち悪いんですが。
Variantの事言ってるのか? 意味あいが全然違うぞ
372 :
デフォルトの名無しさん :2008/05/28(水) 23:41:18
デフォルトの型を定義していない限りは勝手に型解決したりなんかしません
>>370 templateの型解決はきれいな解決。どんな型でも通るわけではない。
VB の型解決は動的。 実行時に型が好きに変わる。 高等な union みたいなもん。 テンプレートの型解決は静的。 コンパイル時に型が決まる。
375 :
デフォルトの名無しさん :2008/05/29(木) 02:56:07
テンプレートクラス内にメンバ関数で const T* const func() const; というのがあった時、2個目のconstの意味が分かりません。 どういう意味ですか?
>>375 戻り値は書き換えできませんよ、って意味。
でも、戻り値は a + b の結果と同じように、元々別のルールで書き換えできないから
あんまり意味は無い。
戻り値の型がクラス型だと、少しは違いが出る。でもやっぱりそんな違いを利用した
コードは書かないほうがいいんで、総じて意味が無い。
377 :
デフォルトの名無しさん :2008/05/29(木) 04:17:35
>>376 それだと、一個目のconstがあるから二個目のconstは必要なくないですか?
関数名の後のconstは メンバ変数を参照することはあっても変更はしない、 という意味
>>377 その2つは修飾している先が違うから、片方がもう一方のかわりになったりはしない。
一個目の const はポインタの指す先の値に付く const 。
二個目の const はポインタの値に付く const 。
>>375 一番左のconstは構文上の利便性のために特別扱いされてる。
「const T* const」は
「T const * const」と解釈される。
constは左結合。
T ←const(実体がconst) * ←const(ポインタ値がconst)
※別の例
char * * const a = NULL;
a = NULL; //コンパイルエラー
char * const * b = NULL;
*b = NULL; //コンパイルエラー
const char * const p って書いたら、((const-->char) *)型の(const-->p)くらいに思ってたんだけど。
右結合で考えてるってことかな? 2番目の位置にconstを書いてみると分かるよ。 const char const * p; // (VC++2005) warning C4114: 同じ型の修飾子が 2 度以上使われています。
ほんとだ、普通に右側にだけ置いても大丈夫なんだ。 typedef const char cchar ; const cchar c = 0; こういうのはアリなんだ。constつけれた方が分かりやすいから?
>>375 参照やポインタ返しの場合は書き換えを禁止できる点で有効。
>>380 そうだったのか!いままで法則性をさっぱり見つけられなくって難儀してたとよ。
メンバ関数内でクラスの値を変更しない場合に、関数の後にconstが付けられる。 これはインスタンスのメンバをキャッシュ参照で済ませても良いよという事をコンパイラに伝える役割を持っている。
388 :
387 :2008/05/29(木) 08:54:35
ごめん
389 :
デフォルトの名無しさん :2008/05/29(木) 10:47:38
doubleの計算の過程で 1.00000000002とか出たときに、 この2の部分を消したい(小数点以下11桁以降を0にしたい) のですが、何か方法ありますでしょうか?
>>389 表示の問題?それとも数を変更する問題?後者なら正確には不可能。
double に 10 進法である桁以降完全に 0 にするという概念は無いから。
近似的には 10^10 かけて floor して 10^-10 かけるとかの関数書くとか。
391 :
389 :2008/05/29(木) 11:29:32
>>390 なるほど!floor関数とか使ったことなかったので勉強になりました。
これから書いてみます、どうもありがとうございました。
>>389 こんな方法もあるよ
#include<stdio.h>
#include<math.h>
int main(void){
double x=1.234567890123456789;
printf("%.12f\n", x);
x-=fmod(x, 1e-10);
printf("%.12f\n", x);
return 0;
}
393 :
389 :2008/05/29(木) 11:50:50
>>392 あぁ〜〜なるほど!
余りを引いても出来るんですね。
ありがとうございました。
mapを使うとき<string , int>ならば、未使用のとき0が入っていますが、 <string , クラス>のときは、未使用の判別はどうやれば良いですか?
>>394 デフォルトコンストラクタで初期化されてる。判別できるかどうかはクラスによる。
int だって、未使用の場合と 0 を入れた場合は判別できないね。
自己解決しました。 > もし存在しないキーを指定してアクセスした場合には、そのキーを自動的に登録します。 > その キーに対応する値は、その値の型のデフォルトコンストラクタによって初期化されます。
>>395 トンクス! 自分で作るクラスなので判別できるように設定したいと思います。
未使用かどうか調べたいなら find(key) すればいいと思うぞ。
あくまで想像だけど、map::find()やmap::lower_bound()を使うべきところを 全部map::operator[]で済まそうとして、本来遭遇しなくていい問題に遭遇している気がする。 「見るだけなのに要素が生成されちゃう。困ったなぁ」みたいな。
トンクス! そっちのほうが良いです
401 :
デフォルトの名無しさん :2008/05/29(木) 17:52:27
Visual Basic 6.0 の配列要素、例えばA(5000),B(5000),C(5000)としたときに、 Visual C++ で作成したDLLからその配列要素に書き込んだり、読み込んだりすることは出来るの? もちろん、Visual Basic 6.0で起動中にそのDLLを使います。 今はVisual Basic 6.0を使っていますが、これからVisual C++を勉強する自分にとってまだDLLがよく分からないので、 よろしくお願いします。
最近独習Cをかって自力でやろうと思っているんですが、環境vistaで最初の1.2で躓いてます。 技術的な問題じゃないんですが、CD付属のものを使わずに、C言語を扱える環境をつくれませんか?
>>402 サンクス。
あと、インターネットからのホームページのHTMLデータを収得する方法がわかりましたら、
これもよろしくお願いします。
今はVB6で収得していますがチョット時間がかかるため、C++に移植したいので。
>>404 ここをサポートセンターと勘違いしない方がよい。
サポートセンターで吹いてしまった
>>405 わからないならレスしないで下さい。スレが汚れます。
せっかく他の人はいい人なのに。
Cでスクレイピングなんてまた面倒くさい事を
>>408 みなさん、ありがとう。
勉強する糸口がみえました。
>>409 他に早く処理できる方法があるんですか?
VB6でやっている自分としては、C++でやった方が早いと思ったので。
VC++で、プログラム中に他のexeに引数を渡して実行するという事をしたいんですがどうすれば良いんでしょうか?
>>411 system
spawn
exec
CreateProcess
>>410 もし、ネットワーク回線がボトルネックなら、
VCで書き換えても劇的に速くなるということはないぞ。
>>414 参考までに同一回線&PCで、
4000ページを取込処理した場合、
自分で作ったVB6だと80秒。
他人の作ったC++だと25秒。
ということでボトルネックはプログラム手法。
だったら作った他人に聞けということはナシね。
非同期でチョコとずつ読み込めれば速いよ
同期で、ひとつ読み込むまで止まっていると幾らでもかかる。
>>416 VB6は非同期で4列並列処理していて、もうこれ以上早くするのは無理かと思って。
となるとC++かなぁと思っています。
ちなみに1つサーバーに対して3コネクション以上同時に繋いで、 しかも節操無くアクセスしてたらアクセス遮断されることもあるので、 程ほどに。
>>418 ロジックのチューニングを検討しないあたりがVB育ちなのかね。
それとも十分に検討済みなのかな。
>>418 variant 型にどんどん追加してるとかじゃないよね?
>>419 それは知りませんでした。
となると、2コネクションにするとさらに取得時間がかかります。
>>420 >>421 VB6をご存じなら分かると思いますが、
GetChunkでデータをString型でバイト配列または文字列として取得しているだけです。
>しているだけ うーん
424 :
デフォルトの名無しさん :2008/05/30(金) 11:35:28
16ミリ秒周期のプログラムはVC++で組めますか? あとVC++の一部にアセンブラを入れられますか?
厳密な正確さを求めないなら組めます 入れられます
426 :
デフォルトの名無しさん :2008/05/30(金) 11:58:58
std::pair<> の配列みたいなものを作りたいのですが、配列としてmapかvectorかで 迷ってます。本だとpairといえばmapだったのですが、vectorの方が使い慣れているし 便利な感じがしてます。どういう基準でmapとvectorを使い分ければよいですか?
>>426 配列を作りたいなら配列を使えばOK。
伸縮できる配列が欲しいならvectorを使えばOK。
pairの中身がkeyとvalueの対応関係があって(複数のpairでkeyが重ならな
い)、「keyに対応するvalueを取りだす」のような操作が必要ならmap。
挿入・検索が多いならstd::map メモリ効率重視・末尾に追加のみならstd::vector
「あらゆる使い方が同じくらいあり得るから迷う」 ということなら、dequeでその場を凌いでしまうのも手かなぁ。
430 :
デフォルトの名無しさん :2008/05/30(金) 13:11:12
ループ処理のあるボタンを押すとループを抜けるまで他の操作ができないんですが、これはなんの項目を勉強すればいいんですか?
Sleep(0); をループの中に入れておけばよかろう
>>431-432 >>430 みたいな「まったく言えてない」質問に、こちら側で徹底的に頭を回して答えてあげるのは、
「たまたま動いてるだけのコード」を見てる時みたいな、得も言われぬ不安がわいてくるなぁw
適当にエラーを出して、回答できねえよと言ってあげるのが、長い目で見れば本人のためだと思う。
clickイベント内で重い処理してるんだと思た
WindowsのGUIのボタン押した際に発生する
メッセージハンドラ内でループして
他のメッセージが処理されずにウィンドウが固まっていると予想。
なので俺も
>>431 だと思う。
他の方法として、WM_TIMER(OnTimer)で
ループ一回分の処理だけ進め、
一旦抜ける、というのを繰り返す。
マルチスレッドよりタイマーの方が簡単そうでいいですね。 ありがとうございます。
438 :
デフォルトの名無しさん :2008/05/30(金) 14:59:41
>>214 で質問した者なんですが
stringstream ss;
ss << "0123456789";
const char* p;
p = ss.str().c_str();
cout << p[2];
みたいにすると、ちゃんと2が出力されるのですが
ss.str.c_str()
はss.str()で生成した一時オブジェクトのポインタを返しているのに、なぜちゃんと2が出力されるんでしょうか??
ss.str()で生成した一時オブジェクトは、その部分を過ぎたら消えてしまうのではないかと思っていたのですが、違うのでしょうか??
>>438 解放されたメモリというのは、以前に書き込まれていたデータがしばらくそのまま残っていることが多い。
なぜなら解放時にわざわざデータを消すっていうのは時間がかかるので。
ただし、後で誰かがどこかで何かのためにメモリをnewやmallocで確保したとき、その解放されたメモリが再利用される。
その「後で」「誰かが」「どこかで」の把握は基本的に無理なので、たまたまそのときはまだデータが残ってるかもしれないが、いつ再利用され他の用途に使われ内容が書き換えられるかわからない。
そういうわけで、解放されたメモリには触ってはいけない。
440 :
デフォルトの名無しさん :2008/05/30(金) 15:19:10
ファイルを削除しても大抵は本体が残っているのと同じようなものだな。
>>438 「有効でなくなる」のと「値が残っている」のとは違う。
殊にポインタの場合、ポイント先が生きていようと死んでいようとアクセスできればデリファレンスしてしまう。
一時的なオブジェクトは恐らくスタックフレームに作られているはずなので、他の一時的なオブジェクトが
作られたときにでも上書きされるだろう。
例えば、私の環境ならこれで"2"ではなく"c"が(その前の出力と並んで)出力される。
--
stringstream ss;
ss << "0123456789";
stringstream sss;
sss << "abcdefg";
const char* p;
p = ss.str().c_str();
cout << sss.str().c_str()[2];
cout << p[2];
課題でファイルを分割する練習なんだが… Error: 外部シンボル 'myclass::set_a(int)' が未解決 Error: 外部シンボル 'myclass::get_a()' が未解決 ってエラーが出て、これのコンパイルが通らないんだ。 //main.cpp #include "myclass.h" int main(){ myclass ob1, ob2; ob1.set_a(10); ob2.set_a(99); cout << ob1.get_a() << "\n"; cout << ob2.get_a() << "\n"; return 0; }
443 :
442続き :2008/05/30(金) 15:46:10
// myclass.h #include <iostream> using namespace std; class myclass{ int a; //private なメンバ変数 public: void set_a(int num); int get_a(); }; //myclass.cpp #include "myclass.h" void myclass::set_a(int num){ a = num; } int myclass::get_a(){ return a; } 理由がよく分からないんだが、先輩方、この小僧にご教授くださいませんか
444 :
442 :2008/05/30(金) 15:53:49
すまない。自己解決できました。 どうやら、使っていた環境の設定をしてなかったみたいだorz
C++ではヘッダファイルに呪文のように #ifndef GUARD_myclass_h #define GUARD_myclass_h // ヘッダ本体 #endif って書こう。でないとすぐにリンカが文句を・・・。
>>445 多重インクルード防ぐのは呪文でもなんでもないような。
おまじないってことだろ。
448 :
デフォルトの名無しさん :2008/05/30(金) 20:31:11
void CFT245RMFCDlgNonUnicodeDlg::OnBnClickedsabo() { HANDLE hThread; int parm; AfxBeginThread(CFT245RMFCDlgNonUnicodeDlg::saboThread, &parm, THREAD_PRIORITY_NORMAL); } void CFT245RMFCDlgNonUnicodeDlg::saboThread(LPVOID parma) { FT_STATUS ftStatus; ULONG bytesWritten; int count = 10; byte ucMask; for ( int i=0; i < count; i++ ) { ucMask = 1; ftStatus = FT_Write(ftHandle, &ucMask, 1, &bytesWritten); Sleep(500); ucMask = 0; ftStatus = FT_Write(CFT245RMFCDlgNonUnicodeDlg::ftHandle, &ucMask, 1, &bytesWritten); Sleep(500); } } スレッド勉強してきた。下のエラーから進まなくなった、たすけて! CFT245RMFCDlgNonUnicodeDlg::saboThread': 関数呼び出しには引数リストがありません。 メンバへのポインタを作成するために '&CFT245RMFCDlgNonUnicodeDlg::saboThread' を使用してください
エラーの内容は「メンバ関数へのポインタを作る記述が間違ってるぞ」で、 ご丁寧に直し方まで教えてくれているわけだけど、 残念ながらそれに従って直しても別なエラーを目にすることになると思う。 AfxBeginThreadの第一引数にはメンバ関数へのポインタを渡すことが出来ないから。 saboThreadをstaticな関数にして引数としてクラスのポインタを渡すとか、別なやり方が必要。
>>448 //クラスを定義している箇所
class CFT245RMFCDlgNonUnicodeDlg
{
static UINT __cdecl saboThreadStatic(LPVOID pParam){
static_cast<CFT245RMFCDlgNonUnicodeDlg*>(pParam)->saboThread();
}
...
};
void CFT245RMFCDlgNonUnicodeDlg::OnBnClickedsabo()
{
AfxBeginThread(CFT245RMFCDlgNonUnicodeDlg::saboThreadStatic, this, THREAD_PRIORITY_NORMAL);
}
void CFT245RMFCDlgNonUnicodeDlg::saboThread()
{
...
}
できたよー ありがとうございました
すいません・・・ PICをかませないでWindowsのUSBのみで0.01ミリ秒単位安定動作させるプログラミング方法はありますか?
Windows自体にそこまでの時間分解能がない。
WindowsはリアルタイムOSじゃないので無理。 PCでっていうのなら自分でOS書けばいける。
>>452 USBは定周期転送があるからそれを使えばいいんじゃないか
456 :
デフォルトの名無しさん :2008/05/31(土) 08:14:07
coutで構造体メンバまで出力したいのですが struct sex { int man; int woman; }; struct sex ok; ok.man = 1; ok.woman= 2; cout << sex << endl; とするとエラーになりますが、なんか昔 sex.man = 1, sex.woman = 2 みたいな表示してくれるのを見た記憶があるのですが、 これって私の勘違いか妄想なのでしょうか? よろしくお願いいたします。
>>456 std::ostream& operator<<(std::ostream& ost, const sex& val)
{
return ost << 好きな表示方法;
}
>>452 自分でドライバ書いてCPU占有すれば出来るかも。
カーネルモードならスケジューラに邪魔されずに処理できるから。
ただ、占有中は当然、キーボードもマウスも利かず、画面描画もされないから
ハングアップ同然の状態になるけど。
周期動作に関しては、自分でループして処理する。
QueryPerformanceFrequencey()とQueryPerformanceCounter()で
1GHzのCPUなら 1/1G秒=0.000001ミリ秒の精度で時間を計測出来る。
コピペしたのにスペルミスとかw QueryPerformanceFrequency()とQueryPerformanceCounter()ね。
'このなかで' 『"』 を表記する場合は、"この中と同じ様に" 『\"』 と表記しないとだめだったっけ?
QueryPerformance〜系は、 CPU周波数が動的に変わったときちゃんと動かないとか
QueryPerformance〜系は 一時期CPUクロックだったこともあったけど、 今はだいたいACPIタイマで、周波数は3579545Hz
465 :
デフォルトの名無しさん :2008/05/31(土) 19:05:27
std::stringで if(str="ABC")をやろうとすると error C2678: 二項演算子 '==' : 型 'std::string' の左オペランドを扱う演算子が見つかりません (または変換できません) (新しい動作; ヘルプを参照)。 1> 'ビルトイン C++ 演算子==(const char [15], const char [15])' の可能性があります ってなるんですが何か変わったのですか? VC++2008です。
466 :
465 :2008/05/31(土) 19:16:03
#include<string.h>を #include<string>にしたら動作しますた
Singleton なんだけとアプリ終了するときはデストラクタ を実行させたいです、どうすればいいですか?
staticオブジェクトにする スマートポインタに包んでおく etc
atexitに登録しておく
山ほど方法があるな
>>467 というか普通、何もしなくてもデストラクタ実行されるけど、
どういう終了のさせかたしてる?
おそらくSingletonクラスの実体そのものをnewしてんだろw
473 :
デフォルトの名無しさん :2008/05/31(土) 21:10:01
C++でコンソール画面を消去する、APIを教えてほすい 環境はWindows VS2005 C++及びLinux g++
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
system("cls");
curses使う
山ほど方法があるな
std::wcout << static_cast<wchar_t>(0x301C) << std::endl; ローケルを日本語圏に設定してこれで波ダッシュが出るはずなんですが、何も表示されないみたいです。 更にstd::endlも出力されておらず、これを一般プログラムに使いまわすとそのプログラムが落ちてしまいます。 このような出力すると落ちる文字が書いてある表なんてものは存在するんでしょうか?何とかしたいです。
wchar_tがどのような形式で文字を保持しているかは規定されていない。 ましてや、intをwchar_tにキャストしてそれをあたかも文字であったかのように扱うなんてとんでもない。
>>479 環境はvc8です。他の文字はコードをちゃんと設定すればこれで表示されます。
とりあえずUTF-16が内部で使われているみたいなので、その場合に限っての話で進めてもらえませんか?
よくわからんけど、落ちるのは別の問題な気がする
落ちるのは別の問題ですが、表示が狂うという問題もまた独立した問題なのでこれも解決しないと とにかくデバッグ情報が出力できないので先に進まないです。 聞きたいこと : コマンドプロンプトで表示が不可能なUTF-16の文字
0xFF5E
CP932でぐぐるといいんじゃね
_UNICODE的な話題か?
>>479 メモ帳にU+307Cの波ダッシュを入力し、ANSIで保存(日本語なのでコードページ932)、
それを開くと?になっていた。
つまり、Windowsの持っているCP932変換では波ダッシュからの変換が存在しないということ。
(全角チルダ0x8160への変換になっていない)
VCもWindowsの変換ルーチンを使っているので、
やはり正しく表示されないことの説明がつく。
Windows APIを使ってUTF-16を直接出力するか(これもフォントの都合でうまく表示されないかもしれないが)、
U+301CをCP932の0x8160にするように自分で予め変換しておくかだな。
wchar_t使うなら、コンソールもワイド系APIで出せって話だよな
有名なネタだと思うんだが知らん奴も多いのか
MSのCP932では、〜を
>>483 が書いてるようにU+FF5Eにマップするんだよ
こういう要注意な文字は他にもある
U+307CをCP932で出したとして、?にならずに 出力出来なくなるってのは何でなんだ? 昔作ったツール経由でコンソールだしたら、 普通にU+307Cだけ?になって、後の出力は問題なく出たんだけど。
491 :
489 :2008/06/01(日) 00:59:29
×U+307C ○U+301C
今度はレス番間違ったorz
493 :
デフォルトの名無しさん :2008/06/01(日) 01:05:08
クラスAにクラスBからの型変換が定義されていた場合、 B b; A a = b; って、したとき、 型変換でbの一時オブジェクトが出来て、コピーコンストラクタでaが構築されるのか? それとも、型変換だけでaが構築されちゃう?
コピーコンストラクタで参照渡しをすればいい
>>490 なんで?に置き換わると思うんだ?
そんなもんは変換層の仕様/実装次第だろ
iostreamのエンコード変換に使われるcodecvt<>は、正常に変換できないときには
エラーにする仕様ってだけじゃまいか
そういう仕様なのか・・・すごい地雷実装だな
>>493 その変換って、クラスAにクラスBの参照を引数に取るコンストラクタがあるってこと?だったらそのまま渡される。
でなくて、その変換がクラスBにクラスAへの変換の演算子が定義されてるって意味なら、戻りのオブジェクトがaになるかコピーされるかはコンパイラによるんじゃないか。戻り値の最適化(RVO)でググるべし
>>497 493に「クラスAに〜」ってあるから前者かな?
もうちょいソースが必要かな。
>>498 >>495 の通り、変換できないときにはエラーになるなら、
「〜」とかに加えて、ASCIIと日本語以外の文字全部じゃね?
const A& operator const B& ()くらい定義しとこうぜ たぶん動くw
変換が必要な場合、戻りのオブジェクトAを作る必要があるから B::operator A() じゃないかな。
古いコードなんかでよく以下のようなコードを見かけるのですが、 どういう意図なのでしょうか? char* c c = (char*)NULL; NULLをポインタに入れるときにあえてその型にキャストする必要はあるのでしょうか? c = NULL; ではまずいのでしょうか?
ttp://janestyle.s11.xrea.com/downloader/ のようなソフトはどのようにしてIEと連系を取っているのでしょうか?
OLEやCOMといったようなインタフェース?が関係しているように思っているのですが
よく分かりません。
perlでは、youtube等から動画を保存するモジュールなどがあるようですが、
例えば、上記のようなツールはどこかのサーバに接続してperlスクリプトを走らせた
結果を入力して、URLなどを取得したりしているのでしょうか?
ご教示願います
505 :
デフォルトの名無しさん :2008/06/01(日) 14:07:50
>>504 単独で取得できるよ
ブラウザアクセスの履歴を眺めて、それをエミュレートすれば良いだけ
基本のGETアクセスだけで出来る
irvineスレ言ったら、解析済みのコードが見られる。
507 :
506 :2008/06/01(日) 14:14:24
そういうイミではなかったか・・・失敬。
>>505 >>506 ありがとうございます。GETコマンドについて調べてみます。
右クリックメニューは、レジストリキーいじってたんですね。
509 :
デフォルトの名無しさん :2008/06/01(日) 14:21:49
お前らvalarrayって使ってる?
>>503 NULLが(void *)0と定義されていれば暗黙の型変換ができると思うけど
そうじゃなければ型指定しないとだめとかじゃないっけか?
NULLの定義は環境依存だしな・・・不親切な説明だが
512 :
デフォルトの名無しさん :2008/06/01(日) 14:37:51
Blitz++使ってる。
513 :
503 :2008/06/01(日) 14:48:45
>>510 >>511 なるほど。#define NULL (void*)0
しているところばかりじゃないということですね。
ありがとうございます。
>>513 いや、C++では #define NULL 0 で、その場合もc = NULLでOKと思うよ。
c = (char*)NULL にする必要性あるのかな。詳しい人よろしく。
515 :
デフォルトの名無しさん :2008/06/01(日) 16:01:43
voidの本にキャストしなければならないって書いてあるからだろ。
もし、C++でNULLを(void*)0にしてるような規格違反の処理系があれば、 c = (char*)NULL; とせざるを得ない。
>>513 昔は違ったかもしれないが、少なくともC89以降、0やNULLはどのポインタ型へも
暗黙の変換ができることになっている。
NULLを(void*)0と定義するのは、
誤ってポインタ以外に使おうとしたときにエラーにさせることが主目的。
規格に沿えば、単に0などという定義でも全く問題ない。
>>503 ANSI Cが制定される前のCでは、キャストが必要な処理系があった。
その時代のコードならNULLやmallocの戻り値をキャストしてるコードはよくある。
519 :
513 :2008/06/01(日) 16:06:14
確かCではNULLが0か(void*)0にしてたが、C++だと型変換が厳しくなり、 NULLを(void*)0にするとc=(char*)NULLと 書かないといけなくなるから0にしたという話だったと思う。 0はC/C++どちらでもキャストしないでいいはず。(int* p = 0とか大丈夫でしょ) いずれにしてもc=(char*)NULLと書く必要はない気がする。
520 :
513 :2008/06/01(日) 16:08:54
518読む前に投稿してしまった。518が答えですかね。
521 :
デフォルトの名無しさん :2008/06/01(日) 16:20:05
cがchar以外のポインタに変えられた場合にエラーになってくれると 助かる場合には意味があるかもなぁ。
C++ での NULL の定義は処理系定義だよ。 0 とは限らなくて、処理系独自のキーワードで定義されていることもある。 C でも C99 で処理系定義になった。
>>503 C でも void* から別のポインタ型への暗黙のキャストをしようとすると警告出すコンパイラもある。
そういうコンパイラを黙らせるには明示的にキャストをしないといけない。
そういうことなんじゃないの?
>>519 ただし、可変長引数の末尾には、(char *)NULL と書いておきなさい、という説があるみたいです。
>>525 末尾に限らず可変長引数の途中でヌルポインタを渡したいときはキャストが必要。
同様に、実引数から型を推測するような関数テンプレートにもヌルポインタを渡す
ためにはキャストなどの注意が必要。
>>525 NULL終端文字列として扱えるからな。
お前は何を言ってるんだ
>>527 NULLとだけ書くと整数のゼロを渡してしまうかもしれないからだろ
intとポインタのサイズが同じかつNULLのビット表現がintの0と一致するという限られた環境の下ではたまたま動くかもしれないが
530 :
デフォルトの名無しさん :2008/06/01(日) 21:35:21
もっとも新しく追加したデータが0番に来て、データの削除は古い方から行うにはどんなSTLを使えばいいですか
> どんなSTL なんか斬新だな dequeでいいんじゃないか
532 :
デフォルトの名無しさん :2008/06/01(日) 21:46:37
トンクス
シリコングラフィックのSTLを使え!
>>530 boost/circular_buffer
535 :
デフォルトの名無しさん :2008/06/01(日) 23:40:50
メソッドの宣言にて void Hoge() throw (HogeException){ } として、VC++にてビルドすると C++ の例外の指定は無視されます。 関数が __declspec(nothrow) でないことのみ表示されます。 という警告が出ます、 メソッドの例外型制限は VC++ 以外の環境でもサポート外なのでしょうか よろしくお願い致します。
VC++が実装してないだけ
>>535 gccでは使える
でもそれほど役に立たない機能だぞ
正直だれも使ってないから当面は実装されないだろ
exception クラスを継承する時に使わざるを得ないけどな。
C++でものすごく初歩的な質問なんですが・・・ int a[] = { 0,1,2,3,4,5,6,7,8,9 } みたいな組み込み型の配列を関数に引数として渡すにはどうしたらいいんでしょう? vectorならそのまま参照でもコピーでもできるんですけど組み込み型はどうにもうまくいかなくて。
void func(int *a) { ... } int main() { int a[] = {0,1,2,3...}; func(a); return 0; } もし関数内で配列を弄らないなら void func(const int *a); と宣言しとけばいい
それだけじゃサイズが分からないからサイズも渡した方がいい。 #define ELEMOF(array) (sizeof (array) / sizeof (array)[0]) void func(const int *a, size_t n) { ... } func(a, ELEMOF(a));
>>542-543 どもです。
やっぱり組み込み型はサイズを自動的には受け渡せないんですね。
vector では受け取った関数内で size を確認できるのに
組み込み型は sizeof の結果が変わってしまうので困ってました。
>>541 テンプレートという手もありだよ。
template<typename T>
void func(T const& a) //中身を書き換えるなら当然T&で
{
...
}
これなら関数内ではsizeof a / sizeof a[0]もできる。
以下蛇足。Boost.Rangeを使ってboost::size(a)などと書けば、
組込配列も渡せるし、std::vectorも渡せるようにできる。
俺もBoost.Rangeが良いとは思うけど、まず基本のbegin,endを覚えた方が良い。 void func(const int* begin, const int* end) { ... }
547 :
デフォルトの名無しさん :2008/06/02(月) 11:10:55
この前valarrayについて質問したものです。 valarray va(10); log(va); とか出来ますが、これは、自分で作ったクラスに対してlogとかsinとかを適用できるようにすることが できるということだと思うのですが、どうやればよいですか? valarrayのソースを見てみたけどよくわからんかったス
>>547 普通に
Hoge log(Hoge x){ ... }
っていう関数を新たに定義すればいいのでは?
549 :
デフォルトの名無しさん :2008/06/02(月) 12:44:25
データ読み込みに関する質問です。 csvファイルからデータを読み込むときに、一行目を飛ばして二行目から読み込みを始めたいと思い、 以下のようにプログラムを書きました。 /**** データ読み込み ****/ fscanf(fl,"\n"); //一行目(V1とか書いてあるところ)とばす for(n = 0; n < P; n++){ 以下配列に読み込み fscanf(fl,"\n"); のところで一行飛ばしてから、for文で読み込んでいこうと思ったのですが、 うまくいきませんでした。 自分なりに調べてみたのですがうまくいきませんでした。ご教授よろしくお願いいたしますm(_ _)m
550 :
デフォルトの名無しさん :2008/06/02(月) 12:47:17
>>548 たしかにそれでも出来ますが、valarrayのソース内にはそういう関数定義はないみたいなんですが、
やっぱり普通に定義しないとだめですよね?
>>549 >fscanf(fl, "\n");
そのように書いても、一行飛ばすという意味にならない。
なぜこれで一行飛ばせると思ったのか?
教科書やリファレンスにそう書いてあったか?
カンでプログラミングしないこと。
while (fgetc(fl) != '\n') ;
などとすれば次の行まで読み飛ばせる (本当は EOF もチェックした方がいいけど)
>>550 どの処理系か知らないけど、うちの C:\Program Files\Microsoft Visual Studio 8\VC\include\valarray には
>template<class _Ty> inline
>valarray<_Ty> log(const valarray<_Ty>& _Left)
>{ // apply log to each element of valarray
>_VALOP(_Ty, _Left.size(), ::log(_Left[_Idx]));
>}
って書いてあるよ
>>551 レスありがとうございます。
fscanf(fl,"\n");
と書いて一行飛ばせると思ったのは、\nは改行を示しているために、
一行飛ばせると思ってしまいました。。もっと勉強します。
本当にありがとうございました。
改行を読み込む ≠ 一行読み込む
どーしても行読み飛ばしをfscanf()で書くんなら fscanf(fl,"%*[^\n]"); /* 改行以外の文字を読み飛ばしてから */ fscanf(fl,"%*c"); /* 次の一文字(=改行)を読み飛ばす */ とかになる fscanf(fl, "%*[^\n]%*c"); と一見書けそうに思えるが、いきなり改行が来るとジャムるのでダメ ま、scanf()系って理解すればそんなに難しいものではないけど 初心者には鬼門だな
DLLを作ってます。本来VBAから呼ぶのですが、DLLのコードをデバッグするため コール元をVCで作成してるいんですが、 「test.obj : error LNK2019: 未解決の外部シンボル __imp__CareerDataRead が関数 _main で参照されました。」 がでます。testはDLL用テストプロジェクトです。 下記はtest用DLLソースです。 extern "C" __declspec (dllimport) int CareerDataRead(char *chrFileName); int main() { CareerDataRead("test.c"); } なにが足りないのでしょうか?
インポートライブラリのリンク
>>556 DLLをビルドしたときに出来たインポートライブラリをコール元にリンクする
559 :
556 :2008/06/02(月) 16:05:54
>>557 >>558 即レスありがとうございます。
インポートライブラリのリンクとのことですが、
@プロパティページの「Frameworkと参照」の「参照」にて当該libファイルを設定する
A同プロパティページの「リンカ」「入力」「追加の依存ファイル」にて当該libファイルを設定する
と2通りのやり方を調べあげました。どちらもやっても結果が変わりません。
申し遅れましたがVC++2008 Expressにて開発しております。
>>559 プロジェクトのプロパティのリンカの入力に設定するか、
ソースに #pragma comment(lib, "xxxxxx.lib")
を追加する。
libファイルの場所は問題ないね? そのDLLの関数はCリンケージでexportしてるね?
562 :
556 :2008/06/02(月) 16:38:47
>>559 の@は違う気がしたので
>>560 さんの指摘はAとお見受けしまた。pragmaの方は試してないのですが、なぜ前者の
方でうまくいかないのか謎です。
>>561 ソリューションは以下の構成下にあります。
ExcelVBA
Debug ←ここにlibファイルがあります。
ExcelVBA
Debug
test
よってリンカの「入力」「追加の依存ファイル」より「ExcelVBA.lib」を設定してあります。
また、リンカの「全般」に「追加のライブラリディレクトリ」というのがあったので
上記のライブラリがあるパスをフルパスで設定しました。
が、あいかわらず未解決がでます。
>>561 DLLのエクスポートですが
#define DllExport extern "C" __declspec (dllexport)
DllExport int WINAPI CareerDataRead(char *chrFileName);
を先頭につけており、同関数の中身を return 128;
でExcelから呼び出した場合128が却ってきたことを確認しています。
なお、これから複雑な処理を書くためVBAから結果のみみてデバッグは危険かと思い
ダミーコールプログラムをVC++で書いてる次第でございます。
563 :
556 :2008/06/02(月) 16:43:54
リンクのコマンドラインというところにリンクオプションっぽいのを発見したので貼り付けてみます。 /OUT:"C:\Documents and Settings\xxxx\My Documents\Visual Studio 2008\Projects\ExcelVBA\Debug\test.exe" /INCREMENTAL /NOLOGO /LIBPATH:"C:\Documents and Settings\xxxx\My Documents\Visual Studio 2008\Projects\ExcelVBA\Debug" /MANIFEST /MANIFESTFILE:"Debug\test.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\Documents and Settings\xxxx\My Documents\Visual Studio 2008\Projects\ExcelVBA\Debug\test.pdb" / SUBSYSTEM:CONSOLE /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT excelvba.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
WINAPI つけろ windows.h のインクルードもね
>>556 export側では呼び出し規約がWINAPI
import側はWINAPIが抜けてる(んでcdeclを仮定している)
正しい方に統一汁
dumpbin.exeやバイナリエディタでDLLやlibの中身をのぞいたりすることも
してみると良い
呼び出し規約が違えばライブラリに埋め込まれるリンカ用の名前も変わるから
見りゃすぐ分かるよ
566 :
556 :2008/06/02(月) 17:06:12
猛烈に感動してます。先週からはまってて解決できなかったのでありがとうございます。 ちなみに下記のように修正しました。 #include <windows.h> // extern "C" __declspec (dllimport) int WINAPI CareerDataRead(char *chrFileName); #define DllImport extern "C" __declspec (dllimport) DllImport int WINAPI CareerDataRead(char *chrFileName); int main() { CareerDataRead("test.c"); }
567 :
556 :2008/06/02(月) 19:03:10
連投ですいません。 ↑の実際の処理手法を調べていました。 処理内容はファイル(テキストファイルで行ごとにタブ区切り)を読み込んで、ある一部分を集計するように したいのですが、ファイルを読み込む方法として @fopen fget等C言語を使用する。 Aifstreamを使用する。 BCreateFile ReadFile等 Win32を使用する。 CMFCの利用(すいません、調べきれてません) などなどやり方が多くありどれが最適かよくわかりません。 元々VBAでやっていた集計が遅いとのことなのでスピードアップが目的なのですがどのやり方がよいか、 こんなのが一般的だなどアドバイスお願いします。
>>567 MFCは除外するとして、WinAPIは行単位の読み込み関数がないから敷居が高いんでない?
ifstreamを使うかfopenを使うかは習熟度次第。
読み込むファイルが数値だけの書かれたテキストファイルならどっちでもいいでしょ。
処で、なんでExcel自身に処理させないの?
tsvを読み込むのも集計するのもExcelでできると思うのだけど。
569 :
566 :2008/06/02(月) 19:18:49
>>568 レスありがとうございます。
ifstreamがC++っぽいらしいのでそれで挑戦します。
ちなみにExcelVBAで処理を行うと1ファイル500行ほどで5万ファイルほど集計をかけなければならないため
(この5万ファイル中で項目によりベスト5、ワースト5等を決めます)
表示を切ったりセルに書き込む処理を抑制しても、処理に15分から20分ほどかかってしまいます。
VBAでいろいろな努力をした結果、1ファイルの処理をDLLで計算させると速いと聞いたのでいま苦戦中です;;
VBの速度が分からないけど(VBも処理速度を意識して書けば早い) 場合によっては awk でも実用的な速度になるかもしれない 興味があれば「gawk」でググれば見つかると思う # こんな感じ BEGIN{FS="\t"} {if(NF>=3) sum+=$3} // 3番目のレコードの総和 END{print sum}
571 :
568 :2008/06/02(月) 19:25:27
>>569 なるほど、ちょっとした量だな。
できれば、DLLにするよりも単体のプログラムにした方がらくだとは思うのだけれど……
あぁそうか、DLL作成のノウハウは(ここで)得ているのか。
エクセルから呼び出せなきゃいけないんだな
>>567 サンプルデータを用意してくれれば挑戦してみたい
どんな入力(サンプルデータ)に対してどんな値を返せばいいのかを教えてくれれば
C言語でやってみます
要するに関数プロトタイプとサンプルデータ下さいって事です
574 :
デフォルトの名無しさん :2008/06/02(月) 19:35:00
Win32が最速。 C++はWin32を利用している。
>>574 そして車輪の再生産ですね?わかります。
まー、Windowsの開発なら、それが無難だろう 生産性重視なら他の言語でもいいが、C++にはパフォでは絶対勝てないな
>>570 awkは以前Unixの処理系でやりましたが挫折しました。
>>571 初心者ですがこれも経験だと思ってチャレンジします。
>>572 集計結果が表やグラフで表示するため保存形式やドキュメントの流用性を考えるとExcelが有効だと考え
ました。
>>573 タブ区切りのデータが8個あり最終は改行です。
1 コメント 300 400 500 600 800 900
2 コメント 200 200 30 6 800 90000
3 コメント 350 100 450 600 20 500
:
(500行ほどあります)
↑このファイルが5万ほどありますが、ファイル指定は親のVBAからします。つまりファイル名を入力として
最終データの最高値、最小値、平均の3つを返せればそれを利用して他の処理もできると考えてます。
578 :
566 :2008/06/02(月) 19:49:55
↑は566でした。
579 :
568 :2008/06/02(月) 19:54:56
>>577 VBAでファイルを読み込んで、VBAでExcel関数を使って集計するのは試した?
ファイル数が多いから微妙だけど、VBAを使いこなせていればそれなりの時間で処理できそうだけど。
>>577 5万ファイルはxlsじゃなくてtsvファイルってこと?
んで、集計結果もエクセルで扱いやすい形式であればよい?
>>577 6種の項目すべてについて最高値・最小値・平均を求めるとして
返すのは一番左の数値?それとも最高値・最小値?
int CarrerDataRead(const char *filename, long *max0, ... , long *max5, long *min0, ... , long *min5, long *ave0, ... , long *ave5);
こんなん?引数の数が半端無いよw
反復とかさせればいいだろw
>>582 VBAからの呼び出し時に配列を ByRef で渡す方法があれば簡単になるんだけど
その方法を知らないんだ
>>579 ご指摘の内容はWorksheetFunctionのことだと思われます。が合計、平均等の処理は
当該処理を利用させてもらいました。おそらくダイエット可能な場所はほとんどやり尽く
した感があったためDLL化とうい道を選択しました。
実際算出しなければいけないデータは平均、最高値、最低値だけでないためExcel関数
の範疇を超えております。
585 :
デフォルトの名無しさん :2008/06/02(月) 20:05:10
ファイルの入出力はWin32使った方が良い。 速度も、安定性もアップする。 なんか開けるすうに制限あるし、不安定な動作することがある c++
586 :
566 :2008/06/02(月) 20:05:54
↑566でした。
なるほど、自分のバグを棚に上げて言語批判ですね、判ります。 そりゃぁ、バッファリングしないAPIなら速いでしょうね。早くはありませんが。 つーか、ハンドル閉じ損ねても100や200じゃ問題出ませんもんね。
589 :
デフォルトの名無しさん :2008/06/02(月) 20:09:20
バグじゃなくて200個くらいファイルにアクセスすると無視されるよ C++の仕様
一度にそんなにファイルを開く方がおかしいだろ。
もしかして: ファイルクローズはデストラクタ任せ
592 :
デフォルトの名無しさん :2008/06/02(月) 20:10:55
C++はバッファ管理があまいから、自分でそのつど制御した方が断然速い
593 :
566 :2008/06/02(月) 20:10:56
>>581 データは各行の8項目の最終データのみ対象です。返すのは3つのデータです。(最高、最低、平均)
int CarrerDataRead("ファイル名"、結果の配列)
がベストと考えてます。ただVBAの方で受けられる型とかの検証はまだしてません。すいません。
まずは、サンプルデータ作成コード #include<stdio.h> #include<stdlib.h> int main(void){ int i, j, k; FILE *fp; char filename[FILENAME_MAX]; for(i=0;i<500;i++){ // とりあえず50000じゃなくて500 sprintf(filename, "temp/dat%05d", i+1); // tempというディレクトリは予め作っておいて下さい printf("%s\n", filename); if((fp=fopen(filename, "w"))==NULL) exit(1); for(j=0;j<500;j++){ fprintf(fp, "%d\tコメント", j+1); for(k=0;k<6;k++) fprintf(fp, "\t%d", rand()); fprintf(fp, "\n"); } fclose(fp); } return 0; }
>>570 俺もこの手の内容ならawk か perlあたりでいいかなと思ったんだけどね。
UN*Xユーザはなかなか理解されないのだろうかorz
awkで書けば、こんなもんだよ awkは全て実数だし配列処理が遅いことでも有名なので、 awkが遅すぎると思えるならperl/ruby/pythonあたりを試すといいだろう 別解としては、TSVなら簡単にDBに取り込めるはずなので、 SQLに集計処理をやらせる手もある #!/usr/bin/awk -f BEGIN { from = 3 to = 9 } NR == 1 { for (i = from; i < to; i++) amax[i] = amin[i] = asum[i] = $i } NR > 1 { for (i = from; i < to; i++) { if ($i > amax[i]) amax[i] = $i if ($i < amin[i]) amin[i] = $i asum[i] += $i } } END { for (i = from; i < to; i++) printf("%d\t", amax[i]) printf("\n") for (i = from; i < to; i++) printf("%d\t", amin[i]) printf("\n") for (i = from; i < to; i++) printf("%g\t", asum[i]/NR) printf("\n") }
>>597 スレ違い感が否めないが、$8だけでいいらしいよ。
>>598 よく読んでなかった
まあ、俺がいいたかったのは、わざわざC/C++で書く必要がある仕事には見えない
ってことだったんだけどね
そこは同意。 だがもしかするとみんなそれを理解したうえで、主のDLLで 何とかしたいという要求に答えたいだけなのかもしれないや。 とりあえずawkでやってみたけど、大して速くないものの処理が終わり、 テストデータの大きさが2ギガあったことにびっくりしつつ削除してオワタ。
602 :
573 :2008/06/02(月) 21:41:47
作ってはみたけど、一つのファイルに対して best5、worst5、平均 の計11個求めるんじゃなかったみたいだね orz
603 :
573 :2008/06/02(月) 23:14:20
#include<stdio.h> typedef long value_t; int value_get(FILE *fp, value_t *value){ return fscanf(fp, "%*[^\t]\t%*[^\t]\t%*[^\t]\t%*[^\t]\t%*[^\t]\t%*[^\t]\t%*[^\t]\t%ld", value)==1; } int CareerDataRead_internal(const char *filename, value_t *best, value_t *worst, value_t *average){ FILE *fp; long i, sum=0; value_t value, maximum, minimum; if((fp=fopen(filename, "r"))==NULL) return 0; if(!value_get(fp, &value)){ fclose(fp); return 0; } maximum=minimum=value; sum+=value; for(i=1;;i++){ if(!value_get(fp, &value)) break; if(value>maximum) maximum=value; if(value<minimum) minimum=value; sum+=value; } fclose(fp); *best=maximum; *worst=minimum; *average=sum/i; return i; } __declspec(dllexport) int CareerDataRead(const char *filename, value_t *result){ return CareerDataRead_internal(filename, &result[0], &result[1], &result[2]); }
>>603 だけでなく、ソース貼る人全員に対してだけど、
全角空白でもいいからインデントしてくれるとありがたい。
だと半角空白のままインデント出来るから尚いいけど、
こっちは文字数制限に掛かりやすくなるからね。
SQLなんちゃらにぶち込んだほうがよくね?
SQLite?
Cの系譜は{}でインデントが導出できるから必要ないんでないのかなー。 自分でindent叩くとかindent-regionするとかさー
indent-regionはともかく、わざわざ回答側にindent叩かせるなってこと。
Core Duo 1.66 GHz / 1 GB Mem という環境で、直列の ifstream 実装を 試したところ 3 分弱。結構かかるねー。
ぶっちゃけこの程度の計算はゴミだから大半はI/Oの時間でしょ ifstreamなんて糞みたいに遅いから、わざわざC++使ってもちっとも速くならないと 思う
#include <stdio.h>
#include <stdlib.h>
void hyouji(int x);
main()
{
int i,x;
char hikisu[];
printf("数値を入力してください(1-52):");
scanf("%d",&x);
hyouji(x);
for (i=1; i <= x; i++){
printf("%d %c",i,hikisu[i]);
}
}
void hyouji(int x)
{
FILE fp;
int i;
if(NULL == (fp = fopen("homework.txt","r"))){
printf("ファイルが開けません\n");
exit(1);
}
for (i=1; i <= x; i++){
fscanf(fp, "%c", &hikisu[i]);
}
fclose(fp);
return;
}
以上のプログラムで『LightC』を使ってコンパイルしようとしても上手くいきません。
どの辺りが間違っているのでしょうか?
『LightC』
ttp://www.tamasoft.co.jp/lc/index.html
iostreamは遅いとの噂。 少なくともVC6の頃は鼻血出そうなくらい遅かった。
エラーメッセージくらいな・・・
#include <stdio.h> #include <stdlib.h> void hyouji(int x); main() ←戻り値の型指定が無い { int i,x; char hikisu[]; ←サイズが決まってない printf("数値を入力してください(1-52):"); scanf("%d",&x); hyouji(x); for (i=1; i <= x; i++){ printf("%d %c",i,hikisu[i]); } } void hyouji(int x) { FILE fp; ←普通ファイルポインタを使うので*fp int i; if(NULL == (fp = fopen("homework.txt","r"))){ printf("ファイルが開けません\n"); exit(1); } for (i=1; i <= x; i++){ fscanf(fp, "%c", &hikisu[i]); ←hikisuなどと言うものはこの関数内に存在しない } fclose(fp); return; } ぱっと見た感じこんなもの
>>608 vimで
ggVG=
とやればよいよ。VSなら}を書き直したらそれでやってくれなかったっけ?
>>615 わざわざそれだけのためにエディタ起動させるのか。
618 :
611 :2008/06/03(火) 01:31:43
>>611 のエラーコードを書き忘れてました・・・
test.c(7): エラー C.2530: 変数 hikisu のサイズが不明です
test.c(5): 警告 C.5280: 関数 main に return 文がありません
test.c(19): エラー C.2920: struct _FILE/* を struct _FILE に変換することはできません
test.c(24): エラー C.2130: 識別子 hikisu が未定義です
test.c(26): エラー C.2920: struct _FILE を struct _FILE/* に変換することはできません
>>617 だってビルドエラーとか、半端なソースの場合とか、動かす前に
見なきゃじゃん。
エディタ起動すらめんどくさがるとかどうやってソース書いてんの?
620 :
611 :2008/06/03(火) 02:16:05
>>614 のヒントを元に
>>611 を修正してみました。
#include <stdio.h>
#include <stdlib.h>
void hyouji(int x);
char main(char hikisu[])
{
int i,x;
printf("数値を入力してください(1-52):");
scanf("%d",&x);
hyouji(x);
for (i=1; i <= x; i++){printf("%d %c",i,hikisu[i]);}
}
void hyouji(int x,)
{
FILE *fp;
int i;
char hikisu[52];
if(NULL == (fp = fopen("homework.txt","r"))){
printf("ファイルが開けません\n");
exit(1);
}
for (i=1; i <= x; i++){fscanf(fp, "%c", &hikisu[i]);}
fclose(fp);
return;
}
しかし、それでも以下のようなエラー文が出ます。
test.c(4): 警告 C.5280: 関数 main に return 文がありません
test.c(19): エラー C.2150: == 演算子の引数が正しくありません
一体どこにエラーがあるのでしょうか・・・
#include <stdio.h> void f(int **p){ int x[2]={1,2}; *p=x; } int main(void){ int *p; f(&p); printf("%d\n",p[0]+p[1]); return 0; } 上のプログラムの誤りを指摘せよという問題が出たのですが、 どこが間違っているのかよくわからないので教えてください。 おそらくp[0],p[1]のあたりが違うのだと思うんですが・・・
>>620 >char main(char hikisu[])
ただ付ければ良いって物でもないだろ。
一度「ちゃんとした」入門書を買ってきて勉強したほうがいい。
>test.c(4): 警告 C.5280: 関数 main に return 文がありません
「return文がない」と言われているのだから、どこかにreturn文を追加すれば
いいのではないか、というくらいは想像つかないか?
>>620 ※1
char main(char hikisu[])
↓
int main(int argc, char** argv)
※2
printf("%d %c",i,hikisu[i]);のhikisuが不明
※3
main関数の最後にreturn 0;を付ける
※4
void hyoujiと関数の戻り値がvoidになっている。
戻り値を使わないのなら、最後のreturn;は必要ないです。
※5
void hyouji(int x,)
↓
void hyouji(int x)
625 :
623 :2008/06/03(火) 03:12:28
定性 ※2 printf("%d %c",i,hikisu[i]);のhikisuが不明 と書いたけど、mainの引数を使いたいっぽいのですよね。 mainの引数を使うなら、 argcの方に引数の数が入ってるから、その数を参考にしてその数をオーバーする事のないようにして、 printf("%s", argv[i]); これみたいに表示かな。
626 :
1/2 :2008/06/03(火) 03:20:56
#include <stdio.h> #include <stdlib.h> void hyouji(char*, size_t); int main() { char *hikisu; size_t size; while(1){ printf("数値を入力してください(1-52):"); scanf("%d", &size); if(size > 0 && size < 53) break; else printf("サイズを超えています\n"); } hikisu = (char*)malloc(size * sizeof(char)); if(NULL == hikisu){ printf("メモリが確保出来ません\n"); exit(1); } hyouji(hikisu, size); free(hikisu); return 0; }
627 :
2/2 :2008/06/03(火) 03:21:17
void hyouji(char *hikisu, size_t size) { FILE *fp; int i; if(NULL == (fp = fopen("homework.txt","r"))){ printf("ファイルが開けません\n"); exit(1); } for(i=0; i < size; ++i){ fscanf(fp, " %c", &hikisu[i]); printf("%2d: %c\n", i+1, hikisu[i]); } fclose(fp); } やりたいんだろうなと言う事を考えたらこんな感じになるかな homework.txtの中身を知らないからその辺は変わるかも知れないけど
問題をより小さな問題に切り分けていくことが出来ないのが、一番致命的。
629 :
611 :2008/06/03(火) 09:19:09
>>回答してくださった皆様
ありがとうございます、そして本当にご迷惑をおかけしました・・・
>>614-627 とテキストを見直してもう一度自分で考えてみようと思います。
630 :
デフォルトの名無しさん :2008/06/03(火) 16:57:39
#include <iostream> using namespace std; int main(void) { cout << "Hello" << endl; } 上記のソースをコンパイルして、 c:\>hello.exe > hello.txt のように実行すれば、テキストファイルができるのですが、 出力させたいのがテキストではなく、バイナリデータの時はどうすれば良いのでしょうか? cout << binary_data; とすると、意図しないデータが出力されてしまいます。 どうすればバイナリデータを変換させないでそのまま出力させることができるのでしょうか? どなたか、優しい方いましたら教えて下さい。 携帯から書き込んでいるので、見にくかったらすみません。
>>631 その、バイナリモードってやつにはどうすればできるのでしょうか?
>>632 cout バイナリとかでググればいいんじゃね?
>>632 Windowsだよね。__setmode(__fileno(stdout), _O_BINARY)でOK。
バイナリデータ書くなら << はダメだ char*にキャストしてwrite()とかするんだね
オイオイ
>>636 俺なんかおかしいこと言った?
バイナリ出力ならエンコード変換も書式フォーマットも改行制御も要らない
つまりiostreamは完全に余計な邪魔者でしかない
ostream::write()がマシだと思うが
streambufを使う方がマシで、
本当はiostreamなんて使わないのが一番いい
バイナリを文字列に変換して<<する
>>638 fwrite()一発で済む仕事でなぜわざわざそんなことをやる
明らかに遅く、特に得るものがあるとも思えない
<< で連結して書けるのは、ソース中の記述と 実際の出力との対応を分かりやすくできて、メリットだと思うけどね。
よくわからんなー 32bit整数をバイナリ出力するときとか、Cならアドレス取って4byte書き出す わけじゃん iostreamの作法ではどうするの?
え?バイナリデータをバイナリエディタみたいに数値として表示するんじゃないの?
>>642 意味が分からない
バイナリビューワなら、出力は「テキスト」じゃないか
>>630 は「バイナリデータを出力したい」と言ってるんだぞ
質問者の意図を理解してなかったの?
644 :
630 :2008/06/04(水) 00:00:25
>>630 です。
あれから、色々頑張ってみたのですが、なにぶん初心者な者で、かなりてこずりました。
最終的には _setmode でなんとかできました。
fwrite で書き出したファイルとも一致するので、とりあえずはこれで良しとします。
色々と教えて下さった皆さん、どうもありがとうございました。
>>644 分かってると思うけどC++でもfwrite()は普通に使っていいんだよ
使ったら負けかなと思ってる
>>646 参考までに聞くけど、fwrite()の替わりに何使ってるの?
fwrite()なら
int a = 0xdeadbeaf;
fwrite(&a, sizeof a, 1, fp);
で済むけど
ostream::write()やstreambuf::sputn()はキャストしなきゃいけないから
stream.write(reinterpret_cast<char*>(&a), sizeof a);
とかになるよね
コードは長い、汚い、その上遅い
oven::streambuf_writer
boostですらないのかw
fwrite系をパックした自作クラス使ってるわ。 必要ならFILEポインタからstreamオブジェクトに キャストできるし、f系の方が便利よね。
fopenでいいじゃん
変数のオーバーフローを検知する方法を教えてください
こんなん? if ( MAX - 値 < 変数) 変数+値はオーバーフローしちゃうよヽ(゚∀゚)ノ
インラインasmでオーバーフロービットをチェックが正解かな?
if((rhs > 0) && ((lhs + rhs) < lhs)){ ; }
656 :
デフォルトの名無しさん :2008/06/04(水) 19:20:07
VC++ で開発する際に、常に警告レベルを最高に設定しています。 警告レベル最高だと、未初期化の変数が使用される可能性がある場合に ビルド時に警告が出力されますが 構造体変数の初期化方法に困っています 使用直前で変数宣言すべきか、構造体1つ1つに初期値をセットすべきか 他に何かスマートな方法があるのでしょうか、 よろしくお願い致します。
657 :
566 :2008/06/04(水) 19:57:17
お世話になってます。ようやく処理部分のデバッグをすませました。 仕様変更などもともなって、long型のデータ7個とdouble型のデータ4個をVBA側に返すことになりました。 が、これらのデータをどうやってVBA側に渡せばよいのかわかりません。 なお、処理はCのライブラリのみ使用してC++ MFCのライブラリ等はほとんど使用しておりません。 あともう少しなのでアドバイスお願いします。
658 :
566 :2008/06/04(水) 20:00:59
過去レスまでの流れは ・VBAの処理をC++で書き直してDLL化。 ・VBAからDLLの関数を呼ぶ。 ・DLLの関数から結果をVBAで受ける。 ・VBAでグラフやレポートを出力する。 こんなことする理由:データ量が多いので処理が遅いため。 でございます。
659 :
566 :2008/06/04(水) 20:05:58
あ、なるべく配列で渡したいです。
入力した文字列を、malloc等で作った動的メモリに保存して、 1文字ずつ扱えるようにしたいのですが、 入力する文字列を保存する変数には最初に、 char c[256]; のようにメモリを確保しないとバッファオーバーフローがおき、 問題がありますよね? メモリの動的確保の目的が、メモリの効率的な利用なのはわかりますが、 この入力する文字列のメモリ確保の無駄は、 オーバーフローを防ぐためには仕方がないのでしょうか? また、メモリ確保の無駄を無くすために、宣言時に char c; として、故意にバッファオーバーフローを起こさせるのは、 やはりプログラム的にはNGですよね? よろしくお願いします。
>>656 全部 0 で良ければこんな感じでどう?
struct foo = {};
>>660 ストリームからは一文字づつ取得すればいいいだろ
>>661 それはダメだ。{}の中には最低一つの式がないといけない。
>>661 レスありがとうございます
オール0になってて使えそうです
>>658 そもそもその処理は頻繁に行う必要があり、短時間で処理を終える
必要があるの?
>>660 10Kバイトくらいをバッファとして用意していて、入力が数バイトしかなければ
残りの9Kバイトくらいは無駄になりますね。
けれど、実際の環境において、9Kバイト余分に使用したからといって
破綻するような精一杯な状態って、あまりないですよね。
富豪的プログラミングというか、そういう発想でいいと思いますよ。
どうしても無駄にallocしたくない、って言うのであれば一文字ずつ取得して、
都度reallocすればいいと思いますが。。
668 :
660 :2008/06/04(水) 21:16:55
>>662 >>663 >>667 レスありがとうございます。
プロバイダ規制中のため、携帯でちまちま打ってたら反応が遅くなってしまいました。
打ってる最中でしたが、望んでいた答えが
>>667 さんから得られたので、
ここは、富豪的プログラミングということで手を打ちたいと思います。
ありがとうございました。
ネストしない限り、自動変数は低コストだろ。
>>657 VBAから呼ばれる関数の引数で返せばいい。
配列(ポインタ)引数で、要素に書き込んでおけば、VBA側にも反映される。
printfとかscanfの戻り値はどう決まってるんですか?
そのくらいドキュメント読めばわかるような
文字
「単位」と聞いているのだよ
単位は"char(s)"です。和訳すれば文字です。
charのときもあればwcharのときもあるのだよ
printfの戻り値の単位はcharだが、scanfのは個だろ。
なんかスレ違いのような気がするけど… Cのエディタって何使ってます? 今までVS使ってたんですけど、マイコン用のに使うのには向かなくて… テキストエディタでオススメの教えていただけませんか? 個人的に、ヘッダファイル読んで構造体や関数の補完入力、表示の機能があるといいですね。
>>681 個人的にはvimなんだけど、sakuraとかemacsとかEclipseもいいんでないの?
etagsだとかctags対応してるエディタならだいたい可能だね つってもVS見たいなポップアップではないが
>>660 宿題スレから。realloc() を使います。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFSIZE 3 /* >= 2 */
char *getline(void) {
static char inbuff[BUFFSIZE];
char *outbuff_malloc, *tmpbuff, *p;
int fEOL;
if ((outbuff_malloc = malloc(1)) == NULL)
return NULL;
*outbuff_malloc = '\0';
fEOL = 0;
do {
if (fgets(inbuff, BUFFSIZE, stdin) == NULL) break;
for (p = inbuff; *p != '\0'; p++);
if (*(p - 1) == '\n') { *(p - 1) = '\0'; fEOL = 1; }
if ((tmpbuff = realloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1)) ==NULL) { free(outbuff_malloc); return NULL; }
strcat(tmpbuff, inbuff);
outbuff_malloc = tmpbuff;
} while (!fEOL);
return outbuff_malloc;
}
int main()
{
char *inputLine_malloc;
if ((inputLine_malloc = getline()) != NULL) { printf(">>%s\n", inputLine_malloc); } else { printf("getline: cannot alloc memory.\n"); }
free(inputLine_malloc); /* NULL ok */
return 0;
}
/* end */
#include <memory> #include <string> #include <cstddef> // T 型オブジェクト e 個分の領域を確保し、値 t で埋める template< class T > void foo( const int e, const T& t ) { using namespace std; allocator< T > alloc; T *begin, *end, *iter; // 領域の確保 begin = alloc.allocate( e ); end = begin + e; uninitialized_fill( begin, end, t ); // 何らかの処理 // 領域の開放 iter = end; while( iter != begin ) { alloc.destroy( --iter ); // オブジェクトを後方から順に破棄 } alloc.deallocate( begin, end - begin ); // 確保した領域を破棄 } 上記のような関数で、領域開放の際、 deallocate の前に 各要素に対して destroy を実行するのが通例ですが、 これを行う意味ってなんでしょう? 実行しない場合、何が起こると考えられますか?
デストラクタが呼ばれないという、全プログラマを恐怖のどん底に突き落とす事件が発生します。
688 :
686 :2008/06/05(木) 00:32:49
>>687 なるほど。
型 T がポインタやクラス(特に自らリソースを確保するクラス)であったような時
メモリリークを引き起こす可能性があるわけですね。
一方、型 T が int や double であった場合には
オブジェクトが使っているメモリ領域は
まさに deallocate で削除される領域なので問題はおきない
と考えてよろしいでしょうか?
まあね。でも、テンプレートの場合は言わずもがな、 テンプレートを使わない場合でもコードが入り組んでくると ほにゃらら_tみたいな、実態が組み込み型なんだかクラスなんだか 後で組み込み型からクラスに変更されるかも知れないような怪しいtypedefが出てくるので、 POD型の時にはデストラクタを呼ばないようなテンプレートを書いておいて call_destructors<T>(begin, end); みたいな感じで必ず記述しておいたほうが良いと思うけど。
podかどうか判定する演算子とかあったっけ?
Boost使うとか出来る範囲で自分で書くとか、非標準だけど__is_podとか。
692 :
686 :2008/06/05(木) 01:35:29
クラスでいきなり詰まりました。 VC++2008EEで独自のダイアログを表示するクラスを作ったのですが、メンバ関数からDialogBox()する時に同じメンバ関数のダイアログプロシージャを呼ぶ方法が良く分りません。 DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), g_hWnd, hoge::MsgBox); ↓ error C3867: 'hoge::MsgBox: 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&hoge::MsgBox' を使用してください その通り書き換えてもキャスト出来ない旨のエラーが出ますし、ヘルプの凡例には該当するものがなくて対処出来ません。 クラスを使わなければ表示出来るのですが、何が原因でしょうか。
this->MsgBox
>>693 MsgBoxが非staticメンバ関数であることが原因
非staticメンバ関数にはthisポインタという隠れた引数があるので普通の関数と同等には扱えない
そういう場合には普通の関数かstaticメンバ関数を渡しておき、
何かのトリックを使ってどこかからthisポインタを取り出し、それを使ってメンバ関数を呼ぶ
>>694-695 回答ありがとうございます。
処理が複雑になりそうなので(普通の関数とローカル変数を使えば出来そうな気もしますが)、現状ではダイアログプロシージャをクラスに含めない事にしました。
本当にありがとうございました。
>>691 あー__is_podか。
大分前にispodって書いてる人がいて、それで検索してたんだけど、
どうりで見つからなかったわけだ。
C で日本語のオートマトンを書きたいのですがヒントをくれませんか
>>689 > POD型の時にはデストラクタを呼ばないような
それ、まさにallocatorのdestroy。
正確に言うとx.~T()の構文はPODでもエラーにならず、何の効果も起きないだけ。
ちなみに、こんなコードも合法のはず。
int main()
{
typedef int t;
t i;
i.~t();
}
タスクトレイにメッセージバルーンを任意のタイミングで表示させたいんですが やり方が分かりません。 アプリケーションのアイコンをタスクトレイに表示させた後、そのアイコン上に マウスを移動させた場合に指定したメッセージを表示させる事は出来ます。 これを、マウスをアイコン上に移動させなくてもイベントが発生した際に バルーンを表示させるようにしたいのですが・・・。 NIM_SETFOCUSを使えば似た事が可能なのですが、NIM_SETFOCUSを利用すると ウィンドウのフォーカスがアイコンに持っていかれてしまうので不便です。 別のやり方は無いでしょうか? 伝えにくいので以下に現状のプログラムを示します。 NOTIFYICONDATA g_nid; case WM_CREATE: ZeroMemory ( &g_nid, sizeof( NOTIFYICONDATA )); sprintf( g_nid.szTip, "TESTメッセージです" ); g_nid.cbSize = sizeof( NOTIFYICONDATA ); g_nid.hWnd = hWnd; g_nid.uID = TRAY_ID; g_nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; g_nid.uCallbackMessage = MYWM_NOTIFYICON; Shell_NotifyIcon( NIM_ADD, &g_nid ); break; case WM_MYEVENT://任意のタイミングでメッセージを表示 Shell_NotifyIcon( NIM_SETFOCUS , &g_nid );//フォーカスを割り当てる、これで一応バルーンは表示される break;
ググれば分かるきがする。
703 :
デフォルトの名無しさん :2008/06/07(土) 08:07:02
win9x、BCCです。 以下のプログラムで構造体を初期化するには どう記述すればいいでしょうか。 括弧のつけ方をいろいろ変えているんですけど、 初期化の一部だけに括弧が付いているとか、 宣言構文エラーとか出てうまくいきません。 typedef struct { int a; int b; }FOO_STRUCT; typedef struct { FOO_STRUCT foo[2]; }HOGE_STRUCT; int main(void) { HOGE_STRUCT hoge = {{0, 1}, {2, 3}}; return 0; }
>>703 HOGE_STRUCT hoge = {{{0, 1}, {2, 3}}};
706 :
デフォルトの名無しさん :2008/06/07(土) 13:44:39
自動変数は解放の必要が無いですが、 なぜ calloc等で動的確保した変数には、 解放のコードを書かないといけないのでしょうか、 逆に自動変数はなぜ解放のコードが不要なのでしょうか。
メモリはすべて確保/解放しなければなりません 自動変数は自動的に確保/解放されるから「自動」変数なのです
>>707 ありがとうございます、初歩的な質問ですみませんでした
行列の乗算を演算子オーバーロードで表現したいのですが 結合規則の問題で悩んでます。 |A| = |B|*|C|*|D|の式をプログラムで表現するときに、 MATRIX matA, matB, matC, matD; matA = matB * matC * matD; と書いて表現させたいのですが、普通にやると |A| = (|B|*|C|)*|D| と認識してしまいます。 ()などを使わずに 右辺を右から左の順序で乗算させる方法が何かありませんでしょうか
同じ優先順位の二項演算子は左から順に組にすることになってるので、 結合律が成り立たない場合は括弧で括ってください。
>>710 ありがとうございました。
それでやろうと思います。
行列の積って結合則なかった? (B×C)×D = B×(C×D) でしょ? どっちでも一緒じゃん?
>>712 結合順によって計算量が変わる可能性は高い
>>712 行列演算で×を使うと意味が変わっちゃうよ
直積には ⊗ を使わなかったっけ?
行列は内積だろうが外積だろうが掛ける順番が変わっても問題ない。 ただ外積は順番によっては計算量が著しく変わる。内積はどんな順番でも行 * 列 * 項の数で一定
計算量を考えるのであれば そもそも行列積に operator* を使わない方がいいと思うが。
>>716 A 100x100
B 100x100
C 10x100
(AB)C
100x100x100+100x10x100=1100000
A(BC)
100x10x100+100x10x100=200000
行列の内積って Σij AijBij のことか?
フロベニアス積だっけ?
そこでシューア積ですよ
それって内積と呼ぶんだろうか? そして行列の外積って何を表しているんだろう?
間違えた。 Σij AijBji のことか? と聞こうとしたんだった。 要するに tr A^T B
外積とは、ふたつのオペランドベクトルに対して直交したベクトルを返す演算の事 _,,....,,_ _人人人人人人人人人人人人人人人_ -''":::::::::::::`''> ゆっくりしていってね!!! < ヽ::::::::::::::::::::: ̄^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄ |::::::;ノ´ ̄\:::::::::::\_,. -‐ァ __ _____ ______ |::::ノ ヽ、ヽr-r'"´ (.__ ,´ _,, '-´ ̄ ̄`-ゝ 、_ イ、 _,.!イ_ _,.ヘーァ'二ハ二ヽ、へ,_7 'r ´ ヽ、ン、 ::::::rー''7コ-‐'"´ ; ', `ヽ/`7 ,'==─- -─==', i r-'ァ'"´/ /! ハ ハ ! iヾ_ノ i イ iゝ、イ人レ/_ルヽイ i | !イ´ ,' | /__,.!/ V 、!__ハ ,' ,ゝ レリイi (ヒ_] ヒ_ン ).| .|、i .|| `! !/レi' (ヒ_] ヒ_ン レ'i ノ !Y!"" ,___, "" 「 !ノ i | ,' ノ !'" ,___, "' i .レ' L.',. ヽ _ン L」 ノ| .| ( ,ハ ヽ _ン 人! | ||ヽ、 ,イ| ||イ| / ,.ヘ,)、 )>,、 _____, ,.イ ハ レ ル` ー--─ ´ルレ レ´
すみませんゆっくりAAは誤爆です無視してください
>>724 行列でouter productって言ったらテンソル積のことじゃね。
マーチングキューブ法について質問があります。
http://www.jspf.or.jp/cd2/7505cd/75-5/sakagami/2-11.html などのサイトに乗っている15種類の状態からでは2^8=256通りではなく254通りしか
生成できません
具体的には立方体のうち向かい会う2面のそれぞれ対角線上の格子点が垂直をなすように
ON(OFF)になっているケースの2通りの状態が含まれていません。
どこのサイトを見てもこのことに関する情報はありませんでした。
マーチングキューブ法ではこのような状態は異常として無視して描画しないのでしょうか?
しかしどこを見ても必ず「256通り」の記述があるのがどうにも・・
外積にそんなに呼び名があるなんて知らなかった・・・ おまいら頭だけはでかいんだな
ソースも貼らずに質問とな?
>>730 14通りのうち表の左上が0。
そしてトポロジーにより0の状態が2つある。
よって2^256 - 2 = 254
734 :
デフォルトの名無しさん :2008/06/07(土) 19:34:22
次の式を使って自然対数の底の値を求めよ 1+Σ(1/i!) (1〜10まで) やってみたのですが分かりません。 何がおかしいでしょうか? #include <stdio.h> main(){ int i,fact; double j,e; fact=1; i=1; while(i<=10){ fact=fact*i; j=1/fact; i=i+1; } e=1+j; printf("e=%lf\n",e); }
j=1.0/fact;
>>734 とりあえず
1/fact;
これの結果は切り捨てになるぞ?
0.いくつとかにはならずに
#include <stdio.h> main(){ int i,fact; double j = 0.0,e; fact=1; i=1; while(i<=10){ fact=fact*i; j+=1.0/fact; i=i+1; } e=1+j; printf("e=%lf\n",e); }
すいません参考にしていたサイトが間違っていたことに今気が付きました
13番目の状態が
>>730 で欠落している2箇所にあたります
ポリゴンは正しいけど黒丸の表示位置がそれとずれていました
739 :
デフォルトの名無しさん :2008/06/07(土) 19:46:36
>>735 doubleで定義すると1.0としないとだめなんですか?
>>736 なぜですか?
>>737 なぜそういう風にしないといけないのか教えてもらいたいのですが・・・
doubleでぐぐれ
>>739 整数同士の演算結果は整数だから、そんでその結果をdoubleにして代入だから
暗黙の型変換とかでぐぐれ
742 :
デフォルトの名無しさん :2008/06/07(土) 20:04:23
>>740 doubleだけだとちょっと辛いだろw
そこから学べばOK
いっそgnu mp使っちゃおうぜ!!
[1]プログラミング [2]問題文 三つの整数値を読み込んで、それらの値が全て等しければ、「三つの値は等しいです。」と、どれか二つの値が等しければ、「二つの値が等しいです。」と、そうでなければ、「三つの値は異なります。」と表示するプログラムを作る。 [3-1]windows [3-2]gcc [3-3]C言語 [4]明後日まで。 [5]if文を使って下さい。お願いいたします。
あまりの最適化された回答に理解できなかったらしいな。w
書き忘れました 目的はWin32版のビルドです
VC++ 4.0 じゃなくて eVC++ 4.0 のようだけど
>>750 上手くいきません、だけじゃ回答の仕様が無い。
何をやって、どういう状況になったか明確に説明せずに、回答者側にそれを想像することを求めている?
そもそも、そのブログに
>eVC++ 4.0、eVC++ 4.0のサービスパッチ、PPC2003 SDK、PPC2003のエミュレータを順次インストールすればOK。
と書いてあるのに、勝手にVC++2005を使って上手くいかないと言われても。
VC++2005の他に何かインストールしなければいけないのではなく、上記のものを正しくインストールすべき。
>Visual C++ 4.0などを入れてファイルを開いたら固まるので
これについてはどこか他スレで。
その他のプラットフォームについて 自分では試せないので、上記を参考に試してみてください。 現在GSPlayer2は「Windows Mobile 2005」にも対応してます。この場合は、「Visual Studio 2005 Standard Edition」でビルドするんですかね。 相応のSDKも必要になるでしょう。 ただ、上記の手順で作ったバイナリは、H/PC系を除き、各種WMで動くと思います。 をやろうとしたんだと思う。多分。
755 :
750 :2008/06/08(日) 13:02:52
>>753 >VC++ 4.0、eVC++ 4.0のサービスパッチ、PPC2003 SDK、PPC2003のエミュレータを順次インストール
はやったのですが固まってしまうので下の方に書いてあるVisual Studio 2005 Standard Editionを入れました。
libmad.vcwを開くとあるのですが見つからないので、libmad.dspをダブルクリックで開くと
「Visual C++ プロジェクト形式に変換されなければなりません」と出たので変換して開いてソリューションのビルドをすると1 失敗となってしまいます
>>754 それをやろうとしたんですが上手くいきませんでした
>相応のSDKも必要
とあるので何かインストールしなければならない物があるのかと思ったのですが見当違いでしょうか
初心者は何故、初期状態で動かす努力をしないのだろう。 勝手に、インクルードのパス変えてみたりフォルダの構造変えてみたり・・・ 聴いてみれば、あれがなかったからかえてみた。とか、パスを通すの面倒だからコピーしたとか・・・・ どんな経験者でも、他人が作ったプロジェクトのどこにノウハウが隠れているか分からないものを変更するのは細心の注意が必要なのにな。
>>755 >ソリューションのビルドをすると1 失敗となってしまいます
ビルドエラー時にもっと詳細なメッセージが出ているはずだけど、それについて調べる努力はした?
自分にとって意味不明なメッセージはスルー?
>>753 も書いているけど、失敗というだけでなくもっと詳細な情報を出さなければ回答してもらえないよ。
たぶんこのスレで聞く様な問題ではなく、visual stdioとかそっち系を探すべきだとは思うけど。
758 :
750 :2008/06/08(日) 13:54:49
☆2005はやめて2008入れようね☆
>>758 をまとめてみた
d:\gsplayer\libmad\libmad.c(2) : fatal error C1083: include ファイルを開けません。'windows.h': No such file or directory
char a[] ="str"; ++a; /* lvalue required as increment operand */ printf("%p", &a);でアドレスは取れるのにもかかわらず、このaは左辺値じゃないんですか?
配列型ってインクリメントしていいのか?
>>761 lvalueでもmodifiableなものとそうでないものがある。
その例のほかに、たとえばconst修飾されたlvalueはmodifiableでない。
764 :
761 :2008/06/08(日) 16:00:36
>>762 代入が不可能である時点でインクリメントが出来ないんだろうなという気はするんですが、
>lvalue required as increment operand
というような表現なんで不思議に思ったのですよ
>>763 じゃあこのエラーメッセージは罠で、
aが変更不可能な変数であることがポイントって事なんでしょうか?
>>761 char a[] は、
char* const a だと思っておけ。
ISO/IEC 14882 5.19-4 The pointer shall be created explicitly, using the unary & operator, or implicitly using a non-type template parameter of pointer type, or using an expression of array (4.2) or function (4.3) type. このルールで右辺値じゃないけど&でポインタをとれる
>>764 そもそもa[0]などがlvalueであって、a自体はlvalueではないだろ。
&演算子が使えるかどうかはlvalueであることとは無関係では?
aは変更可能な左辺値って奴だろう
>>761 lvalue の解釈を「アドレスが取れるもの」とせずに、素直に「代入式の左辺に置けるもの」と
考えておけば何も問題ないエラーメッセージじゃないか?
770 :
768 :2008/06/08(日) 16:19:34
すまん逆だ modifiableでないlvalueだ
関数だって左辺値だしな。確か。 左辺値なら何でも代入可能とは限らない。
#include <iostream> #include <bitset> #include <boost/lambda/lambda.hpp> #include <boost/cstdint.hpp> int main() { double d=1.0; std::bitset<64> b(*((boost::int64_t *) &d)); namespace bl=boost::lambda; for (int i=0; i < b.size(); ++i) std::cout << b[i]; } doubleのビット表現をbitsetにぶちこむ為に一時変数使ってポインタのキャストしてるんですが こういう面倒臭いことせずに std::bitset<64> b( foo(1.0) ); みたいに一発でできる方法ってないですかね?
std::bitsetって確かstd::stringを引数に持つコンストラクタあったろ。 std::string("0110110101")みたいな
>>772 一時変数を使うほうが分かりやすいと思うぞ。
reinterpret_cast<boost::uint64_t const&>(static_cast<double const&>(1.0))
そもそも標準のbitsetでは、コンストラクタが
773も言っているstringを取るやつと、unsigned longを取るやつ、
あとコピーコンストラクタしかないからうまくいかなくても知らないぞ。
>>772 double型を引数としてビット表現を文字列表記したstd::string型を返す関数fooを用意すれば
>std::bitset<64> b( foo(1.0) );
という風にかけるんじゃない?
以下は適当に書いてみた。テストもコンパイルもしてない。
template<typename T>
std::string foo(T d)
{
char buf[sizeof(T)];
for (int i= 0 ; i < sizeof(T) ; i++)
{
buf[i] = *(reinterpret_cast<char*>(&d))[i/8] & (0x80 >> i%8);
}
return std::string(buf);
}
× *(reinterpret_cast<char*>(&d)) ○ (reinterpret_cast<char*>(&d))
めちゃくちゃだけど雰囲気は伝わった。
そういやoperatorによるキャストって、C++のキャスト演算子でも使えるの?static_castあたりか
当然使える
しかもif()はboolを引数に取る関数です。
じゃぁifのオーバーライドって可能なのか?
関数じゃねえよw
俺、catchをオーバーライドしてくるわw
さあ while をオーバーロードする作業に戻るんだ
部長それは昨日やりました
#define while myfunction
#define wife my_fiction
#define nagato my_wife
#error
#ifdef nagato #undef nagato #endif
return -1;
#define private public
なんかキモいスレが続いてるな
明日は日曜日だからな
795 :
デフォルトの名無しさん :2008/06/09(月) 23:34:24
すいません、質問なんですが 構造体の配列をユーザ関数で作って それをメイン関数に返したいのですが可能ですか?
796 :
デフォルトの名無しさん :2008/06/09(月) 23:35:40
配列のインスタンスを返すというのなら無理
template<typename T, unsigned int L> struct array_wrapper{ T data[L]; }; array_wrapper<int, 10> function(){ array_wrapper<int, 10> result_value; /* ... */ return result_value; }
799 :
デフォルトの名無しさん :2008/06/09(月) 23:45:29
関数の中で構造体はmalloc関数で確保してるんですけど、 どうすればメイン関数で使えるか分からないんです 返却値を構造体の配列の0番目の要素のアドレスにして、 メイン関数で使おうとしたら、0番目の要素以外には処理に使えなくて… どうすれば、メイン関数ですべての構造体の配列が使えるようになりますか?
800 :
795 :2008/06/09(月) 23:47:39
今頃ですいません 使ってるのはCです
>メイン関数で使おうとしたら、0番目の要素以外には処理に使えなくて… 使えるよ。 どう使えないの?
802 :
デフォルトの名無しさん :2008/06/09(月) 23:48:50
ヒント:a[n] == *(a + n)
なんか、宿題が増えてないか?
宿題とな?
805 :
795 :2008/06/09(月) 23:57:59
for(i = 0; i < n; i++){ printf("%d n",a[i]->num); } 見たいな処理を関数内とメイン関数内ですると 構造体を作った関数内では表示できるんですけど メインでは0番目の要素を処理した後に処理が止まります
806 :
デフォルトの名無しさん :2008/06/09(月) 23:58:57
a[i]はポインタじゃないから普通にドット演算子a[i].numでいい
そりゃあC++でいいなら、配列をクラスに隠蔽させるだろw
808 :
デフォルトの名無しさん :2008/06/10(火) 11:20:43
DWORD値をTCHARに入れるのはどうすればいい?
DWORD foo = 1; TCHAR bar = foo; 但し、桁あふれに注意。
C言語で、標準出力する際のタブ(もしくはスペース)の幅を揃えることって出来ますか? 「char型データ(\t)int型データ(\t)int型データ(\t)double型データ(\n)」 この形式で、保存されている分(1件〜無制限)だけデータを表示させたいのですが、 char型データは最大で全角20文字で、この文字数によって表示が崩れてしまいます。
811 :
810 :2008/06/10(火) 15:24:03
すみません、ちょっと説明が足りなかったかも。 氏名 英語 数学 平均 ほげ 20 21 20.5 名無しのごんべ 100 100 100.0 このように揃えたいのですが、現状だと 名前 英語 数学 平均 ほげ 20 21 20.5 名無しのごんべ 100 100 100.0 名無し 50 50 50.0 このように表示されてしまいます。
ずれてたorz
>>810 それはchar型ではなく、char配列だろ。
と言うのはさておき、printf()を使えば済む話なのか?
printf("%20.20s\t%12d\t%12d\t%24.20g\n", string, int1, int2, double1)
>>813 そうでした、ご指摘ありがとうございます。
printf("%40.40s\t%d\t%d\t%0.1f\n",p->name,p->english,p->mathematics,p->average);
このように記述したところ、一応揃いました。
ただこの構造体は、毎回標準入力でデータを保管していくので、氏名の文字数も毎回変わります。
その都度(全データにおけるの氏名の最大文字数)に合わせて幅を変えたいのですが、可能でしょうか?
そんなのねえよ!というのであれば、ここで諦めるのですが・・・。
>>814 printf("%*s", 40, "string")
怖い構造体書くなぁw
817 :
デフォルトの名無しさん :2008/06/10(火) 20:12:48
C++の頂点を極めあらゆる質問に答えて下さる皆さんに質問があります。 VS2003のVC++のGDI+なんですが、 Font font = new Font(dc, &logfont); とするとフォントをインスタンス化できますけど、logfontのフォント名に "@MSゴシック" のように横に傾くフォントを指定すると、うまく指定され ないように思われます。 たとえば LOGFONT lf1, lf2; lf1.lfFaceName = "@MS ゴシック" Font* font = new Font(dc, &lf1); font->GetLogFontW(&graphics, &lf2); というように確認してみると、lf1には確かに"@MS ゴシック"がセットされて いるのに、lf2には"@"が外れて"MS ゴシック"がセットされてしまいます。 私は何を勘違いしてるでしょうか?
とりあえずC++とはまったく関係ないな
819 :
817 :2008/06/10(火) 20:31:54
環境依存なものでもOKじゃないんでつか… ぷーん それじゃ他のトコで質問してきます…
820 :
デフォルトの名無しさん :2008/06/10(火) 21:17:12
関数ポインタの配列の様に、クラスの配列を作ってみようと思ったのですがなかなか上手く行きません。 どのように書けばいいのでしょうか #include <iostream> using namespace std; class A { public: virtual void func() { cout << "func A" << endl; } }; class B { public: virtual void func() { cout << "func B" << endl; } }; enum COMMAND { FUNCA_CMD, FUNCB_CMD, EoC }; int main() { A a; B b; void (*f[EoC]) = { &a, &b }; //(*f[FUNCA_CMD])->func(); エラー return 0; }
共通の基底クラスが必要(ほかにも方法がないわけではないが)。 class Base { public: virutal void func() = 0; } class A : public Base { public: virtual void func() { cout << "func A" << endl; } }; class B : public Base { public: virtual void func() { cout << "func B" << endl; } }; int main() { A a; B b; Base* f[2] = {&a, &b}; f[0].func(); f[1].func(); }
ありがとうございます。 次は示して頂いた物をテンプレートを使って再現できないか弄ってみます。
どこをテンプレート化するか興味があるので、出来たら成果を見せてくれないか。
あ、他にも方法があると聞いてテンプレートで出来るのかと思っただけです。 template < class _T > sub( _T & t ) { A aa; B bb; t F[2] = {&aa, &bb}; // error } int main() { A a; sub ( a ) } なんだか二度手間っぽくて面倒だし、型もBはAに出来ないと言われちゃいましたw
t F[2]はおかしいだろ
まぁ、一つずつ知識を深めていけば良いと思うよ。
深みにはまると大変なのでテンプレートはほどほどに。
828 :
デフォルトの名無しさん :2008/06/11(水) 01:37:31
テンプレートクラスのプライベートなメンバを <<演算子 で出力可能にするため↓ #include <iostream> template < class T > class test { friend std::ostream& operator<< ( std::ostream& os, test< T > t ); public: void set( T val ) { x = val; } private: T x; }; template < class T > std::ostream& operator<< ( std::ostream& os, test< T > t ) { os << t.x; return os; } ↑のようにfriend宣言したとき、 int main() { test< int > t; t.set( 5 ); cout << t << endl; } とするとエラーが出るのですがなぜでしょう・・・。orz テンプレートクラスでなければ問題なく動くのですが・・・。
多分 template < class T > class test { friend template< class U > std::ostream& operator<< ( std::ostream& os, test< U > t ); public: void set( T val ) { x = val; } private: T x; }; 本当は知らない。
>>828 エラーメッセージぐらい貼ろうぜ。
どうせ friend の <> なんだろうけど。
初心者で、且つ馬鹿な人にとっては、 エラーメッセージは「エラー」という意味しか持たないものだから、 どういうエラーが出たかを書くという行為にまったく意味を見出せないんだろうね。 いつか胃ガンにでもなった時、「病気である」とだけ解釈してどういう病気かまったく興味を持たず、 呑気に胃薬飲み続けて死ねばいいと思うよ。
エラーはコンパイル時エラーではなく 実行時クラッシュです・・・
追記すると、つまりエラーはありません。 コンパイルは通るのです。
コンパイラは何よ? テンプレート周りにバグ抱えてる処理系はまだまだ多いぞ
デバッグの勉強をする段階に来たって事じゃないの。
>>832-833 実行時クラッシュでもエラーメッセージは出てるだろ?
そうじゃなけりゃ何を見て「実行時クラッシュ」だと思ったのさ?
あのコードってコンパイル通る方がおかしくね?
どうせ答えは
>>830 だろうけど。
>>829 VC9だけど通らない
Temaplate1.obj : error LNK2019: 未解決の外部シンボル "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class test<int>)"
(??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@V?$test@H@@@Z) が関数 _main で参照されました。
C:\Documents and Settings\*****\My Documents\Visual Studio 2008\Projects\Learn1\Debug\Temaplate1.exe : fatal error LNK1120: 外部参照 1 が未解決です。
template <class T> class test { template <class U> friend std::ostream& operator<<(std::ostream& os, test<U> t); public: void set(T val ){ x = val; } private: T x; }; これなら通るし正常に動く
840 :
デフォルトの名無しさん :2008/06/11(水) 18:19:36
クラス型のvectorからfindしたい場合で上手くいかないケースがあります。 class Hoge{ int nhoge; public: operator==(Hoge hoge){ if(this->nhoge == hoge.nhoge){ return true; }else{ return false; } } hoge(int nhoge){ this->nhoge = nhoge; } } class Hogehoge{ std::vector<Hoge> vHoge; public: std::vector<Hoge> getVhoge(){return vhoge;} void push_back(Hoge hoge){vHoge.push_back(hoge);} } main関数以下次レス。
841 :
840 :2008/06/11(水) 18:20:13
>>840 の続きです。
int main(){
Hoge hoge1(1), hoge2(2), hoge3(3), hoge4(4);
Hogehoge hogehoge;
hogehoge.push_back(hoge1);
hogehoge.push_back(hoge2);
hogehoge.push_back(hoge3);
std::vector<Hoge>::iterator itrHoge;
itrHoge = std::find(hogehoge.getVhoge().begin(), <-ここがおかしい
hogehoge.getVhoge().end(),hoge2);
hogehoge.insert(itrHoge,hoge4);
return 0;
}
とかいう感じでやりたいんですが、findのところで上手くイテレータを返してくれません。
hogehoge.getVhoge()を一時変数std::vector<hoge> tmpVhogeなどに格納してから
std::find(tmpVhoge.begin(),tmpVhoge.end(),hoge2)
などとやれば動くのですが、一時変数ではなく実体を直接いじりたいのでこれだと上手くないです。
原因がおわかりになるでしょうか?また、解決策はありますでしょうか。
コンパイラはcygwinのg++です。よろしくお願いします。
>>840 getVhogeがvHoge自身ではなくvHogeのコピーを返してるから
実体を直接いじりたいなら
std::vector<Hoge> &getVhoge(){return vhoge;}
843 :
840 :2008/06/11(水) 18:43:31
>>842 それでしたorz
とても助かりました。ありがとうございます。
Effective C++にも似たようなことが書いてあったので読んで修行します。
C++覚えたての初心者です。 ベンチマークソフトと言ったら大袈裟ですが HDDの単純な読み書き性能テストを行える ソフトを作ろうかと思ってます。 単純にファイルの読み書きを100回位やった ラップタイムを計測しようと思っています。 ベンチマークソフトのHDD性能計測ってなんか 凄いロジックとか使ってるんでしょうか? C++じゃダメで何か他の言語じゃないと いけないとかあるんでしょうか? アドバイスをお願いします。
だいたいそういうベンチは、OSのキャッシュにやられて、 メモリ/CPUの速度を測るオチになる
OSのAPIを叩いてCPUのキャッシュサイズを評価してスコアを出す≒HDDのベンチマークソフト
847 :
デフォルトの名無しさん :2008/06/11(水) 21:55:06
vectorを指すイテレータを使ってinsertしたとき、 挿入が終わったあとにイテレータが指している要素が 場合によって変わってしまう現象が起こります。 具体的には vector:12345 iterator:3 vector.insert(iterator,6) をやったときに vector:126345 iterator:6 となる場合と vector:126345 iterator:3 となる場合があります。 ちなみに前者は大きめのコードを書いてcygwin g++でコンパイル、 後者は検証用に仮想マシンのvine Linux上で書いてg++でコンパイルしてます。 原因等わかりますでしょうか。
>>847 変わるのは仕様
メモリ確保しなおすからアドレスが変わるの
イテレータセットしなおすかlist使うとかしてください
849 :
848 :2008/06/11(水) 21:59:43
すいません見なかったことにしてください
850 :
847 :2008/06/11(水) 22:05:19
すんません書き方が分かりづらかったです。 イテレータの位置が変わるのはいいのですが、 ・insertした要素を指すように変わる ・insert前に指していた要素を指すように変わる 場合が発生して、どちらかに統一されていないので困るという話です。 insert後のイテレータの位置は保障されないってだけの気もしてきました。 だとしたらなんて不便なんだvector…
google: iterator 無効化
853 :
847 :2008/06/11(水) 22:11:03
>>851 orz
ありがとうございます。
ランダムアクセスイテレータを前提にしたコードなので今更listにするわけにもいかず…。
いちいちinsertする度にfindするしかなさそうですね。遅くなりそうだ…。
854 :
847 :2008/06/11(水) 22:15:22
>>852 それだ(;´Д`)上手く行きました!どうもありがとうございます!
855 :
デフォルトの名無しさん :2008/06/11(水) 22:38:55
struct na *ni(); って関数があったとき、 void mein() { struct na = *ni(); } って呼び方あってる?
856 :
デフォルトの名無しさん :2008/06/11(水) 22:41:39
main(){ printf("A"); sleep(1); printf("B"); } としてもABが同時に表示されるのは何故ですか? sleep(1) を system("sleep 1") としても同じです。 コンパイラは gcc version 4.1.2 20061021 prerelease (NetBSD nb3 20061125) です。
同時って意味わからん。AとBが同じ行に出るのは\nが不足しているから。 AとBが重なって出るようなら端末がしぼん
あ、判った。stdioのバッファリングの事を言ってるんだな。 切ってしまうか必要に応じてfflushするか、stderrに出力するか
>>856 バッファの問題じゃないかな
printf("A");
fflush(stdout);
sleep(1);
printf("B");
ってやってみては?
>>855 ni()の仕様による。mein()ので正しい場合もある。
>>856 printf()の出力がバッファリングされているから。間にfflush(stdout)
とか入れると意図どおりになるかと。
while(1){ fgets(buff,sizeof(buff),stdin); if(!strcmp(buff, "A\n")){ ..... } 上のプログラムで、何故かループ2週目からのfgetsでキーボードからの入力を待機せずにそのままif文に入ってしまいます。 どなたか原因を教えていただけないでしょうか(´・ω・)
865 :
デフォルトの名無しさん :2008/06/11(水) 23:17:37
VisualStudio2005 core2duoマシンで win32API勉強中なんですが、 CreateProcess("hoge.exe",..., pInfo); WaitForSingleObject(pInfo.hProcess, INFINITE); DeleteFile("hoge.exe"); とやると たまに DeleteFileが失敗するときがあります。 アクセス拒否 5 を返してるようです。 まだプロセスが終了していないということなのでしょうか。
入力がバッファに残ってるから 移植性のある解決方法としては空読みして捨てるしかない
867 :
863 :2008/06/11(水) 23:18:34
buffは256とってあるのですが、足りないですかね
868 :
863 :2008/06/11(水) 23:22:19
>>864 更にbuffを増やしてみたら解決しました。アドバイスありがとうございます!
869 :
デフォルトの名無しさん :2008/06/12(木) 00:42:08
typedef struct tagSerialParam { DWORD dwBaudRate; // 取り得る値 9600/19200/38400 BYTE byByteSize; // 取り得る値 4/5/6/7/8 ・・・ // 上記以外の5個ほどの変数 }SERIAL_PARAM; CSerialCom::Open(SERIAL_PARAM *pParam) { // 引数チェック {・・・} // dcb構造体に代入 GetCommState(hComm, &dcb); } 上記のような型が違う可変の引数を複数チェックをする場合、 みなさんならどのように実装しますか? ケースバイケースと言われそうな気もしてますが、 ソースコードの可読性を優先して実装案をお願い致します。
int sum(int min,int max){ int num; num = min + max; return num; } 例えばこれだったら int sum(int min,int max){ return min + max; } でもいいと思うんだけど そうしないのが慣習なのは見やすくするため?
>>869 構造体チェック用の関数を作る
さらに構造体メンバそれぞれについてチェック用の関数を作る
構造体自身を隠蔽して(不完全型)セッターでのアクセスしかできないようにする
C++ならセッターで制限する
>>870 そこまで短いコードだったら下1択でいいと思うよ。
>>870 書き方がまちまちだと気持ち悪いから統一する
自分のルールに則ってるだけ
自分ルールでOKなら下でいいんじゃないかな
複数人開発なら気持ち悪いの度合いが違うからルールを統一する
このときはルールを厳しくした方が例外出にくいから上の書き方に統一したりする
デバッガで止めたい時もあるからなあ
>>872-875 ありがとうございます
もし誰かと何か作ることになったら周りの人に合わせる感じでいきます
>>876 最初の if 文の条件が成立してもしなくても、2番目の if 文が実行されるから
std::stringって、何でvectorとかと同じメソッドがついてるの?
何を訊きたいのかが不明瞭だなぁ。 「vectorとかと同じメソッド」というのは「コンテナと同じメンバ関数」という意味だろうけど、 「同じ」というのは関数名のこと? 機能まで含めてのこと?
グローバル変数をstaticつけて宣言するのって、つけない場合とで何らかの違いが現れますか? どちらの場合も同じような寿命を持つ気がするのですが、区別するべきですか?
別のファイルで同じ名前付けたやつ作ってもだいじょぶ
そういった効用があるのですね、ありがとうございます。
無名名前空間を使うほうがオススメだと聞いた。
どなたか、お暇な方いましたら教えて下さい。 ある処理の実行時間を計測しようと思い、次のようなコードを書いたのですが、うまく動きません。 int main() { s=GetTickCount(); { // 処理 } e=GetTickCount(); cout << s; cout << e; cout << e-t << endl; return 0; } このようなコードをコンパイル、実行すると、sとeが一致してしまいます。 一体なぜなのでしょうか? どなたか、ご回答よろしくお願いします。
分解能より短い時間で処理終わってるんじゃね? 試しに処理のとこにSleep()入れてみては
889 :
887 :2008/06/12(木) 19:21:15
sleep入れたら、計測できました。 GetTickCountで時間を取得するタイミングをずらしても計測できました。 でも、 s=GetTickCount(); { // 処理 } e=GetTickCount(); みたいにすると、計測できません。 一体なぜ? 極端に短い時間で処理が終了した? うーん…。 とにかく、ご回答下さった皆さん、ありがとうございました。
>>888 が書いてくれた内容まともに読んでいないようだな…。
staticをつけての内部リンケ−ジは C++的には「非推奨」なんで将来なくなるかも知れない 現実にはありえないだろうけど
>>889 最適化で、無意味処理として削られたんじゃないの?
ちなみにSleep()は削られないから測定可能。
GetTickCount()の替わりにQueryPerformanceCounter() 使ったらいいんじゃね? SetPriorityClass()で他のプロセスの影響を最小限に 抑えておかないと測定の度にバラツキが出やすいけど
(質問) C++です。プリプロセッサでsizeof(int)に応じて新しい型を定義したいのですが、 こういうことって不可能なんでしょうか?
>>891 クラスなど、無名名前空間にできてstaticでは不可能な
ものがあるということが大きな違いだと俺は思っている。
もともとの趣旨はstaticを静的確保の意味だけにする
(可視性制御の意味をなくす)ということだったと思うけど。
>>895 struct hoge;に対してsizeof(hoge)の結果を任意に決めたいってこと?
898 :
895 :2008/06/12(木) 23:48:34
>>897 いえ、例えば
#if sizeof(int) == 4
#define int32 int
#elif sizeof(int) == 8
#define int64 int
#else
#error("unsupported")
#endif
といったような感じです。通りませんけど。
>>898 目的がよく分からないんだけど
int と書いたほうが処理速度が速くなるんじゃなくて
処理速度が速いものが int だと思ったほうがいいよ
それを自分でやりたい理由が分からんが。 intのサイズは処理系依存で、大抵はその処理系のヘッダファイルにサイズ保証の整数型がtypedefされている。
901 :
895 :2008/06/12(木) 23:54:58
>>899-900 まあ上の例はただの例なんですけど、
やっぱりできないみたいなのでまた別の方法を考えてみます。
どうもありがとうございました。
sizeofの結果が得られるタイミングって、コンパイラによって違うんだっけ
C99だと場合によっては実行時だしな。
じゃあ必然的にプリプロセッサには使えないな
905 :
デフォルトの名無しさん :2008/06/13(金) 00:00:49
>>871 レスありがとうございます。
以下の認識でOKですか?
>構造体チェック用の関数を作る
>さらに構造体メンバそれぞれについてチェック用の関数を作る
→bool CSerialCom::CheckParam(SERIAL_PARAM *pParam) { bool ret = checkBaud(pParam->dwBaudRate); ...}
>構造体自身を隠蔽して(不完全型)セッターでのアクセスしかできないようにする
>C++ならセッターで制限する
→bool CSerialCom::Open() {}
bool CSerialCom::SetParam(void *pParam) {... m_Param = *(SERIAL_PARAM *)pParam) ...}
>>898 の例は意味わからんけど、
型のサイズに応じて別な型をtypedefするってことなら
まさにテンプレートの領域じゃないか?
selector<sizeof(hoge)>::fuga_type fuga; // hogeのサイズによってfugaの型が変わる
指定ビット数の整数型が欲しいなら、<stdint.h>使えばいいよ。
結局何をやりたいのか言わずに去ったからな。
909 :
871 :2008/06/13(金) 01:04:02
>>905 改行で間を空けてあるのは、それぞれ別の方法
つまり三つの方法を書いてあるだけなのでいずれか一つを採用すればおk
910 :
905 :2008/06/13(金) 01:17:46
>> 871 早々のご回答ありがとうございます。 便乗して追加質問よいですか? >構造体自身を隠蔽して(不完全型)セッターでのアクセスしかできないようにする >C++ならセッターで制限する 無学で申し訳ないですが、上記2案の差分がモヤモヤしてました。 もう少し詳しく意見をいただけませんか?(サンプルコードがあると助かります)
911 :
871 :2008/06/13(金) 01:46:02
>>910 Cの場合とC++の場合の対処方法が違うだけ
Cの場合には不完全型にしないと隠蔽できないから
// ----- hoge.h -----
typedef struct tagSerialParam SERIAL_PARAM;
SERIAL_PARAM *hoge_alloc(void);
void hoge_free(SERIAL_PARAM *param);
int hoge_BaudRate_set(SERIAL_PARAM *param);
// ----- hoge.c -----
#include"hoge.h"
struct tagSerialParam {
DWORD dwBaudRate; // 取り得る値 9600/19200/38400
BYTE byByteSize; // 取り得る値 4/5/6/7/8
・・・ // 上記以外の5個ほどの変数
};
static const DWORD dwBaudRateList[]={9600, 19200, 38400};
SERIAL_PARAM *hoge_alloc(void){
SERIAL_PARAM *param;
param=malloc(sizeof(*param));
param->dwBaudRate=dwBaudRateList[0];
param->... // 色々有効範囲内になるよう初期設定
return param;
}
int hoge_BaudRate_set(SERIAL_PARAM *param, DWORD dwBaudRate){
int i;
for(i=0;i<ARRAY_SIZE(dwBaudRateList);i++)
if(dwBaudRate==dwBaudRateList[i]){
param->dwBaudRate=dwBaudRate;
return 1;
}
return 0;
}
フリーソフトでメジャーなコンパイラとエディタってどんなのがありますか? 自分はBorland C++ CompilerってのとBCC Developer 1.2.21使ってるんですが 勉強になるかもしれないし他のやつ使ってみたいです
>>912 VC++ Express (コンパイラとエディタとその他もろもろのセット)とか。
GCC と Emacs とか。
>>913 エディタとしてインストールするのもありだな。これはいいこと聞いた
基本クラスを作る場合と、テンプレートを使う場合を比べると テンプレートを使うメリットと言うのは何になるんでしょうか。 自分なりに考えた結論としては下記のような感じなんですが ・コードを書く量が少なくて済む ・変数を扱う場合、型を指定しなくて良いので柔軟に出来る
>>915 目的も効果も違う2つを比べる意味がわからない。
何をするときの話?
基本クラスも作ってテンプレートも使えば? 比べるものではないと思うけど。
てっきり同じ物かと思ってました どんなときにテンプレートを使ったりするんでしょうか
>>919 とりあえず Google に聞いてみろ。ひとつでも解説ページを見れば同じ物だなんて思わないはずだから。
質問です 昔から愛用していたVC6.0製品版から、このたびVC9.0(VS2008)の無料版に乗り換えました。 VC6.0用のプロジェクトを9.0用に変換し、コンパイルを通したのですが、実行速度にだいぶ差があるように見えます。 単純なファイルコンバータプログラムなのですが、だいたい9.0版のほうが1.5倍程度時間がかかります。 両方最適化をONにしていますし、ソースも当然同一のものです。 時代が経過して性能が下がったというのは不思議なのですが、そんなものなのでしょうか? 2008質問スレで聞こうかと思ったのですが、そういうスレがなかったのでここで質問させていただきました。 よろしくお願いします。
安全性チェックのためのコードが挿入されて遅くなってるのかもね。 コンパイラオプション調べて弄ってみろとしか言えない。
エンコードの違いかな。 まぁ、2008のスレはあるけどね。
>>921 以前libc.lib(シングルスレッド版のCランタイム)を使っていたのなら、
マルチスレッド版ランタイムを使うようになったためである可能性が高いかな。
libc.libはVC7.1以前のデフォだが、VC8以後は無くなって、現在は
マルチスレッド版のCランタイムしかない。マルチスレッド版ランタイムは
デフォで排他制御を行うので、何も考えずにgetc()のようなものを使うと
パフォーマンスへの影響がデカい。
一応その対策として、_getc_nolock()のような関数が用意されているんだが。
MSDNの「マルチスレッドライブラリのパフォーマンス」の項目を
参照。
ttp://msdn.microsoft.com/ja-jp/library/ms235505 (VS.80).aspx
すばやいお返事ありがとうございます。
>>922 なるほど。確かにそのとおりです。オプション調べてみます
>>923 2008スレ自体はあったのですが、なんだかピリピリしていて・・・
>>924 あ、ほんとですね。マルチにさせられてます。
リンク先を読んで、改良してみようと思います。
シングルスレッド版のころそのもののスピードはでなくても、近い速度が出るといいなぁ
ありがとうございました。
改良してテストしたら、また報告に伺います
すいません、結構改造所がありそうだったので「また報告に〜」なんていいましたが、
>>924 のリンクの最後に
とりあえず #define _CRT_DISABLE_PERFCRIT_LOCKS しとけば、ファイルアクセスは全部nolock版使うよ
とあったので速攻試せました。
速度はがっつりあがり、VC6.0版の半分程度の時間で処理が終わるようになりました。
やっぱり最適化の部分は進化してたんですね!
アドバイスありがとうございました。
vectorに文字列を追加しつつ、 今までvectorに追加した文字列全てを ひとつの文字列にして返す関数が欲しくて 以下のように書いたのですが vector<const char*> ログ; char* ログ追加・取得(const char* getstr) { ログ.push_back(getstr); char logs[1000]; for(int i = 0; i<ログ.size() - 1 ; ++i) { strcat(logs,ログ[i]); } return logs; } strcatのところで入力した文字が化けてしまいます どこがまずいでしょうか?
vector<>とか使うんなら、ついでにstringも使えばいいのに
・strcatって、'\0'を見つけるまでコピーするんだぜ? ・ローカル変数を返してどーする
930 :
デフォルトの名無しさん :2008/06/13(金) 19:20:41
vectorから取得したbegin()やend()についてiteratorと同様に扱えないのは仕様でしょうか。 class Hoge{ int hogehoge; public: Hoge(int hogehoge){this->hogehoge = hogehoge;} int getHogehoge(){return hogehoge;} } int main(){ Hoge hoge1(1); Hoge hoge2(2); std::vector<Hoge> vhoge; vhoge.push_back(hoge1); vhoge.push_back(hoge2); std::cout << *(vhoge.begin()).getHogehoge(); <-この辺が上手くいかない std::cout << *(--vhoge.end()).getHogehoge(); <- } 例えばvectorの先頭要素と終端要素を比較したい場合にこういうのを使いたいのですが、 うまくコンパイルできません(getHogehoge()などというメソッドは無いと言われる)。 環境はcygwin g++です。解決策等あればよろしくお願いします。
>>930 × *(vhoge.begin()).getHogehoge()
○ (*vhoge.begin()).getHogehoge()
>>930 なんで全部hogeにするかなあ?
foo とか bar とか分けてくれないと難読化したようにしか思えないわ
933 :
デフォルトの名無しさん :2008/06/13(金) 19:34:39
>>931 それだー。ありがとうございます。
>>932 すみません。対称性が好きなもので。以後気をつけます。
MSVCRT.lib(crtexew.obj) : error LNK2001: 外部シンボル "_WinMain@16" は未解決です :\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\kadai\Release\kadai.exe : fatal error LNK1120: 外部参照 1 が未解決です。 このようなエラーがでてきてコンパイルできてもビルドできません どうすれば良いのか教えてください 使用ソフトはVC++2008EEです
>>934 コンソールアプリケーションなのにウィンドウアプリだと思ってリンクしようとして
エラーになっているんだよ
プロジェクトを作り直せ
>>929 \0ないとコピーし続けるって始めて聞きますた
>>928 charはもういや
string使うことにします
>>935 一応解決しました、また問題が発生した時はコードも一緒に張るのでその時はよろしくお願いします
>>936 解決しました
ありがとうございます
>>937 文字列を扱う関数はほぼ全部\0を終端の判断に利用するんだよ
だから\0は常につけとけ
Javaそれなり、C初心者です。 ビルドに関してなのですが、エラー0行目と表示されています。 Eclipseで確認しながら作成したのでおそらく書いたコード自体にはエラーはないと思います。 エラーがどういう意味なのかが分からないので質問させて頂きました。 作成したプログラムはソケット関連で、 「TCP/IPプログラミング C言語編」の一番最初のコードです。 エラーの詳細表示は Eclipse make: ***[libtcp_ip1.dylib] Error 1 line0 Undefined symbols: line0 Eclipse コンソール /usr/bin/libtool: internal link edit command failed make: *** [libtcp_ip1.dylib] Error 1 となっています。 これはどのように解釈すればいいのでしょうか?
少し長いので2つにわけます。 #include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define RCVBUFSIZE 32 void DieWithError(char *errorMessage); int main(int argc, char *argv[]){ int sock; struct sockaddr_in echoServAddr; unsigned short echoServPort; char *servIP; char *echoString; char echoBuffer[RCVBUFSIZE]; unsigned int echoStringLen; int bytesRcvd, totalBytesRcvd; if((argc < 3) || (argc > 4)){ fprintf(stderr, "Usage: %s <server IP> <Echo Word> [<Echo Port>]n", argv[0]); exit(1); }
servIP = argv[1]; echoString = argv[2]; if (argc == 4){ echoServPort = atoi(argv[3]); }else{ echoServPort = 7; } if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0){ DieWithError("socket() failed"); } memset(&echoServAddr,0,sizeof(echoServAddr)); echoServAddr.sin_family = AF_INET; echoServAddr.sin_addr.s_addr = inet_addr(servIP); echoServAddr.sin_port = htons(echoServPort); if(connect(sock, (struct sockaddr *)&echoServAddr, sizeof(echoServAddr)) < 0){ DieWithError("connect() faild"); } echoStringLen = strlen(echoString); if(send(sock, echoString, echoStringLen, 0) != echoStringLen){ DieWithError("send() sent a different number of bytes than expected"); }
totalBytesRcvd = 0; printf("Received: "); while(totalBytesRcvd < echoStringLen){ if((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE -1, 0)) <= 0){ DieWithError("recv() faild or connection closed prematurely"); } totalBytesRcvd += bytesRcvd; echoBuffer[bytesRcvd] = '0'; printf(echoBuffer); } printf("n"); close(sock); exit(0); } よろしくお願いします。
別ファイルです。記載し忘れてました。 #include <stdio.h> #include <stdlib.h> void DieWithError(char *errorMessage){ perror(errorMessage); exit(1); }
>>940 まずはシェルから自分で直接ccでコンパイルしてみて、
「何が」エラーを出しているのか切り分けたらいいと思うよ
どこかにアップしろっていう言葉が見えなかったの?って言われそうですね。 がんばって耐えるんだよ。
>>942 どこかにアップしろっていう言葉が(ry
ってのは冗談だけど、次に貼るときがあればインデント付けてね。
半角空白は消えるから全角空白で。
スレ上でも読みやすし、全角空白→半角空白の置換は簡単だから。
950 :
438 :2008/06/14(土) 00:39:55
お礼カキコ忘れていました。だいぶ前ですが・・ ありがとうございましたm(_ _)m
951 :
デフォルトの名無しさん :2008/06/14(土) 09:52:47
てst
>>942 インデントを気にするくらいなら、アップローダを使えばいい。
>949のような専用ブラウザも使わない阿呆は放置でいいからね。
953 :
デフォルトの名無しさん :2008/06/14(土) 10:13:59
専ブラ使わないやつはもれなく阿呆ですかそーですか
その点は間違いない
>>952 >専用ブラウザも使わない阿呆は
専ブラは全て同じ仕様だと思ってる阿呆ですか。
文句なら壷作ったマァブ達に言ってくれ。
んじゃ、訂正しておこう。 専用ブラウザも使わない、或いはインデントごときで駄々を捏ねる阿呆ってことで。 ちょっと手元のエディタにコピペして、インデント掛けさせるだけのことができないってどんだけかと。
で、それがこのスレと関係あるのかな 【初心者歓迎】C/C++室 Ver.54【環境依存OK】だろ スレとは関係無い所であおってばかりだな 何のスレかよく考えろよ
「インデントごときもかけない質問者」なんて思われたくないんで、俺は質問する時全角スペースインデントするよ
>>956 お前の頭にはemacsしか無いのかもしれないが、
多くの環境で、自動的にインデント掛けるより
全角空白を半角空白に置換する方が容易。
また、コピペするまでも無く読みやすい。
専ブラなどの余計な前提無しにな。
少なくとも、その程度のことも分からないお前に
阿呆と呼ばれる筋合いは無いな。
ちなみに質問者がロダにも上げず、半角空白のまま
貼ったとしても責める気は無いし、責めたことも無い。
より良いという話をしているだけだ。
初心者歓迎スレだから、初歩的な質問がどうしても他より多くなる。
で、初心者って、例を最少にする技術がまだまだだから、貼るソースが長くなりがちだし、
書き方も洗練されていないから、内容的に読み取りづらかったりするよね。
つまり、初心者歓迎スレであるが故に、「要所を押さえた貼り方をしなかった時の害」が、
通常より大きいってことなんだ。
つまり、ここが
【初心者歓迎】C/C++室 Ver.54【環境依存OK】
であるから、こういう話が通常より濃く交わされる、というのは、少なからず言える。
>>957 だから、関係関係と連呼するほど、関係無くはないんじゃないかな。
初心者に「インデント」だの「全角空白」とか言っても通じないから、 アップローダをつかってもらうの推奨ってことでおk?
962 :
デフォルトの名無しさん :2008/06/14(土) 13:55:10
まあ初心者歓迎と書いてある以上は全角スペースだろうが半角スペースで消えようが妥協して嫁ってことでいいだろ
質問です VC2008で_CrtSetDbgFlagを使い、メモリリークのチェックをしたところ Detected memory leaks! Dumping objects -> f:\dd\vctools\crt_bld\self_x86\crt\src\mbctype.c(593) : {4} crt block at 0x003D3728, subtype 0, 544 bytes long. Data: < > 02 00 00 00 A4 03 00 00 01 00 00 00 11 04 00 00 f:\dd\vctools\crt_bld\self_x86\crt\src\ioinit.c(136) : {2} crt block at 0x003D2110, subtype 0, 2048 bytes long. Data: < > FE FF FF FF C1 0A 00 00 00 00 00 00 00 00 00 00 f:\dd\vctools\crt_bld\self_x86\crt\src\tidtable.c(394) : {1} crt block at 0x003D1EC0, subtype 0, 532 bytes long. Data: <X > 58 12 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 Object dump complete. とメモリリークが検出されたんですが、 1.出力されたディレクトリのパスに自分のソースもVCのソースも入ってない 2.上記3つのソースはVCのディレクトリに入っていたので、ここがメモリリークの原因だとは思えない この2つの理由から対処に困っています。 この場合どうすればいいのでしょうか? OSはXPです。
空白が消えるのは2ちゃんの仕様ですでいいだろ
>>963 _CrtSetDbgFlagの下で_CrtSetBreakAlloc(4)とかやってみる
>>963 _CrtSetBreakAlloc
呼び出し履歴
>>959 おおむね同意。
置換だけならXP以降のメモ帳でもできるしね。
補足として、再インデント可能なエディタは割と多いですよ。
元がトラップ気味なインデントであることを考慮すると再インデントして
読むようにしてます。
if (hoge)
A;
B;
みたいなね;-)
全角空白インデントよりは、インデントなしのほうがいい。 とりあえずそのままコンパイルできるから。 逆に言えば、VC++とかGCCが全角空白を受け付けてくれるようになれば、 全角空白でも別にいいと、俺は思う。
>>968 makefile を使うのはどうだろう?
俺は空白は に置換してるんだけどこれで困る人いる? コピペったときにU+0160になってしまうようだと困るのかなと 思うのだけれど
971 :
963 :2008/06/15(日) 00:42:03
>>965-966 無事場所が分かりました!
mapのinsertの中でメモリリークが起きていました。
ただ、mapには120個くらいデータを挿入しているんですが、
メモリリークが起きるタイミングがまちまちで、メモリリークの合計が3回ということもあり、今一原因が分かりません。
オーバーフローが起きていると考えていいのでしょうか?
mapはmap<wstring, list<wstring> >で宣言してあります。
>>970 わざわざそうするならうpすればいいのに。
検索エンジンに引っかかるように、あえてスレにソースを載せたいのかな?
974 :
tst :2008/06/15(日) 01:21:27
none
1tab
;2tab
>>974 専ブラのレス参照では参照されなかったりする
>>973 2chに貼り付けるのは、数行のコードだからねぇ
「わざわざ」ってのは、意味が分からないな
それこそ、「わざわざ」手で置換するわけがないでしょ?
プログラマ板の住人ならさ
一番の問題はコピペ時にスペースにならんところか
 [ ] NBSP(U+A0)つかわないでも、普通のSPでいいでしょ。
言われてみればそうだな、今後はそうしよう
おっぱい おっぱい おっぱい
インデントを全角空白に置き換えるってどうやんの?
置換すらできないのか
いや、置換はできるけど、行頭の空白orタブを相当数の全角空白に置換ってどうやればいいのかなって。
ああ、深く考えなくてもTABを全角空白に変えてるのか。 開発対象によってはスペースでインデントすることもあるから妙に気にしてしまった。
s/\t| {4}/ /; とかでいいんでねえの。 インデント以外でスペース4個以上の連続なんてそうそう出てこないだろ。
>>971 newしてるような箇所は無いのか?
mapにwstringにlistだと問題なさそうだけど
>>986 ふぅむ。
タブインデントを空白インデントにするだけならvimで
:set et
ggVG=
ってやってる。
>>987 で、その後で空白を全部エンティティ参照に置換するとレス長が無駄に長くなるので、
置換をなるべく押さえた上で一発で仕事が済むようにプログラムを書いたわけですよ
まあ馬鹿げてるとは思うが
単純に、"SPSP"の連続を" SP"に置換すればいいだけなんじゃ。
>>989 行頭だけは特別扱いする必要あるけど、
1) タブを開く
2) 行頭のSPを に置換
3) SPSPを SPに置換
でいいのかな
ああ、奇数タブならそういう必要も出てくるんかな。よくわからんけど。
>>991 いや、行頭に空白一文字だけあるときに潰れてしまうことだけが問題
書いてから気づいたが、2)と3)は逆順のほうがいいな
タブを SPあるいはその繰り返しの並びに直接置換したらダメなの? もちろん、必要に応じて空白から SPの並びへの置換もやるとして。
>>993 タブ位置が行頭以外の場合、いくつの空白に置換すべきかが自明ではないでしょ。
だから、「きちんと」タブを開いてから空白だけを処理したほうが楽だと思う。
Unixのexpandコマンドは、バイト数=文字幅が成り立たない環境では
役に立たないものがほとんどだと思うけれど。
そういうことかすまん。 自分が行頭インデントにしかタブを使わないんで、 常にタブ1つを機械的に置換できると思い込んでいた。
コメントが不揃いになってもまあいいよ。 コメントとコードの両方が不揃いなのに比べれば。
いってくる
うめ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。