【初心者歓迎】C/C++室 Ver.35【環境依存OK】at TECH
【初心者歓迎】C/C++室 Ver.35【環境依存OK】 - 暇つぶし2ch28:デフォルトの名無しさん
07/02/20 23:26:06
>26
グローバル変数をやめればおk。

29:デフォルトの名無しさん
07/02/20 23:32:25
>>27
MSXML

30:デフォルトの名無しさん
07/02/20 23:32:55
>>28
そんな Σ(´Д`lll)

31:デフォルトの名無しさん
07/02/20 23:36:17
>>26
グローバル変数をやめて、今までグローバル変数にしていたものを管理するクラスを作ればいい。
#つーか、設計しなおせよ。

32:デフォルトの名無しさん
07/02/20 23:47:24
>30
全部パラメータ渡しに変える。可能な限りconstつきで。
これで今まで気がつかなかったバグも見つかって一石二鳥。

33:デフォルトの名無しさん
07/02/20 23:49:48
よーしぱぱシングルトンクラス1つ作って全部つめこんじゃうぞー

34:デフォルトの名無しさん
07/02/20 23:50:23
グローバル変数どこで使う?みたいなグダグダ進行してるスレ探してみたがないな

35:26
07/02/21 00:01:23
>>31-32
なるほどー…
クラスってこういう使い方もするんですね…

しかし、一つしかないグローバル変数扱うのに
わざわざクラス作って宣言し、pc->a(data)とかやるのは非効率な気がしてならないのですが、
そこら辺教えていただけませんか?

36:デフォルトの名無しさん
07/02/21 00:07:47
実行時の効率という意味なら、そこがボトルネックになることは100%ない(言い切ってみる
コーディングのしやすさや後々のわかりやすさという意味なら、ぐろーばるはしねばいいのに

37:デフォルトの名無しさん
07/02/21 00:21:08
>>29
それがめんどくさい。
スペースをどうするかとか同期か非同期か指定して
BSTRとかvariantとかL"~"とか、
HRESULT hr =~
if(FAILD(hr)~

もっと、楽に設定ファイルの読み書きが出来たらなあ。

GetPrivateProfileは、キーがなかったらデフォルト値を返す
みたいな便利なのがある。

てか、便利なものってC/C++標準装備になんねーかな。

38:デフォルトの名無しさん
07/02/21 00:30:17
>>35
時間ないし、複雑じゃないし、いっそグローバル変数にしたほうが楽なら
グローバル変数でいいと思うのが俺。
悩んで時間かけて改造したけどたいしたことないなら効率悪いじゃん。

でも、そうでないなら、グローバル変数やめたほうがいい。

引数減らす程度でどれくらい速くなると思う?
俺は調べたことないけどさ
メモリアクセスがわりとキャッシュにヒットしたと考えれば
よほど大量に実行しないと測定できないんじゃないの。
アセンブラでスタック積み込みに数命令、
読み込みはグローバルでもスタック積み込みでもたいして命令数かわらんだろ。

39:デフォルトの名無しさん
07/02/21 00:35:25
>>26
externつけてない宣言でも外部から参照可能だよ。
externつけた宣言しておきながら定義してもOKだよ。
それともCとC++でちがったっけ?
ちゃんと確認していないので間違えてたらすみません。
グローバル変数はあまり使わないものでして。

40:デフォルトの名無しさん
07/02/21 01:49:00
externをちゃんとわかってないヤツがいるな

41:デフォルトの名無しさん
07/02/21 09:35:38
externって「どっかにあるから探せよコラwwww」っていう感じくらいしかわかってない

42:デフォルトの名無しさん
07/02/21 09:45:48
extern 無しは「ここにおいとくから使えよコラwww」

ヘッダー内で extern 無しを書いて、あちこちでインクルードされると、
じゃどれつかうんだよコラ!!! とリンカが怒る

43:デフォルトの名無しさん
07/02/21 10:06:32
なるへそ

44:デフォルトの名無しさん
07/02/21 10:19:44
超訳/超解説の類って集めると楽しそうだ。役には立たなさそうだが。

45:デフォルトの名無しさん
07/02/21 10:40:48
D&Eによれば、Stroustrupはグローバル変数肯定派だよ
Simula使った後にC with classを開発する際にその必要性を
痛感していたようだ

C++ならてきとーにnamespaceにくるんどけば、別に困らんと思うよ

46:デフォルトの名無しさん
07/02/21 10:53:43
まず、宣言と定義を理解しているかを各自再確認するように。

47:デフォルトの名無しさん
07/02/21 12:22:01
本物のプログラマはヘッダを書かない。
よって本物のプログラマはグローバル変数を使わない

48:デフォルトの名無しさん
07/02/21 12:26:19
へえ

49:デフォルトの名無しさん
07/02/21 13:47:07
>>37
#import使えば戻り値のHRESULTの値がエラーのとき勝手に例外に変えてくれるから、
それに関しては毎回FAILDなんかで調べる必要はなくせるぞ。

50:デフォルトの名無しさん
07/02/21 15:17:14
>>47
偽者発見

51:デフォルトの名無しさん
07/02/21 17:33:39
C++ で exit 関数とか abort 関数を使ってもいいの?

52:デフォルトの名無しさん
07/02/21 17:41:53
exitを呼ぶと、関数呼び出しだから自動変数のデストラクタは呼ばれない。
グローバル変数など静的記憶期間にあるオブジェクトはデストラクタで解体される。
abortはそれすらも保障がない。

それを踏まえた上で呼ぶのなら誰も止める者はいない。

53:デフォルトの名無しさん
07/02/21 17:42:22
>>51
デストラクタがすっ飛ばされちゃうんだっけ?

54:デフォルトの名無しさん
07/02/21 17:46:50
exit と同じことをやろうと思ったら、
例外をスローして main でキャッチして return しかないのか。。。

55:デフォルトの名無しさん
07/02/21 18:28:37
>>54
簡単に実装できるからいいんじゃね?

でも catch(...) とかあるから確実に exit することができないって問題があるか。
まぁ、これは利点でもあるわけだが。

56:デフォルトの名無しさん
07/02/21 18:33:57
全部オブジェクトのポインタをグローバルに保っておいて適当な関数で解放させるようにしてその関数をatexitで登録したらいいんじゃないかな?

57:デフォルトの名無しさん
07/02/21 18:37:38
単純にcatch(...)で捕まえたらmainへ向けてさらにthrowすれば良いのでは?

58:デフォルトの名無しさん
07/02/21 18:47:56
だめだめ

59:デフォルトの名無しさん
07/02/21 18:51:23
>>57
それは自分ですべてのコントロールが可能であることが前提だし、
catch(...)じゃなにを捕まえたのかわからんから再throwすべきものなのか
再throwしちゃいけないものなのかの判断ができんし。

60:デフォルトの名無しさん
07/02/21 21:40:16
>59
よく分からない例外を握りつぶすなよ。
処理できる例外なら...で捕まえるなよ。

61:デフォルトの名無しさん
07/02/22 02:02:00
struct OBJECT
{
  FLOAT fHigh;
};
のとき、fHighを初期化するには、何か特別なことをしなければいけないのでしょうか?

62:デフォルトの名無しさん
07/02/22 02:24:16
>>61
コンストラクタで初期化すれば?

63:デフォルトの名無しさん
07/02/22 02:58:25
>>61 ふつうに初期化すればいいよ。

64:デフォルトの名無しさん
07/02/22 02:59:14
>>61
struct OBJECT a={12.345};

65:デフォルトの名無しさん
07/02/22 06:44:45
そもそもFLOATってどんな型だよ。

66:デフォルトの名無しさん
07/02/22 09:43:15
>>62を検索したところ、まさにそれでした!!ありがとうございました。

67:デフォルトの名無しさん
07/02/22 19:55:42
C++でscanf()のいい代替物って無いんですかね

68:デフォルトの名無しさん
07/02/22 20:07:15
#include <cstdio>
std::scanf()

69:デフォルトの名無しさん
07/02/22 20:11:32
>>68
型安全性が無いのと、文字列読み込みで長さを無制限にできない点がちょっと。
素直にstd::stringに読み込みたいのですが。

70:デフォルトの名無しさん
07/02/22 20:14:34
>>67
std::basic_istream<_Elem,_Traits> operator>>(なんとか)

71:デフォルトの名無しさん
07/02/22 20:15:14
>>70
それって、%[a-z]とか%[^,]みたいなことができますか?


72:デフォルトの名無しさん
07/02/22 20:20:25
boost::format

73:デフォルトの名無しさん
07/02/22 20:21:12
boost::spirit

74:デフォルトの名無しさん
07/02/22 20:23:11
>>72
boost::formatがサポートしているのは出力だけだと思っていました。
入力もサポートしていたのですね。

75:デフォルトの名無しさん
07/02/22 20:24:14
>>73
それはscanf()の代わりにlex & yaccを使え、と言っているようなもので、
適切な代替物というよりはオーバースペックに思えます。
無論、もともとlexが適切なケースではlexを使えばよいでしょう。

76:デフォルトの名無しさん
07/02/22 20:27:14
少なくとも俺がBoostを使い始めてからの3年間では
入力でboost::formatが使えるなんて与太話は聞かない。

つ boost::Xpressive

77:デフォルトの名無しさん
07/02/22 20:28:45
readlineしてregexp。

78:デフォルトの名無しさん
07/02/22 20:33:38
>>76
初めて知りました。boost::regexの次期バージョンなのでしょうか。
>>77
regexpだと、その後さらに型変換が必要ですよね。文字列からの。
scanf()より余程複雑な字句解析を行うことができますが、
記述性と簡便性においては、かなり劣るといわざるを得ないのではないでしょうか。

79:デフォルトの名無しさん
07/02/22 20:37:49
なんだか要求が微妙すぎるな。
自作するしかないのでは。

80:デフォルトの名無しさん
07/02/22 20:44:27
googleがPCREに寄贈したラッパーコード(pcrecpp)では、

int n;
string s;
pcrecpp:RE re("(\\w+)=(\\d+)");
re.FullMatch("ruby=1234", &s, &n);
のようなことが出来るようですね。

これぐらいだとかなりいい感じです。

81:デフォルトの名無しさん
07/02/23 11:36:38
仮想関数についての質問です
派生クラスで再定義するメンバ関数以外に仮想関数にする意味はありますか?

82:デフォルトの名無しさん
07/02/23 11:45:35
>>81
あんまり無い。
仮想関数の意味を理解していれば自明だと思うが。

ただしデストラクタとか暗黙のうちに再定義されるものも
あるので、知らないと良く分からない場合もあるかも。
あとは RTTI を有効にするためだけのダミーとか。

83:デフォルトの名無しさん
07/02/23 17:58:49
整数型のメンバ配列変数の便利な初期化方法を教えてください

84:デフォルトの名無しさん
07/02/23 18:05:45
>>83
つ[std::vector]

85:デフォルトの名無しさん
07/02/23 18:08:07
普通の配列の初期化は無理ですか?

86:デフォルトの名無しさん
07/02/23 18:12:33
コンストラクタで memset すればいいのでは。

87:デフォルトの名無しさん
07/02/23 18:25:57
memsetでやります

88:デフォルトの名無しさん
07/02/23 18:39:05
memset()なんて濫りに使うもんじゃない。
せめてstd::fill()を使え。

89:デフォルトの名無しさん
07/02/23 18:41:54
そのほうがよかろう

90:デフォルトの名無しさん
07/02/23 19:41:21
カラフルなテキストを表示したいんですけど
SetTextColor+DrawTextだと限度を感じました。(頑張っても行単位がいいところ)
黒黒赤赤黒黒
黒黒青青赤青
こんな風に描写するのに適した関数教えてください。

91:デフォルトの名無しさん
07/02/23 19:42:59
>>90
スレ違い

Win32API質問箱 Build50
スレリンク(tech板)

92:デフォルトの名無しさん
07/02/23 19:53:32
>>90
一文字ずつ色設定して一文字ずつ書き込む
どうかんがえても、これしかないでしょう
どの環境でも

93:デフォルトの名無しさん
07/02/23 19:59:59
VisualStudio 2002環境で確認したのですが
stringstream::operator <<()を使用すると
プロセス終了まで開放されないメモリプールが発生しているようなのですが
対応方法をご存知の方いらっしゃいませんか?

スレッドを作っては消すを繰り返すプログラムで
生成したスレッド内でoperator<<()を使用すると使用メモリが増加するのですが
インスタンス・スレッドハンドルの開放を行ってもメモリが減りません
(インスタンスを生成しただけでは問題ないようです)

CreateThread()ではCライブラリでメモリリークが発生するとの記述もありますが
スレッドを_beginthreadex()で生成しても発生していて困っています

94:90
07/02/23 20:08:37
>>91
スマン去ります。

>>92
文字列中のタグ解析して色自動でつけてくれるよな物が関数化されてるかと思って

95:デフォルトの名無しさん
07/02/23 21:12:58
>>90
Win32APIスレ行け
んでもってリッチテキストでも使ってろ

96:デフォルトの名無しさん
07/02/24 00:15:58
>>93
それは繰り返しただけメモリ使用量が増加していくの?
プールがちゃんと再利用されてれば問題ないようにも思うんだけど。

97:デフォルトの名無しさん
07/02/24 11:50:18
質問です。
配列を使い、その値の合計値を出す際に私はループカウンタを利用して足す手法を
思いつくのですが、それ以外の方法があると聞きました。
ですが、それ以外の方法が思いつかなく質問させてください。

int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int nSum = 0;

for ( int i = 0; i < 10; i++ )
{
nSum += a[i];
}

return nSum;

ここでループカウンタを使用せず、配列の全てを足すにはどうしたら良いでしょうか。

98:デフォルトの名無しさん
07/02/24 11:57:24
>>97 素直が一番
こんなのじゃなくて
int nsum(int data[], int data_num){
if(data_num<=0) return 0;
return data[data_num-1]+nsum(data, data_num-1);
}

int nsum(int data[], int data_num){
int *p, sum=0;
for(p=&data[0];p!=&data[data_num];p++)
sum+=*p;
return sum;
}

99:デフォルトの名無しさん
07/02/24 11:59:22
>>97
std::accumulate()

100:デフォルトの名無しさん
07/02/24 12:05:12
回答者にも遠慮なく突っ込みを入れよう。

引き数がポインタなので、&data[0]する意味がない。p = dataで充分。
そもそも、ポインタを回す必要はない。ポインタ演算はバグの温床として禁止するコーディング規約もあるくらいだ。
したがって、

int nsum(int data[], int data_num){
// if (data_num < 0 || data == NULL) return 0; // 状況によっては神経質にここまでやるべき。
int sum = 0;
for (int ic = 0; ic < data_num; ++ic) {
sum += data[ic];
}
return sum;
}
の方が自然だろう。

101:デフォルトの名無しさん
07/02/24 12:12:07
>>100
>引き数がポインタなので、&data[0]する意味がない。p = dataで充分。
終了条件と書き方を合わせたほうがいいと判断した

>そもそも、ポインタを回す必要はない。
*ループカウンタを使用せずに*

ついでいうと >>98 の書き方を推奨してはいない

102:デフォルトの名無しさん
07/02/24 12:14:39
std::accumulate( &data[0], &data[num], 0 )

103:デフォルトの名無しさん
07/02/24 14:12:19
>>101
ちょっと>>98を改造して末尾再帰になるようにしたぞ。
これなら文句あるまい。

#include <stdio.h>

int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

int nsum(int data[], int data_num, int acc){
return data_num<=0?acc:nsum(&data[1], data_num-1, *data+acc);
}

int main(void) {
printf("%d\n", nsum(a, 10, 0));
return 0;
}


104:デフォルトの名無しさん
07/02/24 16:37:53
WinAPIの関数で、DWORD型で(コールバック)関数のアドレスを渡す ものがあるのですが、
これに自作のクラスのメンバ関数のアドレスを渡すと、DWORDに変換できないと言われ、コンパイルできません。
そのメンバ関数がstaticなら、コンパイルに成功するので、
「メンバ関数は、普通の関数とは構造が異なる」という理由だと思うのですが・・・
メンバ関数のアドレスを渡すことは不可能ですか?

105:デフォルトの名無しさん
07/02/24 16:43:43
>>104
非staticなメンバ関数≒インスタンス情報をパラメータに取るstaticなメンバ関数 なので、
そのままでは渡せません。素直にstaticなメンバ関数を渡せば宜しいのでは?

106:デフォルトの名無しさん
07/02/24 16:47:55
ここでエスパー
ウィンドウクラスを作ろうとしているなら、

つ [SetProp]

107:デフォルトの名無しさん
07/02/24 17:11:31
>>104
その「コールバック関数を引数に取る関数」に、
コールバック関数に渡す値という引数はないか?

ところでWindows APIのコールバック関数のアドレスを引数に取るのだったら、
DWORD型ではなく何か関数へのポインタ型になっていると思うのだが、
一体何の関数だ?

108:デフォルトの名無しさん
07/02/24 17:13:24
初心者です
if文の中で処理をしてから判断できるんですか?
if(a=5,a==5)みたいな感じ

109:デフォルトの名無しさん
07/02/24 17:16:39
こんな感じのこと?

int moji;
while((moji=getchar())!=EOF)
putchar(moji);

典型的なパターンの時以外はやめたほうがいいよ

110:デフォルトの名無しさん
07/02/24 17:21:20
評価式と別の普通の式をif文の中で分けて使いたいんですが

111:デフォルトの名無しさん
07/02/24 17:22:13
やめておいたほうがいい

112:デフォルトの名無しさん
07/02/24 17:26:56
>>108
>108の例だと、素直に a = 5; if (a == 5) ...; と書いた方がいい。
醜くなるだけでメリットは殆どない。

113:デフォルトの名無しさん
07/02/24 17:34:40
では例えば

if(関数式==1)
else if(関数式==1)
else if(関数式==1)
else if(返り値=関数==1)
のときの

else if(返り値=関数)の関数にかかる時間を計りたいとき

関数の中で時間を計らないで関数の呼び出されてから終了までの
経過時間を計りたいときはどうすればいいですか?

その場合 if(整数A=clock(),評価式)
整数B=clock();
整数A-=整数Bでいけますか?

114:デフォルトの名無しさん
07/02/24 18:03:27
clockは経過時間ではなくCPU時間

115:デフォルトの名無しさん
07/02/24 18:05:28
デバッグ目的なら好きにすれば?

116:デフォルトの名無しさん
07/02/24 18:06:31
デバッグ目的ならプロファイラがいいと思うけど

117:デフォルトの名無しさん
07/02/24 18:07:24
そのあとの経過時間によって処理を分けるので^^;
なにか良い方法があれば教えてください

118:デフォルトの名無しさん
07/02/24 18:08:46
>>114
1000で割れば経過秒数になりますよね?

119:デフォルトの名無しさん
07/02/24 18:10:51
CLOCKS_PER_SEC で割る

120:デフォルトの名無しさん
07/02/24 18:11:17
なんか激しく無謀なことをしている悪寒。

121:デフォルトの名無しさん
07/02/24 18:16:02
ゲームでPCスペックが低い時にフレームスキップするみたいなことをしたい訳だな

122:デフォルトの名無しさん
07/02/24 18:38:30
>>113
if(返り値=関数==1)
こういうのって修正とかデバッグなどしにくいから俺としてはNG。

返り値=関数;
if(返り値==1)

最初からこうならデバッグとか修正とかしやすい。

確かに行数増えるけど
今の俺はそんなこと気にしなくなった。

経過時間は以下みたいに巣りゃいいんじゃナインお

st = 現在時間取得
返り値=関数
et = 現在時間取得
経過時間 = et - st

123:デフォルトの名無しさん
07/02/24 18:43:36
>>122
それ意味変わってね?
==のほうが優先順位高いよ。

124:デフォルトの名無しさん
07/02/24 18:43:38
>>122
>>113をよく嫁

125:デフォルトの名無しさん
07/02/24 18:46:43
>>113自体エスパーが必要だと思うんだが

126:デフォルトの名無しさん
07/02/24 18:47:50
122じゃないけど、自分も同じことやってたよorz


127:デフォルトの名無しさん
07/02/24 18:51:23
>>125
初心者なんですいません

やってみたらできたんで今はclock()を使ってます

128:デフォルトの名無しさん
07/02/24 20:30:32
>>96
1スレッドごとにプールを製作するようです
したがって、同一スレッド内では再利用されるので問題ないのですが
スレッドを閉じて新しいスレッドを生成すると
新しいプールが作成されて、古いプールが残るようなのです

このプールがいつまでも残っているようで困っております

遅レスでもうしわけないです

129:デフォルトの名無しさん
07/02/24 20:32:31
CRTはソースあるんだから嫁よ。

130:デフォルトの名無しさん
07/02/24 20:57:20
>>128
「~ようです」って、何見て言ってるんだ?

131:デフォルトの名無しさん
07/02/24 21:04:07
>>128
「~ようです」って、何見て言ってるんだ?

132:デフォルトの名無しさん
07/02/24 21:12:55
>>128
「~ようです」って、何見て言ってるんだ?

133:デフォルトの名無しさん
07/02/24 21:17:32
何度言えば気が済むんだ?

134:デフォルトの名無しさん
07/02/24 21:18:15
malloc()/newの類はfree()/deleteしても一般にはOSにメモリを返さないという
超基本的事項を知っているか。
free()されたメモリはOSに返さず次のmalloc()で再利用するのがこうした
関数の基本的な戦略だ。

したがって、一般にプロセスの最初にガバッとmalloc()して大きな仕事をし、
その後free()してもプロセスのワーキングセットは大きいままだ。
これは俗に言う「メモリリーク」ではないのだが、
それが問題になるようであれば、自分でHeapAlloc()なりVirtualAlloc()なりを
用いてカスタムのアロケータを書いて、basic_stringstream<>の
テンプレートパラメータとして渡してやるんだな。

135:デフォルトの名無しさん
07/02/24 22:15:30
>>134
ありがとうございます
やってみます

136:デフォルトの名無しさん
07/02/24 22:18:53
HeapAlloc/FreeだってOSに返さないで次のHeapAlloc呼出に再利用するぞ。
HeapDestroyでは流石にOSへ返すが。

137:デフォルトの名無しさん
07/02/24 22:35:45
Linux、UNIXあるいはMacで、OSの名称やバージョン情報を取得するにはどの関数を使えば良いですか?
例えば、FreeBSD 6.0、Vine Linux 4.0などです。
WindowsはGetVersionExなどで出来ました。

138:デフォルトの名無しさん
07/02/24 22:38:59
man 3 uname

139:デフォルトの名無しさん
07/02/24 23:02:10
OSはlinuxです。C/C++勉強してます。
ディレクトリの中のファイルの日付を取得したいのですが、
opendirとreaddir関数使いました。
struct dirent {
ino_t d_ino; /* "inode number" of entry */
off_t d_off; /* offset of disk directory entry */
unsigned short d_reclen; /* length of this record */
char d_name[1]; /* name of file */
};
この中に日付無いのですが、どうしたらよろしいでしょうか。
よろしくお願いします。

140:デフォルトの名無しさん
07/02/24 23:12:23
>>139
つ[stat()]

141:デフォルトの名無しさん
07/02/24 23:37:57
>>140
レスありがとうございます。
d_nameを元にファイルのpath指定して、
stat()実行して、struct statを取得する感じですか。
なんか大変な感じします。(汗

142:デフォルトの名無しさん
07/02/24 23:55:57
>>141
つ[popen("/bin/ls -l", "r")]

143:デフォルトの名無しさん
07/02/25 00:48:23
unsignedはどういう場合に使うべきなんでしょうか?
例えばループのカンターなんかは符号付きを使用すると思いますが、
実際の所は符号なしの方が意味的にはあっていると思います。
ビットシフトしたいとき、くらいしか思いつかないんですが、他にどんな使い道がありますか。

144:デフォルトの名無しさん
07/02/25 01:07:48
>>143
typedef unsigned char BYTE;
size_tもunsignedだな
ループカウンタとかunsigned付けるの面倒だよね。
size_tがunsignedだからもっと使っているはずだけど面倒。
負にならないもの全てunsignedとか面倒だからやらないんじゃない。
unsigned intならファイルサイズとか4Gまで表現できるけど面倒だからintで計算。
2GB以上はこのプログラム動きません。
たとえlong longとかあっても面倒だからunsigned long longでファイルサイズを表そうとも思わない。
俺の場合はね。

145:デフォルトの名無しさん
07/02/25 01:36:52
>>142
レスありがとうございます。

FILE *p;
p = popen("/bin/ls -l", "r");
ネットで検索したところ、
こういう使い方すると、出力をファイルのように
扱うことが出来るみたいですね。
一行ずつ読み込んで、スペースで区切ると日付も取得できそうです。
コマンド実行->標準出力取得 って、やり方知らなかったので
大変勉強になりました。
でも、時間の型を考えるとやっぱり、今回は、stat()関数使用してみます。
ありがとうございました。

146:デフォルトの名無しさん
07/02/25 17:45:57
質問です。
CのソースからC++のソースを呼び出したいのです。

具体的には、
既にかなりの規模になってしまった拡張子.cのプログラムソースがありまして、
どうしても欲しい機能がC++で書かれているので、インクルードしたんですが、当然Cのソースからそれらを読むとコンパイルエラーになってしまいました。

hoge.cppと言うファイルにC++関連のプログラムを書き、何とかその関数をc側から読み出したいのですが
インクルードすると、エラーが出ますし、どのようにすれば良いのでしょうか?

尚環境はVC++.NET 2003です。

よろしくお願いします。


147:デフォルトの名無しさん
07/02/25 17:55:14
EXTERN_C

148:デフォルトの名無しさん
07/02/25 17:58:33
>>147
レスありがとうございます。
extern "C"
をつけた関数の中から、C++固有の機能(クラスなど)へのアクセスが出来ないのですが…
具体的には、error LNK2019: 未解決の外部シンボル とエラーが出ます。


149:デフォルトの名無しさん
07/02/25 18:00:08
ヘルプ

150:デフォルトの名無しさん
07/02/25 18:02:01
ユーザーが入力した日時 (日付と時刻) を
設定ファイルに記録しておこうと思うのですが、
どういう形式で記録するのが一般的ですか?
asctime 関数のような 「Sun Feb 03 11:38:58 2002」 のような形式は
気持ち悪いので採用したくないです。

151:デフォルトの名無しさん
07/02/25 18:02:58
>>148
そりゃC言語にない機能だからクラスを扱えないよ。
C++の方で呼べるようにしてあげないと。

152:デフォルトの名無しさん
07/02/25 18:06:46
>>151
間違えたかも。

>>148
C++の方では
Cから呼べるようにクラスじゃない関数でextern "C"を付けて作る。


Cの方では
extern "C"を付けた宣言をする。
これで呼び出せると思うけど忘れた。


153:デフォルトの名無しさん
07/02/25 18:11:24
>>151
確認したいのですが、extern "C"をつけるのはC++側の関数へですよね?
main.c
#include "hogehoge.h"
int main(void){
int a=0;
func(a);
return 0;
}
hogehoge.cpp
#include <vector.h>
extern "C" void func(int a){
vector<int> v;
}
hogehoge.h
#ifdef __cplusplus
extern "C" {
#endif
void func(int a);
#ifdef __cplusplus
}
#endif

こういう形なんですが・・・。

154:デフォルトの名無しさん
07/02/25 18:18:52
>>150
設定ファイルを直接見る必要が無いなら
timeで拾った値をバイナリで書き込めばいいんじゃないかな。

155:デフォルトの名無しさん
07/02/25 18:20:35
設定ファイルはテキストファイルと決まってしまっているんです。
見ることはあまりないですけど、たまに見ることもあるものです。

156:デフォルトの名無しさん
07/02/25 18:25:04
>>150
W3C-DTF

157:デフォルトの名無しさん
07/02/25 18:30:34
>150
rfc 3339

158:デフォルトの名無しさん
07/02/25 18:33:33
>>153
これで動くんじゃないの?

159:デフォルトの名無しさん
07/02/25 18:38:48
おいらのところではコンパイル・リンクできたけど?

160:デフォルトの名無しさん
07/02/25 18:51:23
>>155
time_tの整数値
yyyymmddhhmmss形式
y/m/d h:m:s形式
好きにしな。

161:デフォルトの名無しさん
07/02/25 19:00:51
>>150
どういう形式にするにしても、strftime関数が使えると思う。

162:デフォルトの名無しさん
07/02/25 19:12:08
>>150
一般的といいつつも日本人向けにしたいっていうことだよね。

163:デフォルトの名無しさん
07/02/25 20:11:34
W3C とか RFC の形式を採用してみます。
情報ありがとうございます。

164:デフォルトの名無しさん
07/02/25 21:51:02
フォルダ内の全ファイルを列挙するプログラムを教えて下さい

165:デフォルトの名無しさん
07/02/25 21:53:35
system("dir");

166:164
07/02/25 22:04:00
printfで表示するには?

167:デフォルトの名無しさん
07/02/25 22:06:14
そういえば昔、
system("dir > hoge.txt")して、fopen("hoge.txt","r")...みたいなことを
やってた連中が居た。

168:デフォルトの名無しさん
07/02/25 22:11:16
>>164
環境依存

>質問者は必ず、環境を書きましょう。

169:デフォルトの名無しさん
07/02/25 22:13:08
>>167
十分アリだと思う dir /b ほうがイイと思うが

170:デフォルトの名無しさん
07/02/25 22:15:15
popenの事たまには思い出してあげてください

171:164
07/02/25 22:16:58
VisualC/C++
WindowsXP
フォルダ内のファイル名をstd::stringの配列に格納したいのです

172:デフォルトの名無しさん
07/02/25 22:32:34
>>171
FindFirstFile
FindNextFile

あたりでどうかな

173:デフォルトの名無しさん
07/02/25 22:56:24
イベント オブジェクトが現在シグナル状態にあるかどうかを調べるには、
どうしたらいい? WaitForSingleObject を使うの?

174:デフォルトの名無しさん
07/02/25 23:03:35
そう、待機時間を0にすればいいと思う。

175:デフォルトの名無しさん
07/02/25 23:08:32
そうか、ありがと。

176:デフォルトの名無しさん
07/02/25 23:11:26
>>172
使い方がわかりません

177:デフォルトの名無しさん
07/02/25 23:20:03
>>176
#include<windows.h>
#include<stdio.h>
int func1(void){
    HANDLE    h_find;
    WIN32_FIND_DATA    file_info;
    printf("\n----- func1 -----\n");
    h_find=FindFirstFile("*", &file_info);
    if(h_find==NULL) return 0;
    do{
        printf("%s\n", file_info.cFileName);
    }while(FindNextFile(h_find, &file_info)==TRUE);
    FindClose(h_find);
    return 1;
}
int func2(void){
    FILE    *fp;
    char    filename[FILENAME_MAX];
    printf("\n----- func2 -----\n");
    fp=popen("dir /b", "r");
    if(fp==NULL) return 0;
    while(fgets(filename, sizeof(filename), fp)!=NULL)
        printf("%s", filename);
    fclose(fp);
    return 1;
}
int main(void){
    func1();
    func2();
    return 0;
}

178:デフォルトの名無しさん
07/02/25 23:21:25
基本的なことで申し訳ないのですが、
クラスのオブジェクトの配列を作るとき、
そのクラスに引数を持つコンストラクタを持たせることは出来ないのですか?

一つ一つコンストラクタ引数を指定する形でも良いので、配列化させたいのですが…
一つ一つ宣言した上でポインタの配列を作った方が手っ取り早いですか?

179:デフォルトの名無しさん
07/02/25 23:33:21
諦めてvectorに収納したら?

180:デフォルトの名無しさん
07/02/25 23:38:28
>>178
引数を持つコンストラクタを持たせることは可能だが、
クラスの配列の初期化時にはデフォルトコンストラクタが呼ばれるので
デフォルトコンストラクタが必須。

どーしてもデフォルトコンストラクタを持たせたくないのなら、
(スマート)ポインタの配列にするしかないな。

181:デフォルトの名無しさん
07/02/25 23:40:35
配置newとかを使ってやる方法は無くもないが、最後の手段。
現在のC++ではどうしようもないから179-180の言うとおりにするしかない。

182:デフォルトの名無しさん
07/02/26 00:07:26
>>179
vectorに収納…というのは、どのような使い方ですか?

vector<MyClass> c1(10);
のような使い方だとデフォルトコンストラクタしか呼べませんよね?

183:デフォルトの名無しさん
07/02/26 00:09:25
reserveしてからpush_back!push_back!push_back!

184:デフォルトの名無しさん
07/02/26 00:19:57
>>177
ありがとう

フォルダとかディレクトリまで表示されるけどファイルだけに
するにはどうするの?

185:デフォルトの名無しさん
07/02/26 00:22:20
>>184
1. それぞれのファイル属性を調べる
2. dir のオプションを調べる

186:デフォルトの名無しさん
07/02/26 00:22:41
>>184
少しは自分で調べろ。

187:デフォルトの名無しさん
07/02/26 12:34:03
彼にとって調べるとは人に聞くことだけなのさ

188:デフォルトの名無しさん
07/02/26 12:52:25
Win32って無くなるの?

189:デフォルトの名無しさん
07/02/26 13:19:14
たとえば Windows のファイル ハンドルをカプセル化したような
クラスを作った場合、

class File {
private:
    HANDLE  m_handle;
public:
    .....
    HANDLE GetHandle(void) { reeturn m_handle; }
    operator HANDLE(void)  { return m_handle; }
};

この GetHandle や operator HANDLE は const 関数にすべき?

190:デフォルトの名無しさん
07/02/26 13:26:32
微妙だな。
MFCのCWndや、ATL::CWindowではconst付けているけど。

191:デフォルトの名無しさん
07/02/26 19:36:57
とあるツールのソースがあるんですが、拡張子が.vcprojというファイルがあることから
Visual C++ で作られたと言うことが想像できるんですが、具体的にVisual C++ のどのバージョン
で作られているのかを知るためにはどうやって調べたらいいのでしょうか?僕の持っているVisual C++
ではコンパイルに失敗して困ってます。

192:デフォルトの名無しさん
07/02/26 19:41:06
.vcprojファイルをテキストエディタで開くと
VC++のバージョンが書いてあります

193:デフォルトの名無しさん
07/02/26 19:46:26
>>192
だっは~すいません、ありがとうございます!

194:デフォルトの名無しさん
07/02/26 20:51:36
たびたびすみません。。
>ProjectType="Visual C++"
>Version="7.10"
とあったのですが、これは .NETになるんですかね?
Visual Studioの .NETを使うべきですかね、それともVisual Studio2005でしょうか

195:デフォルトの名無しさん
07/02/26 20:56:03
>>194
7.0は2002
7.1は2003
8.0は2005



196:デフォルトの名無しさん
07/02/26 20:57:33
>>195
どもです!!

197:デフォルトの名無しさん
07/02/26 21:04:54
>>194
2003を使うのが手っ取り早いですが、2005でも問題ないと思います。

198:デフォルトの名無しさん
07/02/26 22:13:12
VC++ で質問です。

class A
{...}

class B: public A
{...}

class C
{
B* b;
vector <A> a;
}

こんな感じのクラスを作成してて
C::a のうちの一つの参照から C::b へポインタをコピーした場合
C::b を B* として適切に扱えるのでしょうか?

199:デフォルトの名無しさん
07/02/26 22:16:23
B *b = &a[0]みたいなことなら、出来ないと思うが。
追加したメンバ変数・仮想関数がないというような
限定条件を付ければ、reinterpret_castしても動くだろうけどさ。

200:198
07/02/26 22:28:22
ありがとうございます。
上でやりたいことを少し説明します。

まず A が基本フレームと呼ばれるセクタ単位のデータ構造を扱います。
B は基本フレームを拡張したフレームで基本的には仮想ではない関数郡です。
そして C はフレーム集合を保持するクラスです。
C では C::a のうち頻繁に利用するフレームを C::b として利用できたらいいのにと考えています。

今手元に開発環境がないのですが
適切に扱える C::b1 もあったりできない C::b2 があったりして悩んでいます。

ポインタを使わないでよい用法があればよいのですがありますでしょうか。

201:デフォルトの名無しさん
07/02/26 22:28:30
>>198
aをstd::vector<boost::shared_ptr<B> >型にでもしておけ。

202:デフォルトの名無しさん
07/02/26 23:02:25
URLリンク(douga.adult-55.com)

203:デフォルトの名無しさん
07/02/26 23:57:44
>>183
なるほど!
ありがとう!!

204:デフォルトの名無しさん
07/02/27 09:41:55
>>200
vector<A*>にしてBにキャストしたい要素はちゃんとBのインスタンスを格納しとけば普通にダウンキャストできると思うんだが
キャストしたくないというならクラス別に配列分けるか、クラスの設計見直すか

205:デフォルトの名無しさん
07/02/27 21:24:13
>>198
俺の想像だけどさ

某ライブラリで
struct Box { int x0,y0,x1,y1; }; が既にあるとする。

値の配列でライブラリから受け取ったり渡したりするから
Box型の配列のまま変えられない。

受け取ったり渡したりするだけならそのままでいいが
頻繁に使う要素は、やはり不便だ。

そこで
struct BoxEx : Box
{
    int GetWidht() { return x1-x0; }
};
みたいに便利なメソッドつきの無理やりキャストしたいって事か。

206:デフォルトの名無しさん
07/02/27 21:30:58
根本的ですが、

for(i = 0; i < 10; i++){
 if(i < 5) a();
 if(i < 7) b();
 if(i < 9) c();
 d();
}

と、

for(i = 0; i < 5; i++) a();
for(i = 0; i < 7; i++) b();
for(i = 0; i < 9; i++) c();
for(i = 0; i < 10; i++) d();

ではどっちが効率的ですか?

207:デフォルトの名無しさん
07/02/27 21:38:01
なんとなく前者の方が効率よさそうな気がするが、
パフォーマンスに関してはとにかく実測(して比較)しろ。それが鉄則だ。

208:デフォルトの名無しさん
07/02/27 21:46:02
そもそもabcdを呼び出す順番が違ってくるけど、それでいいのか。

209:デフォルトの名無しさん
07/02/27 21:47:13
たぶん後者のほうが効率いいと思うが
そんな効率気にする必要があるのか

「これじゃぁ効率悪いよなぁ」と余計なとこまで考えてプログラミングがなかなか進まないのは罠

210:デフォルトの名無しさん
07/02/27 22:02:03
ファイルの書き込みについて、なんですが
追加モードで開いて書き込むと、一番最後に追加されます。
”先頭に追加した文字列を作ってから書き込む以外”
先頭に追加する方法はあるでしょうか?
std::ofstream ofs( "hoge.txt", std::ios::app );

seekで先頭にファイルのポインタ先頭にしても
末尾に追加されるみたいなんです。
よろしくお願いします。

211:デフォルトの名無しさん
07/02/27 22:06:05
日本語の実装に難があるような気もするが、
要するに、ファイルの先頭行が最新の書き込みであってほしい、という話?

212:デフォルトの名無しさん
07/02/27 22:26:29
>>210
先頭に追加?OSレベルでもそういう機能をファイルシステムに
備えている物はないんじゃないか?

213:デフォルトの名無しさん
07/02/27 22:35:09
>>210
追加だから最後に追加されるのが正しいでしょ。
先頭に書いたら上書きじゃないのか。

それとも先頭に挿入?
メモリでもファイルでも挿入というのは、
それ以降の全てのデータをずらして書き込み場所を空けてから
書き込むのでちょっと大変なサギョウだ。

214:デフォルトの名無しさん
07/02/27 22:50:12
行の先頭4バイトを次(ファイルオフセットには前)の行へのオフセットと決めておいて、
ファイルの先頭だけ特別扱いすれば・・・誰かそんな変態FS作らないかな。

215:デフォルトの名無しさん
07/02/27 23:01:51
>>207-209
確かに…
実測すべきでした。ハイ。
済みませんでした。
やってみます。

216:デフォルトの名無しさん
07/02/27 23:15:00
>>212
>>213
はい。やりたいことは挿入です。
挿入みたいなモードは無いですか。
ログの保存を先頭に挿入して、逆の順番に保存してる
アプリがあったので、どうしてるのかと思いまして。

レスありがとうございました。

217:198
07/02/27 23:21:41
>>205
ありがとうございます。
でもちと違うのかな。

198 の
  vector <A> a;

  vector <A*> a;
として
  b = a.at (x);
とすることでやりたいことができました。

218:デフォルトの名無しさん
07/02/27 23:26:58
え?キャスト無かったら、こういうエラーにならない?

> error C2440: '初期化中' : 'A *' から 'B *' に変換できません。
> base から derived へのキャストには、dynamic_cast または static_cast が必要です。

219:デフォルトの名無しさん
07/02/27 23:29:45
>>216
そのログのフォーマットはどんなかんじでしょうか?
タグ(目印)みたいなものがついてないでしょうか?
ログのフォーマットがわかればそのアプリがどんな
実装してるかわかるかもしれんよ

220:デフォルトの名無しさん
07/02/28 08:10:06
配列の中身をランダムに入れ替えて別の配列に代入したいのですが、
被らず代入する方法を教えてください。お願いします。

221:デフォルトの名無しさん
07/02/28 08:21:50
>>220
手順
要素数を N とするとき
1. そっくりそのまま別の配列にコピーする
2. 配列の 1 番目の要素と x1 番目の要素を交換する (x1 は 1 から N までの一様乱数で求める)
3. 配列の 2 番目の要素と x2 番目の要素を交換する
...
配列の N 番目の要素と xN 番目の要素を交換する

222:デフォルトの名無しさん
07/02/28 08:22:47
そのままコピーした後、ランダムに並び替えるのが楽なんじゃないかな

223:デフォルトの名無しさん
07/02/28 08:29:55
>>221-222
ありがとうございます。
なるほど、入れ替えた回数が「ランダム」ということになりますね

224:デフォルトの名無しさん
07/02/28 08:33:56
>>223 違う

rand() の精度で良ければサンプルはこんな感じ
N 回の入れ替えで全体の順序がランダムになる

#include<stdio.h>
#include<stdlib.h>
#define N 10
void swap(int *a, int *b){
int c;
c=*a;
*a=*b;
*b=c;
}
int main(void){
int a[N], b[N];
int i;

for(i=0;i<N;i++) a[i]=i+1;
for(i=0;i<N;i++) b[i]=a[i];
for(i=0;i<N;i++) swap(&b[i], &b[rand()%N]);
for(i=0;i<N;i++) printf(" %d", b[i]);
printf("\n");
return 0;
}

225:デフォルトの名無しさん
07/02/28 16:53:00
剰余かよ

226:デフォルトの名無しさん
07/02/28 17:27:59
int b[1024];
に様々な+-含めた値が入ってて、そいつをfloat型として無理に渡した関数先で
+- 32768.0の範囲に収まるfloat型にきちんと直したいんですけど
具体的には
void func(float *b){
int o[1024];
for(int i=0; i<1024;i++){
o[i]=b[i]*(1.0 /32768.0);
}
}
int main(void){
func(b);
}
}
こんな感じにしたいんです。
func()の引数がfloatではなくintであれば、この計算で正常に変換出来るんですが
どうしてもfloatで渡す必要があって困っています。
func内でint型の変数を用意してコピーしてやると上手くいきますが、ループ内の計算式で何とかしたいのです。
どうすれば上手くいくのでしょうか?


227:デフォルトの名無しさん
07/02/28 19:58:37
すみません。間違えました。。。
void func(float *b){
float o[1024];
for(int i=0; i<1024;i++){
o[i]=b[i]*(1.0 /32768.0);
}
}

です。結果はfloatで出したいのです。

228:デフォルトの名無しさん
07/02/28 20:19:57
ようするにint to floatって事?

229:デフォルトの名無しさん
07/02/28 22:57:53
>>227
どうしたいのかよく和下欄のだが、
それだと、bの中身とoの中身が全然変わっちまうぞ。

230:デフォルトの名無しさん
07/02/28 23:07:59
すみません。
>>228のとおり、ようするに正しくfloatからintへ変換したいのです。

例えば
int f=-2
printf("%f\n",f);
これで正しく-2が表示出来るようにしたいのです。
この場合fに何か計算式をかければいけそうだとは思うんですが…。

231:デフォルトの名無しさん
07/02/28 23:10:12
浮動小数点数には表現できない数値のいうのがあってだな

232:デフォルトの名無しさん
07/02/28 23:15:17
>>230
その前の話を全て無視して、単にそのprintfの場合だったら、
可変個引数だからキャスト演算子を明示しろということになるが。
printf("%f\n", (float)f);

233:デフォルトの名無しさん
07/02/28 23:17:30
>>230
まて落ち着け。
前の文を見る限りそんな単純な問題でもなさそうだが…
その話なら単純にキャストだ。

とりあえず落ち着けw

234:デフォルトの名無しさん
07/02/28 23:26:40
なんか質問が似てるんだけど
GPGPU
スレリンク(tech板:377番)
とは別の人?

235:デフォルトの名無しさん
07/02/28 23:33:32
void func(float *t){
for(int i=0; i<128;i++)
printf("%f\n",t[i]);
}
int main(void){

int t[128];
for(int i=0; i<128; i++){
t[i]=i;
}
func((float *)t);
return 0;
}
これで0~128が表現できねぇよって話か?
GPUの事はわからんから、intやfloatのサイズの事はわからんからアドバイスは出来ない。

236:デフォルトの名無しさん
07/02/28 23:45:10
>>235
そうです!それです!
GPUじゃなくて、CPUでのやり方が知りたいんです。

237:デフォルトの名無しさん
07/02/28 23:51:42
C なら

int f;
*(float*)&f = -2;
printf("%f\n", *(float*)&f);

C++ なら

int f;
(float&)f = -2;
printf("%f\n", (float&)f);

238:デフォルトの名無しさん
07/02/28 23:52:41
C++ タイプのキャストを使うなら

int f;
reinterpret_cast<float&>(f) = -2;
printf("%f\n", reinterpret_cast<float&>(f));

だな。

239:デフォルトの名無しさん
07/03/01 01:07:25
C++の機能を使わないで済むならC++の機能は使わない方がよい。

240:デフォルトの名無しさん
07/03/01 01:16:39
Cの機能を使わないで済むならCの機能は使わない方がよい。
アセンブラの機能を使わないで済むならアセンブラの機能は使わない方がよい。

241:デフォルトの名無しさん
07/03/01 01:16:40
int to short
*pt>> (8 * sizeof(int) - 16)

int to floart
*p<< (8 * sizeof(int) - 32)


242:デフォルトの名無しさん
07/03/01 01:21:29
>>241
質問者はint型の変数をfloatの引数を持った関数に渡して
関数内でfloatからintに戻すって話だろ

243:デフォルトの名無しさん
07/03/01 01:42:08
>>237
それってsizeof(int) < sizeof(float)のときにメモリ破壊しね?

244:デフォルトの名無しさん
07/03/01 02:17:41
関数の引数にすると、キャストしても無駄だよ。
だから>>235の例は上手くいかない。


245:デフォルトの名無しさん
07/03/01 07:03:14
そもそもサイズの違うかもしれないものにキャストしちゃいかんだろ

246:デフォルトの名無しさん
07/03/01 07:35:14
環境はC++builderです。
CreatThreadを使用したマルチスレッドのアプリケーションを
ウィンドウの右上の×ボタンを、押して終了させたとき、
リソースとか全部開放されるのでしょうか?

247:デフォルトの名無しさん
07/03/01 10:00:08
>>246
動的に確保したリソースは自分で開放

248:デフォルトの名無しさん
07/03/01 10:44:51
>>247
はやいお返事、どうもありがとうございます。

249:デフォルトの名無しさん
07/03/01 14:52:28
>>245
このスレは環境依存 OK なはずなんだが

250:デフォルトの名無しさん
07/03/01 16:26:53
環境書いてないね

251:デフォルトの名無しさん
07/03/01 16:30:37
そうだね、ぬるぽだね

252:デフォルトの名無しさん
07/03/01 17:30:33
C++てどこでDLするの

253:デフォルトの名無しさん
07/03/01 17:33:23
>>252
C++の何がほしいんだ?

254:デフォルトの名無しさん
07/03/01 17:42:23
統合環境なら何でも

255:デフォルトの名無しさん
07/03/01 18:12:16
そんなの探す前にコミュニケーション能力あげる方が先だな

256:デフォルトの名無しさん
07/03/01 18:44:22
>>254
Microsoft Visual C++ 2005 Express Edition

257:デフォルトの名無しさん
07/03/01 19:08:40
>>246
窓っ子として注釈しておくと、
プロセス(タスクマネージャで見れるプログラムの単位)が終了した段階で
すべてのリソースはキレイに開放される

窓を[×]で閉じる=プロセスの終了ならそれで問題ない
だからスレッドの終了やCloseWindowだけとかなら駄目だし、
精神論で言って理想的なのはもちろん>>247

258:デフォルトの名無しさん
07/03/01 23:03:49
>>257
詳細に、どうもありがとうございます。
理解できました。

259:デフォルトの名無しさん
07/03/02 23:16:03
vector<T>を使って、Win32のアプリでクラスの配列を扱いたいんだが、
配列をグローバルに扱う方法がわかりません…
コントロールのハンドル等を扱うクラスなので、
初期化をウィンドウプロシージャ内で行いたいのですが、
どのようにすればいいのでしょうか。

260:デフォルトの名無しさん
07/03/02 23:19:01
push_back、push_back

261:259
07/03/02 23:29:03
ごめんなさい、push_back使うのはわかるのですが、
最初どこでどのように最初のメモリの確保を行えばよいのでしょうか。

262:デフォルトの名無しさん
07/03/02 23:33:14
ヘッダで以下のように
typedef vector<T> vT;
extern vT *pvT;

どっかのcファイルで
static vT *pvT;

最初のメモリ確保は、WM_CREATEとかでnewしておけば良い。

263:デフォルトの名無しさん
07/03/02 23:37:04
>>259
えーと、あるウィンドウに属するコントロールの配列を管理するんだろ?
何で「グローバル」である必要があるんだ?


264:デフォルトの名無しさん
07/03/02 23:42:22
グローバル空間に

vector<T> v;

でいいんじゃないの?

265:デフォルトの名無しさん
07/03/02 23:42:26
>>262
なぜポインタにする必要がある?

266:デフォルトの名無しさん
07/03/02 23:44:13
>>262
staticな変数をexternしてもリンクエラーが出るだけな気が。

267:デフォルトの名無しさん
07/03/03 00:20:41
>>259
int型の変数だろうとvector<T>型の変数だろうと
グローバル変数の使い方は同じじゃね?

268:デフォルトの名無しさん
07/03/03 00:24:21
>>267
static配列は
int a[] = { 0, 1, .. };
のような配列初期化構文が使えるが、vector<T>では使えないという
違いがあるな。

vector<T>をstaticに初期化したいならば
int a[] = { 0, 1, .. }:
vector<int> v(&a[0], &a[N]);
のように書くしかないが、メモリの無駄だな。

が、今回のケースでは初期化はWinProc内で行いたいそうだから
どうでもいいんだな。

269:デフォルトの名無しさん
07/03/03 00:25:57
コントロールを動的に生成/消滅させるウィンドウでないのなら
単なる配列でいいんじゃないの?
要素数が固定なら、vector<>はオーバースペック。

270:デフォルトの名無しさん
07/03/03 08:45:11
>>268
仮にvector<int> v = {0, 1, ...};のような初期化ができるようになっとしても、
コンストラクタの呼出まで初期化子を静的に用意しておくことになるだろうから、
その実装はおそらくこう書くのと同じようになると思う。
int a[] = {0, 1, ...}:
vector<int> v(&a[0], &a[N]);

271:デフォルトの名無しさん
07/03/04 00:41:25
質問させてください。
C++によるオブジェクト間のメッセージ通信についてなんですが、
オブジェクトAがオブジェクトBを含有する構造の場合、
AからBへのメッセージ送信は、AがBのメソッドを呼び出すという形でOKですが、
BからAへのメッセージ送信はどう実装するのがベターなんでしょうか?

1.AからBのメソッドを呼び出し、戻り値をメッセージとして扱う、(BはAに処理させたい内容を戻り値で返す)
2.BにAの参照を渡しておいて、BからAのメソッドを呼び出す、
3.各オブジェクトにメッセージプロシージャを用意して、そこにメッセージを投げる、(ウィンドウメッセージのように)
あたりは試してみているんですが、どうにもソースがスパゲッティになりがちで悩んでいます。
現在は、オブジェクトへのアクセス手段を統一でき、尚且つ不要なメッセージを無視することが可能な「3」を用いて実装しているのですが・・・
何か他にいい手法はないでしょうか?

272:デフォルトの名無しさん
07/03/04 01:02:31
>>271
相互依存するぐらいなら同じクラスにしちゃえばいいのに。
それでおかしくなるようなら A, B のどちらか(または両方)が大きすぎるんじゃないの?

273:デフォルトの名無しさん
07/03/04 01:25:41
>>271
デリゲートな悩みですか

274:デフォルトの名無しさん
07/03/04 01:35:33
実装というか、コーディングマナーの質問です。
配列の並び順を変更するときに、テンポラリ変数としてヒープ領域を使うのはありでしょうか。

275:デフォルトの名無しさん
07/03/04 01:37:36
必要ないのにヒープ領域は使わないかな
うっかりミスでリークしたりしたらあれだし

276:デフォルトの名無しさん
07/03/04 01:40:47
>>271
ケースバイケースだなぁ。

オブジェクト間のコミュニケーションが複雑化しすぎると感じるなら、
Mediatorパターンなんてのもあるよ。

ウィンドウメッセージは直接的なC++のメンバ関数呼び出しより
はるかに非効率だけれども、
非同期にできたり、相手が死んでいた場合のdangling pointer問題を
回避できたりという利点はある。

277:デフォルトの名無しさん
07/03/04 01:42:18
>>274
ヒープ使ってstd::auto_ptr<>に突っ込む分には>>275の言うような
問題はないが、
速度の問題だけで言えばalloca()の方が速い。移植性が劣るし
スタックサイズの制限にひっかかるかもしれないが。

278:デフォルトの名無しさん
07/03/04 01:54:53
>>272
元は全部1つのクラスで処理をしていたんですが、
行数が多すぎて分かり辛くなってきたため、分割しようとしたところ、相互依存の問題が出てきた感じです。

>>273,276
色々ありがとうございます。
デリゲート、Mediatorパターン、ちょっと調べてみます。

ゲームプログラムで、非同期処理なので、その辺ももう少し考えてみます。

279:デフォルトの名無しさん
07/03/04 07:12:04
今後WIN32は消える?

280:デフォルトの名無しさん
07/03/04 07:26:12
>>279
100年後とかには生き残ってないだろな。

281:デフォルトの名無しさん
07/03/04 10:23:01
>>277
allocaをMSのライブラリは拒否している(昔は使っていたが)。
デフォルトで配列を使ってサイズオーバーしたら
ヒープを使うという戦略になっている
当然allocaより速い

282:デフォルトの名無しさん
07/03/04 11:16:36
どうして適当なこと言う奴が後を絶たないのか

283:デフォルトの名無しさん
07/03/04 11:31:09
いい加減な事を発言した奴には罰金を科せばいい。

284:デフォルトの名無しさん
07/03/04 15:13:11
国会でやると大もうけだな

285:デフォルトの名無しさん
07/03/05 18:32:04
レスが付かないのでこちらにきました

Visual Studio2005 C++で
SystemParametersInfo(SPI_SETDESKWALLPAPER, NULL,
"c:\\a.bmp" ,0 );
しても壁紙が変更しません
解る方、教えてください



286:デフォルトの名無しさん
07/03/05 20:14:00
人が居なくても、ちゃんと元スレには「あちらで訊いてみます」って書いたか?

287:デフォルトの名無しさん
07/03/06 00:14:35
>>285
最後の引数に
SPIF_UPDATEINIFILE|SPIF_SENDWININICHANGE
しとけ

288:デフォルトの名無しさん
07/03/06 04:34:28
環境は、C++builderです。

void __fastcall TForm1::Button1Click(TObject *Sender){
//処理
}

他の関数で、ボタンを押した動作をしたいときは、
どのようにすればよいでしょうか。

289:デフォルトの名無しさん
07/03/06 10:29:58
TButton::Click()

290:デフォルトの名無しさん
07/03/06 14:06:31
>>289
ありがとうございます。

291:デフォルトの名無しさん
07/03/06 21:30:09
>>287
レスどうもです
SystemParametersInfo(SPI_SETDESKWALLPAPER, NULL,
"c:\\a.bmp" ,SPIF_UPDATEINIFILE|SPIF_SENDWININICHANGE );
ってしたんですが、だめでした
他にあればお願いします



292:デフォルトの名無しさん
07/03/07 02:58:25
C++
WinAPIをまとめてあるフレームワークライブラリを解析していたんですが

///// hoge.h ////
class hoge{
hoge();
}
extern hoge* phoge;

///// hoge.cpp ////
hoge* phoge;
hoge::hoge(){
phoge = this;
}

上のような(簡略化してあります)記述がありました。
コンストラクタ内でthisポインタでインスタンスのアドレスを
取得していると思うのですが、このインスタンスが実際に何処にあるのかが、分かりません。

他のファイルも調べてみましたが上の場所でしか、phogeにアドレスが代入されていませんでした。
環境はVisualC++2005です。

293:デフォルトの名無しさん
07/03/07 03:04:16
hogeのインスタンスがどこにも無いならコンストラクタも走らず、
したがって、phogeは常にNULLのはず。
とおもったが、phogeの代入箇所?さがすのはhogeのインスタンス化位置でそ?

294:デフォルトの名無しさん
07/03/07 03:38:54
hogeのインスタンス化のいちも探してみましたが、見つかりませんでした。
さっき気がついたのですがウィンドウの作成時にWNDCLASSではなくCREATESTRUCTが
つかわれていました。これが何か関係あるのでしょうか?
以下のように、この構造体のhInstanceに先ほどのhogeのインスタンスがわたされていました。
cs.hInstance = *app;

295:デフォルトの名無しさん
07/03/07 07:08:45
>>292
ソースがあるならそこにブレークポインタでとめて
ステップ実行で周辺を探すって手もある。
上手く行くか知らん。

hoge派生クラスがあるとか。
んなわけないか。

296:デフォルトの名無しさん
07/03/07 07:30:28
生成された時の自分自信のポインタをいれてるだけじゃん?

297:デフォルトの名無しさん
07/03/07 07:36:58
生成されているのは事実だが
何処で生成しているか判らないから聞いている質問だと思うが?

ブレークポイントを置いてこのときはまだ生成されていないとかから
すこしずつ絞り込んで行くとか。

298:デフォルトの名無しさん
07/03/07 07:41:43
extern 宣言してあるんだからコンパイル開始時に生成されると思うんだけど

299:デフォルトの名無しさん
07/03/07 07:43:12
あ、コンパイル開始というかプログラム開始時に

300:デフォルトの名無しさん
07/03/07 08:58:45
「class hoge を継承したクラスのインスタンスを1個は作れ。 作るタイミングはおまえさん次第」
で、どこかで作られたであろう インスタンス をポインタで保持して、
いつでも呼び出せるようにしている と。

# MFC の CWinApp じゃね?

301:デフォルトの名無しさん
07/03/07 09:00:01
グローバルで作ったのなら スタートアップルーチン内 でインスタンス化してる

302:デフォルトの名無しさん
07/03/07 09:30:18
DLLを作成したいのですが、
フリーソフトによる開発環境では不可能なのでしょうか?
Visual C++では出来なかった物で…。

303:デフォルトの名無しさん
07/03/07 09:45:38
できるよ
VCのスレ…いや、画像付きの解説ページがあったはずだから、ぐぐった方が良いな

304:デフォルトの名無しさん
07/03/07 09:50:37
>>303
ExpressバージョンではMFS、ATLが含まれていないので作成出来ないと思っていました。
有難うございます、もう少しぐぐってみます。

305:デフォルトの名無しさん
07/03/07 10:43:30
MFCもATLもなくたってDLLは作れる。
プロジェクト作るときにどこかでDLLを選ぶだけ。

306:デフォルトの名無しさん
07/03/07 11:29:49
>>291
つ GetLastError()

307:デフォルトの名無しさん
07/03/07 16:27:32
質問です。
クラスの「constメンバ関数」は、メンバー変数の書き換えを禁止しますよね。
これによって「その関数は何度呼び出しても問題ないはずだな」
と思って分担作業をしていました。

ところがconstメンバ関数の中から、グローバル空間の変数を書き換えている奴がいたのです。
いままで知らなかったのですが、constメンバ関数はグローバル空間の変数などを書き換えてもコンパイルエラーにならないのですね。

この行為を禁じるための、C++文法的な書き方はありませんでしょうか。
「グローバル変数使うの禁止!」といっても使う奴が稀にでてきてコマっています。

308:デフォルトの名無しさん
07/03/07 16:31:38
ありません。

309:デフォルトの名無しさん
07/03/07 16:43:50
質問です。

ヘッダーファイルで
private:
     int (*ptr)[10];
     int x[10][10];
と宣言しています。ちゃんと機能しています。
それでデコンストラクターでメモリの解放をしたいんですけど
     delete [][] x;
ではコンパイルが通りません。
     delete [] x;
では
     Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
と出てRun-Time Errorになってしまいました。
どうやって解放するんでしょうか?教えてください。

環境はVC++2005 Express Editionです。

310:デフォルトの名無しさん
07/03/07 16:49:12
>>309
newしてないんだからdeleteする必要はない。

311:309
07/03/07 16:53:34
>>310
あア、ナルほど!
newとdeleteはセットなんですね。
ご親切にどうもありがとうございました!

312:デフォルトの名無しさん
07/03/07 17:02:02
あと、デコンストラクタじゃなくて、デストラクタな。
俺も昔勘違いしてた。

313:デフォルトの名無しさん
07/03/07 17:40:36
if(aaa>=1 && aaa<=10)

のように

if(aaa>='1' && aaa<='10')

これも文字だけでできますか?わざわざ数字に変換しなくてもいいですか?

314:デフォルトの名無しさん
07/03/07 17:43:27
わざわざ数字に変換しないとだめです

315:デフォルトの名無しさん
07/03/07 17:43:51
'10'

316:デフォルトの名無しさん
07/03/07 17:45:25
'10'は規格上は通るけど、恐らくあなたの期待した値にはならないでしょう。

317:デフォルトの名無しさん
07/03/07 17:47:25
'9'までしか無理ということですか?

318:デフォルトの名無しさん
07/03/07 17:49:53
文字定数でぐぐれ

319:デフォルトの名無しさん
07/03/07 17:54:32
そもそもaaaの型は何だよ。何が入っているんだ

320:デフォルトの名無しさん
07/03/07 18:00:41
リテラルにあった型です

321:デフォルトの名無しさん
07/03/07 18:30:53
年月日時分秒を取得するlocaltimeという関数は見つかったのですが
その取得した時間に10時間プラスしたときに
24時間を越えると日付によって年月日は変動すると思います

時間をたしたいのですが
こういう処理のためになにか用意されていないでしょうか?
環境はVC++2002です

322:デフォルトの名無しさん
07/03/07 18:33:17
閏秒は無視して、localtimeに渡す前のtime_tに対して10*3600足せばよくね?

323:デフォルトの名無しさん
07/03/07 18:34:19
time_t
struct tm

324:デフォルトの名無しさん
07/03/07 18:34:25
>>321
time_t型にした上で、10時間(10 * 60 * 60[sec])を足し、localtime()でばらすかstrftime()で文字列にすれば宜しい。
既にlocaltime()でばらしてあるなら、tm_hourに10を足してからmktime()でtime_tにしてもいい。

325:デフォルトの名無しさん
07/03/07 18:39:11
初心者本でこの辺りをまともに解説しているのってあるのかな。
ちなみに、localtime(), gmtime(), asctime(), ctime()はスレッドセーフではないので
マルチスレッドプログラミングのときはご用心。

326:321
07/03/07 18:45:56
マルチスレッドプログラミングですがlocaltimeを使うのはまずいでしょうか?

327:デフォルトの名無しさん
07/03/07 18:49:18
処理系のマニュアルを参照セヨ

328:デフォルトの名無しさん
07/03/07 18:49:49
簡単なプログラムの途中に見栄えを良くするために
横線を引きたいのですが、何かいい方法はありますでしょうか?

329:321
07/03/07 18:50:51
1スレッドでしか試してませんが
time_tに対して10*3600してできました
ありがとうございます

330:デフォルトの名無しさん
07/03/07 19:00:18
localtime()などは内部の静的な領域を使い回しするから、
それを呼び出すスレッドが複数ある場合は衝突が発生する可能性がある。
まぁ、呼び出すスレッドが一つだけなら問題ないけどね。

簡単に図式化するとこうなる。
・単一スレッドからの呼び出し
スレッドA ─localtime()呼び出し─内部領域変更─localtime()から復帰─内部領域から結果を回収─

・複数スレッドからの呼び出し
スレッドA ─localtime()呼び出し─内部領域変更─localtime()から復帰─内部領域から結果を回収─
スレッドB ──localtime()呼び出し─内部領域変更─localtime()から復帰─内部領域から結果を回収─
                            ↑                      ↑
                            ここで壊れる。 もし壊れなくても、ここでスレッドBからの呼び出しの結果を読む羽目になる。

331:デフォルトの名無しさん
07/03/07 19:08:53
localtime()を使うスレッドクラスをひとつ用意すればいいということですね
すごく参考になりました

332:デフォルトの名無しさん
07/03/07 19:43:27
>>320
ふざけたこと抜かすんじゃねー

333:デフォルトの名無しさん
07/03/07 19:44:01
VCのCRTはTLS使ってるから問題ないけどね。

334:デフォルトの名無しさん
07/03/07 19:48:49
>>317
数値と文字を一緒にするな。
他の言語だと自動で文字を数値に変換したりするけど
C/C++などは'9'をそのままASCII文字コードだよ。

URLリンク(e-words.jp)

つまり
'9'を数値で言うと57
'$'を数値で言うと36
だ。

'10'はコンパイラによって違うと思う。

335:デフォルトの名無しさん
07/03/07 21:39:31
メイン関数内でnewしている継承される可能性のあるクラスを
継承された場合、継承後のインスタンスでnewしたいのですが、エレガントな方法が
思いつきません、ご教授お願いします。

336:デフォルトの名無しさん
07/03/07 21:49:53
>>335
複数のクラスがそのクラスを継承してる場合はどうするべき?


337:デフォルトの名無しさん
07/03/07 21:52:44
>>335
もうすでにnewしちゃったんじゃしようがないんじゃない。


338:デフォルトの名無しさん
07/03/07 21:54:41
newの代わりにFactoryを用意して(関数ポインタでも可)それ経由で生成するのがC++的には一番楽かな。

339:デフォルトの名無しさん
07/03/07 22:13:46
>>336
継承後も含めてそのクラスのインスタンスが一つしか存在しないようにします。
>>338
Factoryでインスタンスを取得し、
FactoryをVirtualtou(等)にして継承した場合書き換えるという風にですか?

340:デフォルトの名無しさん
07/03/07 22:36:25
継承するクラスをC++より上位のレイヤーで1つだけに制限できるというなら、
グローバルな関数 Base *new_derivered_class(); を実装すればよくね?

それとも、継承先のクラスが存在しない場合Baseをnewする必要があるわけ?

341:デフォルトの名無しさん
07/03/07 23:07:38
ホームページから任意のデータの取得を行いたいんだが
さっぱりその方法が解りません。
その手のことが書かれたサイトを教えていただけませんか?

342:デフォルトの名無しさん
07/03/07 23:10:18
rubyなどのスクリプトを使う

343:デフォルトの名無しさん
07/03/07 23:14:21
>>342
やはりそうですか。
Cでやりたかったのですが、素直に真珠でやります。
ありがとうございました。

344:デフォルトの名無しさん
07/03/07 23:15:59
真珠…

345:デフォルトの名無しさん
07/03/07 23:20:04
>>340
継承してメンバー関数を上書きして処理を記述するようにしたいので、
何か処理をする場合には、必ず継承しなければならないです。
継承しない場合は、現実的にはないと思うのですが・・・

346:デフォルトの名無しさん
07/03/07 23:23:48
>>343
「猫でも分かるネットワークプログラミング」にhtmlを読み込んで表示する方法が書いてあったと思う
今手元にないので分からんが、WinSockをつかってたとおも

347:デフォルトの名無しさん
07/03/07 23:29:17
WinsockでHTTPしゃべるのは結構面倒くさいヨ。

348:デフォルトの名無しさん
07/03/07 23:38:18
どうもです。
分野はネットワーク関係なんですね。
それが解っただけでも十分です。
ありがとうございました。

349:デフォルトの名無しさん
07/03/07 23:51:03
>>343
WindowsならURLDownloadToCacheFile()が一番お手軽

350:デフォルトの名無しさん
07/03/08 01:16:50
>>343
真珠ってPearlって書くのしってんのか?
いやPerlもPearlから来てるんだがな

351:デフォルトの名無しさん
07/03/08 11:07:27
C++builder使っております。
unsigned char*とchar*のキャストは、(*型)だけでキャストできるのでしょうか?
出来ないキャストの場合は、エラーや警告などでますか?
以下のようにしてプログラミングしましたが、希望通りの出力でした。
ネットで危険なキャストがどうの、って良く見かけるんですが
よくわかりません。
”桁が大きくなると、小さい型にキャストするときは気をつける。”
これだけ注意すれば大丈夫でしょうか?

unsigned char* un_str="hoge";
char* str;
unsigned char* from_char_to_unsigned_char_str; //char*->unsigned char *の格納する変数

printf("un_str=%s\n",un_str); //unsigned char*は、char*みたいに出力できるか

str=(char*)un_str;
printf("str=%s\n",str);//(char*)だけで、キャストできるのか

from_char_to_unsigned_char_str=(unsigned char *)str;
printf("from_char_to_unsigned_char_str=%s\n",from_char_to_unsigned_char_str);//(unsigned char*)だけで、キャストできるのか

------出力-------------------------------
un_str=hoge
str=hoge
from_char_to_unsigned_char_str=hoge

352:デフォルトの名無しさん
07/03/08 14:03:04
C言語を仮定するけど、ポインタは全部同じサイズだから相互にキャストできるよ。

> printf("un_str=%s\n",un_str);
%s は const char* 型の引数を期待するから、
*((const char*)un_str)という変換が行われることになる。
un_strが指してるのは"hoge"、つまり const char[] だから、問題なく変換できる。
他も同じ。

353:デフォルトの名無しさん
07/03/08 14:26:55
> C言語を仮定するけど、ポインタは全部同じサイズだから相互にキャストできるよ。
現実には大抵そうなっているけど、規格上はそんな規定なんてないはず。

354:デフォルトの名無しさん
07/03/08 14:28:46
そうだっけ?
んじゃvoid*の扱いはどうなるんだ?

355:デフォルトの名無しさん
07/03/08 14:29:45
同じでない場合は、void*が一番でかいポインタのサイズ
そして使うときはキャストされるので問題なし

356:デフォルトの名無しさん
07/03/08 14:32:17
昔懐かしい、farポインタ、nearポインタ、とか?

357:デフォルトの名無しさん
07/03/08 14:40:29
残念ながら void* も void(*)() を保持できる保証はない。

358:デフォルトの名無しさん
07/03/08 14:42:58
375<< インラインアセンブリならできるかも・・・

359:デフォルトの名無しさん
07/03/08 14:45:19
>>356
普通に char* と int* のサイズが違うようなアーキテクチャも存在した。

360:デフォルトの名無しさん
07/03/08 17:23:43
>>352-359
> C言語を仮定するけど、ポインタは全部同じサイズだから相互にキャストできるよ。
いろいろと実験しながら、少しずつわかってきました。
丁寧に説明ありがとうございました。


361:デフォルトの名無しさん
07/03/09 20:15:24
WinSDKで、
モーダルダイアログボックスを使っているとき、
プロシージャに最後に呼ばれるメッセージは何ですか?
WM_CLOSEメッセージでDestroyWindow(hDlg)して、
WM_DESTROYメッセージが呼ばれた後に、WM_COMMANDがくるのですが…


362:デフォルトの名無しさん
07/03/09 20:55:26
WM_DESTROYでウィンドウが消えた後は
たとえそのウィンドウ宛にメッセージが来ても
それは存在しないウィンドウハンドル宛だし
処理するところがないので無視することになるだけだと思うけど。

何か特殊なケース?

363:デフォルトの名無しさん
07/03/09 21:06:17
>>362
WM_COMMANDがくること自体は問題ないのですが、
エディットコントロールにWM_COMMANDがきたときに使うメモリを解放するのに、
WM_DESTROYの後にエディットコントロールに対してWM_COMMANDがきてしまうと、
わざわざWM_DESTROY呼ばれる前後で、場合分けするのが無駄だと思えるので…

364:デフォルトの名無しさん
07/03/09 21:31:38
VC++6 で CString 使ってるんだけど、
CString な変数に ANSI コードページでもユニコードでもない文字列つっこんで処理したいんですわ。
具体的には、GetLenth とか Replace したい(ANSI コードページでもまともに処理してなさそうだけど)
楽に処理するにはどうしたらいいでしょう?CString 捨てな方法でもいいです。

365:デフォルトの名無しさん
07/03/09 21:56:12
vector<BYTE>でよくね?

366:364
07/03/09 22:07:24
>>365
俺に言ってる?
CString はたとえばコードページ 932 の場合、
Replace で 1 バイト文字を置換対象にするときに、2 バイト文字の下位バイトが置換対象とバイト的には等しくても、置換しないようにするよね?
そういうのをすべてのコードページでやりたいの。
ではよろしくお願いします。

367:デフォルトの名無しさん
07/03/09 22:08:23
>>364
っ nkf

368:364
07/03/09 22:33:56
>>367
nkf のライブラリにコードページを指定出来るようなメソッドを追加したクラスが実装されているということでしょうか?
単なる変換ができるというだけなら却下ですな。
(nkf 使わなくても文字コードの変換はできるし、変換することによってコードをマッピングできなくなる場合とか考えたくない。
ユニコード系のコードに変換すればマップだけはできるんだろうけど。
それといちいち文字コード変換するとよさげなソースコードにならなさそうなんだ。
そもそも nkf って日本語しか対応してないだろ?
個人的には今回の場合 UTF-8,CP51932,CP932 を使えれば問題ないと思ってるんだけど、他の奴が許さないんだぁ。)
注文多すぎてむかつくかもしれないけど、どうかどうかよろしくお願いします。
ぶっちゃけ CString::SetCodepage() とかいうメソッドが実装されていて、あとはよきにはからってくれる実装がほしい。

369:デフォルトの名無しさん
07/03/09 22:44:11
>>368
一々文字コード変換をしたほうがデバッグが楽だと思う

UTF-8 -> Unicode 変換

Unicode で何か処理

Unicode -> UTF-8 変換

よさげなソースコードにならなさそうって言われればそれまでだけど…

370:デフォルトの名無しさん
07/03/09 22:50:22
CStringに自分が今どのコードページのデータを持っているとか
それにあわせてReplaceの動作が変わるなんて出来ないんじゃないのって思うから
vector<BYTE>でよくね?

371:デフォルトの名無しさん
07/03/09 22:53:13
>>364
つ MLang

372:364
07/03/09 23:14:46
>>369
やりたいことの一つに、「ANSI CP 以外の文字列読み込み->文字置換->そのまま書き込み」ってのがあるんだけど、
ユニコードにいちいち変換してたら絶対にスマートでないよね。
あと、調べたところまずなさそうなんだけど、変換->逆変換で違うコードにマッピングされると困る。
>>370
コードページ指定して UNICODE には変換できるんだから、出来ないはずはないとおもうんだけどなぁ。
クラスに変数 1 つだけ入れておけば使用側がセットして良きにはからうことはできるはず。デフォルトは CP_ACP で。
なんで実装されてないのか理解できないほどだ。
vc8 だと reentrant locale が一部実装されていて、1文字送りは簡単にできそうになってるなぁ。VC6 でつくらないといけないんだけど。。。
>>371
ちょっと調べてみます。ざっとみた感じでは変換しかしてくれなさそうだけど。
あと、これつかわないと CP51932 つかえなさそうですね。
MultibyteToWidechar とかに 51932 とかつっこめば変換だけは出来るとおもってたけど。

373:デフォルトの名無しさん
07/03/09 23:17:13
鬼車がCSIじゃなかったっけ。Cだけど。

374:デフォルトの名無しさん
07/03/09 23:30:14
>>372
> ユニコードにいちいち変換してたら絶対にスマートでないよね。
コードページごとに処理を特殊化させるほうがよほどスマートじゃないと思うがね。

375:デフォルトの名無しさん
07/03/09 23:36:58
というか、そういう、1つの言語に対応するエンコーディングが氾濫していて
UNICODEの変換・復元がもったいない、なんていうことを言うのは
日本人だけなのではないか?(w

376:デフォルトの名無しさん
07/03/09 23:38:03
ソケットについて質問です。

クライアントからホストを

char* szHost = "www.google.co.jp"
gethostbyname( szHost );

の様に指定してHTMLをサーバから取得できる事は判ったのですが、例えば、

取得したいHTMLが、

www.google.co.jp/search?hl=ja&q=c言語&btnG=Google+検索&lr=

の様にクエリも含む場合はどうすれば良いのでしょうか。
よろしくお願いします。(板違いなら誘導お願いします。)

377:デフォルトの名無しさん
07/03/09 23:40:20
URLエンコードしてそのままGETにぶち込めばいいだろ?
CESも場合によっては変換する必要があるけど。

378:デフォルトの名無しさん
07/03/09 23:47:15
返信ありがとうございます。
暮れ暮れ君で申し訳ないですが、URLのエンコードってどうやるんでしょうか。

379:364
07/03/09 23:52:19
>>373
単純な置換にはかなり大げさなライブラリですな。いざとなったらこれで Replace をオーバーライドするか。
どうもありがとうございます。
もっと単純にできる方法も引き続き募集いたします。
>>374
個人的にはコードページが違うんだから、特殊になるのは当然だとおもうけど。
ユニコードが*本当に万能*なら汎用的に処理できるんでしょうけど。ま、CSI 論争はやめておきましょうか。
>>375
ま、大きな声でいってるのは日本人だけでしょうな。
でも、XFree86 で utf8 関数が投入されたときは一部の外国人もぶーたれてたな。
CSI かどうかはおいといて、reentrant locale がほしい人は外国でも結構いるみたい。

380:デフォルトの名無しさん
07/03/09 23:55:41
なんかこの人気持ち悪い…

381:デフォルトの名無しさん
07/03/09 23:58:26
>>380
おまえもな

382:デフォルトの名無しさん
07/03/09 23:59:17
俺も俺も

383:デフォルトの名無しさん
07/03/09 23:59:45
std::basic_string<char, euc_jp_traits<char> >みたいな?
traitsを自作するとかさ。

384:デフォルトの名無しさん
07/03/10 00:05:36
>378
「URLのエンコード」程度なら、検索するべきですわん。
簡単に見つかるから。正確な事もわかるし。

ラフに解説すると、URLとして使ってよい文字ってのは
あらかじめ決まってるから(←ってのは知ってたと思うけど)
使えない文字は %xx みたいな形式に置き換える事。

385:デフォルトの名無しさん
07/03/10 00:42:35
>>379
変換コストがもったいないと思っているのなら
大抵のCSI対応クラスは内部で統一コードに変換してるから意味ないぞ

386:デフォルトの名無しさん
07/03/10 00:46:18
>>385
CSIの意味わかってる???

387:デフォルトの名無しさん
07/03/10 01:13:10
キーが倒されている場合は歩くのモーションを、倒されていない場合はウェイトのモーションを再生したいのですが、

whileの中で、

if(キーが倒されている)
アニメーションAを再生
アニメーションBを停止

else if(キーが倒されている)
アニメーションAを停止
アニメーションBを再生

と書くと、()内が真or偽が判定されるたびに、アニメーションが最初から再生されて、0フレーム目しか再生されません。
最初に書いたようなことをするには、どういう風にプログラムを書けば良いでしょうか?
できればヒントでよろしくお願いします。

388:デフォルトの名無しさん
07/03/10 01:19:58
再生時に開始フレーム指定してそっからはじめればいいだけじゃん

389:デフォルトの名無しさん
07/03/10 01:35:22
どっちみちキーが倒されている気がするのは気の所為か?
キーも大変だな、一々倒されて。

390:デフォルトの名無しさん
07/03/10 01:36:17
>>380
ヘンなとこで敬語使ってるからじゃね。

391:デフォルトの名無しさん
07/03/10 02:00:27
整数の加算結果がオーバーフローしたかどうかを調べるにはどうすればいいですか?

392:デフォルトの名無しさん
07/03/10 02:03:47
加算前より減ってたらオーバーフロー

393:デフォルトの名無しさん
07/03/10 02:30:54
>>391
鼻から悪魔がでたらオーバーフローしていると判断してよろしい。
処理系によっては、オーバーフローした場合を判断する方法があるかもしれない。

394:デフォルトの名無しさん
07/03/10 10:26:51
 すいません、初歩的な質問なんですが、どなたかご意見いただければうれしく思います。
 クラスBの中でクラスAのオブジェクトの配列を管理したい。
 でもクラスAは、A2やA3などにも派生させてて、それも配列に入れたい、って場合。

class A {
...
};
class A2 : public A{
...
}
class A3 : public A{
...
}
class B {
vector<A> a1_vector;
}

 ってしたいんだが、これだとa1_vectorにはA2,A3が入らないですよね?
 ってなると・・

class B {
vector<A*> a1_vector;
}

 で、new A, new A2とかでオブジェクト作って、そのポインタをa1_vectorにpushすることになると思うんですが、これだとクラスBのインスタンスが破棄されたときに、a1_vectorで管理されている各オブジェクトって廃棄されないですよね?
 で、google先生とかに聞くと、share_ptr使う人がいるみたいなんですが、それで問題ないですかね?
 なんか注意点とかありますか?もしくは他にいい方法ありますでしょうか?


395:デフォルトの名無しさん
07/03/10 11:11:03
問題ないよ、A のデストラクタを仮想関数にするの忘れないようにね


396:デフォルトの名無しさん
07/03/10 11:19:43
設計を見直せ。

397:デフォルトの名無しさん
07/03/10 11:28:53
>>394
boost::shared_ptrでおk
std:auto_ptrはコピーが破壊的でコンテナにいれらんないから駄目

敢えて他の方法を挙げるとすれば、Boehm GCを使うとか?

398:デフォルトの名無しさん
07/03/10 11:34:10
GC使うと、メモリ解放はいいけど、デストラクタ呼びだしタイミングが
予測不能にならない?

399:デフォルトの名無しさん
07/03/10 11:35:30
>>394ではないが。
>>396
参考までに聞きたいが、どう設計を見直すんだ?

C++でポリモーフィズムを実現したいなら、参照を経由するしかないし
派生クラスを基底型の配列やvectorに突っ込もうとすると
スライシングが発生するから、>>394の言っていることはごく当然の話では?

C++でポリモーフィズムを使うなと言ってる?

400:デフォルトの名無しさん
07/03/10 11:39:21
>>398
勿論その辺は他のGC言語となんも変わらない。

401:デフォルトの名無しさん
07/03/10 12:31:45
Boost使うならポインタに特化したboost::ptr_vectorなんてものもある。

402:デフォルトの名無しさん
07/03/10 13:11:10
>>399
>396ではないが、「他にいい方法」を模索するなら実装方法を検討する前に設計を見直せということでしょ。
>394ではないから、そのクラス構成が最適解なのかは判らないのだから。

403:デフォルトの名無しさん
07/03/10 14:19:41
>>402
それは深読みじゃねえの?
>>394はC++でポリモーフィズムをやりたいときのスマートな方法を問うている
だけに見えるけど。

404:デフォルトの名無しさん
07/03/10 14:36:21
>>402
最適解なのか「判らない」んなら、少なくとも「設計見直せ」は言いすぎだろうな。
「その設計では駄目だ」と断定してるのと同じだ。

405:デフォルトの名無しさん
07/03/10 15:08:24
394です。
みなさん、いろいろありがとうございます。
おおむねsharedでよさげな感じですね。

ただ、396さんの「設計みなおせ」も気にはなるところです。
やっぱり、こういう書き方になる設計って良くないんですかね?
他の人のソース見ても、こういう書き方してるの、あまり見たことないし。


406:デフォルトの名無しさん
07/03/10 15:28:51
他所に見せるソースはサンプルが多いから
サンプルにboost使う状況を避けた設計してるとかじゃないかなぁ(適当

sharedなら割と直感的になるので悪くないと思うし、
EffectiveSTLの7項にもマンドクセってなったらsharedを検討してみては? ってある

407:デフォルトの名無しさん
07/03/10 16:26:35
boostのsharedは物凄く遅いらしいから場合によっては別案を考えた方がいいと思う

408:デフォルトの名無しさん
07/03/10 16:50:44
「物凄く遅い」と言うには、どの程度遅いのかデータが欲しいところだね。

409:デフォルトの名無しさん
07/03/10 16:53:03
URLリンク(www.boost.org)

410:デフォルトの名無しさん
07/03/10 17:01:33
価値観によるところは大きいだろうけど、これが「物凄く遅い」なら
iostreamやソートは「筆舌に尽くしがたいくらい遅い」んだろうね。

411:デフォルトの名無しさん
07/03/10 17:45:37
>>392, 393
鼻から悪魔ですか・・・
まあ、Intel系ならちゃんとオーバーフローしてくれますよね^^

どうもありがとうございました。

412:デフォルトの名無しさん
07/03/10 22:49:42
C++で、Cのstrtok()のような関数はありませんか。

別にstrtok()でも目的は果たせるんですが、
元の文字列を破壊したり、同時に2ヶ所以上で呼びづらかったりと
あまり美しいとは言えないような気がして。


413:デフォルトの名無しさん
07/03/10 22:59:03
無いと思う
けどそれくらい自分で作ればいいんじゃ?
std::stringとか、目的の機能を実装するのに使えそうなモノはあるし

414:デフォルトの名無しさん
07/03/10 23:01:17
>>412
istringstreamからデリミタを指定してgetline()


415:デフォルトの名無しさん
07/03/10 23:11:45
istream_iteratorでfor_eachがC++流

416:デフォルトの名無しさん
07/03/10 23:14:21
高機能さを求めるならboost::tokenizerだと思う。

417:デフォルトの名無しさん
07/03/10 23:17:43
>>415
ただのistream_iteratorだとtokenじゃなくてcharが返らんか?

418:417
07/03/10 23:24:39
ごめん。超アホなこと書いた。
でも、これってデリミタ指定できるか?

419:412
07/03/11 00:10:10
レス感謝。
いただいたヒントを元に、更に調べてみようと思います。

それにしても、strtok()ってクセ強いですよねぇ……。



420:デフォルトの名無しさん
07/03/11 00:23:25
>>412
ちゃんとしたベンダーならマルチスレッドな環境で同時に使っても
問題が起きないことを保証してくれてるもんだぞ>strtok()
まぁ、同じスレッドから複数の処理をやっちゃうと確実にアウトだけど。

421:デフォルトの名無しさん
07/03/11 00:30:41
boost::tokenizerでは、デリミタを残す/捨てる、空トークンを残す/捨てる
を選べるのが良いな。

strtok()には色々問題があるが、デリミタも空トークンも捨てる仕様なので、
これでは困ることもある。
シェルのような感じで空白文字を区切りに使うときはこれでよいのだが。

環境によってはBSD由来のstrsep()という関数が使える場合もある。
こっちは予めリエントラントで、デリミタを捨てて空トークンを残す仕様だ。
ただし、コピーを避けるために元のバッファに破壊的に動作するのは同じ。

Cなら単にsscanf()を使うのも悪くない選択肢。

422:デフォルトの名無しさん
07/03/11 00:32:24
>>420
MSVC++の場合はhidden dataをTLSに隠す仕様だから問題ない。
が、リエントラント版strtok()はstrtok_r()のような別名で提供している
実装も多いよ。
こういうことがあるから、移植性を考えてもstrtok()の使用は
好ましいとは言えない。

423:デフォルトの名無しさん
07/03/11 01:58:54
質問です。

/* test.c */
#include <stdio.h>
#include <math.h>

int main(void) {
double i = 2;
double foo;

printf("%d\n", (int)pow(10, 2)); /* 結果 100 */
printf("%d\n", (int)pow(10, i)); /* 結果 99 */
printf("%f\n", pow(10, i)); /* 結果 100.000000 */
foo = pow(10, i);
printf("%d\n", (int)foo); /* 結果 100 */

return 0;
}

このソースをMinGW32-gccでコンパイル・実行すると、結果がコメントのようになります。
(bccだと、100、100、100.000000、100 になるのですが。)
これはコンパイラの仕様なのか、それともバグなのか、どちらでしょうか?


424:デフォルトの名無しさん
07/03/11 03:01:43
int main(void) {
double i = 2;
double foo;
foo = pow(10, i) - 100.0;
printf("%e\n", foo);
foo = pow(10, i);
printf("%e\n", foo);
}

多分情報落ちしてるだけだと思う。

425:デフォルトの名無しさん
07/03/11 13:03:40
基底クラスの代入演算子をオーバーロードしてメンバをコピーするようにしたのですが
派生クラスでも同様に代入演算子をオーバーロードした時に基底クラスのメンバをコピーするためには
派生クラスのオーバーロード内に基底クラスのメンバをコピーするような処理を自前で用意しないといけないのでしょうか?



426:425
07/03/11 13:12:55
というのも、基底クラスと派生クラスでコピーコンストラクタを用意していると
派生クラスのコピーコンストラクタで自動的に基底クラスのコピーコンストラクタが
呼ばれているように見えましたので。。。

427:デフォルトの名無しさん
07/03/11 13:17:40
こんな感じで基底クラスのoperaotr =を呼べばいい。
class Base
{
public:
  Base& operator =(const Base&);
};

class Derived : public Base
{
public:
  Derived& operator =(const Derived&);
};

Derived& Derived::operator =(cosnt Derived& d)
{
  Base::operator =(d);
  //以下Drived分のコピー処理
}

428:425
07/03/11 13:46:43
>>427

なるほど。基底クラスを指定して呼び出せばよかったのですね。
基本的なことだったのかもしれませんがとても勉強になりました。



429:デフォルトの名無しさん
07/03/11 15:08:05
質問があります。

class Hoge { … }

vector<Hoge> HogeArray;

文法としてこんなことできますか?

430:デフォルトの名無しさん
07/03/11 15:13:14
できるよ

431:デフォルトの名無しさん
07/03/11 15:43:21
出来ないな。セミコロンがない。

432:デフォルトの名無しさん
07/03/11 16:39:16
絶対言うやつがいると思った

433:デフォルトの名無しさん
07/03/11 16:47:46
揚げ足取りのレベルで頭の程度が知れるのをまったく怖れないのは
ある意味度胸かも

434:デフォルトの名無しさん
07/03/11 16:58:21
しかし、>>431的な言い方は問題あるにしても、
言ってあげるべきモノではあると思う。
慣れないうちはつけ忘れ多いだろうし。

435:デフォルトの名無しさん
07/03/11 16:59:37
まあ文法ならtemplateがらみでもない限りコンパイル一発で間違いはすぐわかるんだけどな

436:デフォルトの名無しさん
07/03/11 17:25:54
それでも文法の間違いがわからない人が来るスレだと思ってた

437:デフォルトの名無しさん
07/03/11 17:38:43
>>435
ヒント:ココは初心者スレ

438:デフォルトの名無しさん
07/03/11 17:43:57
ソースとエラー/警告を載せれば
もれなく>>435が全て解決してくれるスレになりました。

439:デフォルトの名無しさん
07/03/11 17:47:23
>ソースとエラー/警告を載せれば
初心者はどれを載せたらいいのかもわからんし難しいなw

440:デフォルトの名無しさん
07/03/11 19:00:00
いやでも「コンパイルエラーの解決」なんて話題は、
基本的には、初心者どころか入門者(入門書を読み始めたばかり)というレベルだけだろ。
それを解決するもの簡単だし。
もちろん、規格の細部や処理系異存かなんて話はあるけどさ。

本当に時間がかかる「バグ」というのは
「コンパイルは通るけど意図通りに動きません」なんだから。
もちろん、極稀なコンパイラのバグにぶつからない限り
「ソースの通りに動いている」わけだけど。

441:429
07/03/12 00:31:30
すいません。

431さんの言うとうりセミコロンの付け忘れでした。

442:デフォルトの名無しさん
07/03/12 01:44:48
>>431のエスパー能力に敬意を表する!

443:デフォルトの名無しさん
07/03/12 01:54:30
これはもうメイクミラクルやね

444:デフォルトの名無しさん
07/03/12 06:03:42
いや>>441は偽物だ。

三点リーダを>>429のように使えるはずないもん!

445:デフォルトの名無しさん
07/03/12 11:07:51
newとdeleteを頻繁に使うのはよくないですか?

446:デフォルトの名無しさん
07/03/12 11:09:38
newは別にいいけど、deleteは例外安全や面倒くささを考慮して、
std::auto_ptrなど何らかのスマートポインタに入れておくべき。

447:デフォルトの名無しさん
07/03/12 16:47:03
pを辿って99から1までを表示するプログラムです。

実行すると途中のcount=35あたりまで表示されてエラーが起こります。
メッセージ:「ハンドルされていない例外は TEST.exe にあります:0xC0000005: Access Violation。」

これは何故起こるのでしょうか。解決法もできれば教えてください。お願いします。
struct Test
{ int x;
 Test *p;
};
int main()
{ int i;
 std::vector<Test> v; //xに1~99を順に入れていく。pには一つ前のポインタを入れる
 Test b;

 b.p = NULL;
 v.push_back(b);

 for (i=1;i<100;i++) { //
 b.x = i;
 b.p = &v[i-1];  //
 v.push_back(b);
 }

 Test *c;
 c = &v[v.size()-1];

 int count = 0;
 while ( c->p != NULL )  {      // NULLが出るまでpを辿る
  printf("%d: %d\n",count++,c->x);
  c = c->p;
 }                                                 長くなってすいません。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch