トップページ⇒tech
1001コメント301KB

【初心者歓迎】C/C++室 Ver.49【環境依存OK】

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2008/02/20(水) 12:33:41
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.48【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1202141921/
【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
0596デフォルトの名無しさん2008/02/24(日) 18:59:37
>>595
そもそもそのような継承にしてる理由は?
0597デフォルトの名無しさん2008/02/24(日) 18:59:59
>>595
CFoo のメンバ関数ならキャストは要らないはず。
IHoge〜 に意味が無くなると言うが、こっちからしたら CFoo や vec の使い方も
ひっくるめて最初からその継承関係の意味がわからん。
05985952008/02/24(日) 19:06:57
えっと、まあ、CFooがMFCのCViewで、CFooEx〜がCTreeViewとかCListViewなのでどうした物かと質問しました・・・。
0599デフォルトの名無しさん2008/02/24(日) 19:10:28
なんでvector<IFoo>とかにしないわけ?
あるいは、virtual Test()をもつ何かインターフェースに。
0600デフォルトの名無しさん2008/02/24(日) 19:18:44
CFooEx の状態で持てないのなら
ダウンキャストすることになるだろうな。
0601デフォルトの名無しさん2008/02/24(日) 20:05:03
>>590
もう自前でパースしてるよ
06025922008/02/24(日) 20:05:24
最適化オプション関係でした
0603デフォルトの名無しさん2008/02/24(日) 20:10:05
>>601
車輪の再発明
0604デフォルトの名無しさん2008/02/24(日) 20:25:22
boostが?
0605デフォルトの名無しさん2008/02/24(日) 20:29:54
ごめん勘違い
0606デフォルトの名無しさん2008/02/24(日) 20:58:50
文字コード?jisコード?って覚えるべきもの?
0607デフォルトの名無しさん2008/02/24(日) 21:06:12
必要になったときに表を見れば十分
0608デフォルトの名無しさん2008/02/24(日) 21:06:13
>>606
全てのJIS漢字のJISコードなんて、そうそう覚えられるもんじゃないと思うが。
0609デフォルトの名無しさん2008/02/24(日) 21:14:12
class Piyo{
〜
};

class Hoge{
public:
  void hoge(Piyo[][256]);
};

void Hoge::hoge(Piyo[][256] piyo){
〜
}

こんな実装をした時に、Hoge::hogeのpiyoを書いておくと'Piyoは未定義のシンボル'と怒られてしまいます。
仮引数をPiyo[][256]だけにすればコンパイルは通りますが、どう使えというのか・・・といった感じです。
コンパイラはBCC5.5を使っています。クラスの2次元配列をできれば「参照」で渡したいのですが、
どうすればいいんでしょうか?
0610デフォルトの名無しさん2008/02/24(日) 21:15:36
単に書き方がおかしいだけだ。
void Hoge::hoge(Piyo piyo[][256]) {
しかもこれいわゆる参照渡しの挙動をするが、
正確にはポインタ渡しだし。
06116092008/02/24(日) 21:29:18
うわ・・・。確かにおかしな書き方してた・・・。
自分でもドン引きです・・・。ありがとうございました
0612デフォルトの名無しさん2008/02/24(日) 23:16:37
http://streaming.linux-magazin.de/en/program_fosdem.htm
cmakeについてのリアルタイム講演が聞けるそうな
0613デフォルトの名無しさん2008/02/24(日) 23:20:24

ReadFile(fp , &(buf[N]) , 1500 , &sz , NULL);

でエラーで止まります bufは十分にとってあります なぜでしょうか
0614デフォルトの名無しさん2008/02/24(日) 23:24:57
>>613
bufの宣言がどうなっているかにも拠るが、&(buf[N])をbufにしてみろ。
それで巧くいくなら、お前は馬鹿だ。
0615デフォルトの名無しさん2008/02/24(日) 23:31:32
位置を変えてループして読もうとしてるんです bufにすると上手くいきますが前のデータが消えます
原因不明ですが、変数の位置変えたらエラーでなくなり一応うごくようになりました 
0616デフォルトの名無しさん2008/02/24(日) 23:34:06
たまたま動いてるだけくさいな。
単純にバッファオーバーフローしてるだけじゃないのか?
0617デフォルトの名無しさん2008/02/24(日) 23:36:56
メモリ関係のエラーみたいです また止まりました
別のところから変更しないと直りそうにありません
設計やり直してきます
0618デフォルトの名無しさん2008/02/24(日) 23:48:58
coutやnewの多重定義ってどうやるのかわかりません できますか
0619デフォルトの名無しさん2008/02/24(日) 23:51:19
>>613
char buf[NMAX*1500]
なら、&(buf[N*1500])

char buf[NMAX][1500];
なら、&(buf[N][0])

char *buf[NMAX]
for(...) buf[N] = malloc(sizeof(char) * 1500);
なら、buf[N]
0620デフォルトの名無しさん2008/02/24(日) 23:52:38
cout の多重定義??
0621デフォルトの名無しさん2008/02/24(日) 23:55:54
<<のオーバーロードに違いない
0622デフォルトの名無しさん2008/02/24(日) 23:56:41
ostream& operator<<(ostream& ostr, const Hoge& hoge) {
 ostr << hoge.str();
}

みたいなやつか。
0623デフォルトの名無しさん2008/02/25(月) 00:07:21
stringは連続していますか? memcpyとかはできますか?
0624デフォルトの名無しさん2008/02/25(月) 00:08:24
なんでstringにmemcpyしたがる人が多いんだろう。
0625デフォルトの名無しさん2008/02/25(月) 00:09:43
stringにmemcpyはまずいんじゃね
0626デフォルトの名無しさん2008/02/25(月) 00:10:45
string s="9999999999";
strcpy( &s[5], "000");
は正しいですか
0627デフォルトの名無しさん2008/02/25(月) 00:14:03
詳しいことわすれたけど、s[i]で文字を取得できるならできるんじゃね?
やった後、stringオブジェクトは壊れるとおもうけど
0628デフォルトの名無しさん2008/02/25(月) 00:15:06
この日本語不自由そうなとこが同一人物くさい
0629デフォルトの名無しさん2008/02/25(月) 00:15:58
>>623
規格ではそんな保障はされていません。
0630デフォルトの名無しさん2008/02/25(月) 00:17:13
>>627
あっ嘘、s[i]で取得できてもできないと思う
置き換えたいなら、replaceを使いなさい
0631デフォルトの名無しさん2008/02/25(月) 00:17:23
>626
std::stringのことなら、正しくない。
0632デフォルトの名無しさん2008/02/25(月) 00:21:59
これが動くのですが、stringはchar*の拡張であることは保証されていませんか?だめな例はありますか


int main(){
string str="9999999999";

char *pointer=&str[5];

memcpy( pointer, "000", 3);

str+=(string)"add";

cout<<str;

return 0;}
0633デフォルトの名無しさん2008/02/25(月) 00:25:35
stringの制御情報はどこへ格納されていますか?
ユーザーは合法的でない方法を使ってもアクセスできませんか?
0634デフォルトの名無しさん2008/02/25(月) 00:28:12
>632
必要のないポインタ操作はやめましょう。
動くか動かないかがプログラムの正しさの判定基準ではありません。
0635デフォルトの名無しさん2008/02/25(月) 00:28:47
>>632
あるコンパイラのあるバージョンで動くとしても、規格で保証されていなければ、
他のコンパイラや同じコンパイラの別バージョンでは動かないかもしれない。
それでもいいなら、どうぞ?
今後ずっと同じコンパイラを使い続けて、決して変えないのなら、たぶん問題ないだろう
0636デフォルトの名無しさん2008/02/25(月) 00:30:23
>>633
なんのためのクラスだと思う?
0637デフォルトの名無しさん2008/02/25(月) 01:00:06
例外の使い方について

エラーの通知にはエラーメッセージより例外を使う方がいいと聞いたのですが
オリジナルな例外クラスを投げたり、charを投げまくる仕様にしていいのですか?

例外というと、これ以上の実行に支障が出るときに使うようなイメージがあるのですが実際の現場ではどうなのでしょうか?
0638デフォルトの名無しさん2008/02/25(月) 01:01:51
例外処理を主要処理に書くと遅くなったりしませんか?
0639デフォルトの名無しさん2008/02/25(月) 01:14:59
コンパイラによって例外処理用のコードが追加されるから
パフォーマンスは落ちる。禁止オプションもあるくらいだからな。
特に組み込みでは。。。。。。
0640デフォルトの名無しさん2008/02/25(月) 01:17:11
クラスメンバー変数は、自動で0やNULLで初期化されますか? 
0641デフォルトの名無しさん2008/02/25(月) 01:20:04
>>637
好きなように使え。

ただ、エラーメッセージと例外では通知する相手が違うぞ。
エラーメッセージはエンドユーザ、例外はプログラマに通知するもんだ。
ユーザがいきなり「0x00d2345でlogic_error例外が発生しました」とか見せられても訳わからんだろ。

charも投げられるが、標準との整合を考えて投げるのはオリジナルも含めてstd::exception派生のクラスにしとけ。
0642デフォルトの名無しさん2008/02/25(月) 01:21:41
>>640
static領域に配置したオブジェクトのメンバなら、コンストラクタで何もしていなければ0になります。
それ以外は不定です。
0643デフォルトの名無しさん2008/02/25(月) 01:29:37
static つけたらクラスが消滅しても値が残るんですか?
クラスが消滅したらアクセスできなくなると思いますが
つけなくても自動でstaticになりますか
0644デフォルトの名無しさん2008/02/25(月) 01:50:30
>>641
なるほど・・・

戻り値でエラーを知らせたり、NULLを返したりという方法もあるのでどういう方法が主流なのかなと思ってまして

自分はたいていの場合
何が起こったのか確認して、何事もなかったかのように受け流してさいごにエラーログを確認する
位のデバッグライト的な使いか確かしてないのですが・・・
0645デフォルトの名無しさん2008/02/25(月) 01:59:21
>>644
どれが主流というのは無い。場面によって適切な方法があるだけ。
ライブラリとか、設計思想によりエラーの返し方がある程度統一されてたりすることもあるけどね。

とにかく作ってみなさい。できたものを自分なりに分析して、ここはこうした方がよかったとか、省みることで成長するんだから。
0646デフォルトの名無しさん2008/02/25(月) 02:09:23
>>643
残ります、というかクラスを複数生成しても全部同じstaticメンバ変数をさすんですよ?

三行目がいまいちなに言ってるのかわからんstaticつけないとstaticにはならないよ
0647デフォルトの名無しさん2008/02/25(月) 02:12:48
まずインスタンスという言葉を覚えようや
0648デフォルトの名無しさん2008/02/25(月) 02:13:09
>>643
>static つけたらクラスが消滅しても値が残るんですか?
(クラスではなくインスタンスのことを言いたいのだと思うが…)
staticで宣言した変数は、main関数の開始前から終了後まで存在する。
破棄されるのがmain関数終了後だから通常はそれへのアクセスが問題になることはないが、
staticの変数が異なるファイルで定義されて、一方のデストラクタからもう一方を参照するような
処理があるとまずい。
意味が分からないようなら気にしなくていい。

>つけなくても自動でstaticになりますか
ならない。
06496482008/02/25(月) 02:14:21
ちょっと訂正
×staticの変数が
○2つのstaticの変数が
0650デフォルトの名無しさん2008/02/25(月) 02:24:32
質問があるのですが、
include " "
include < >
" ", < > の違いを教えて頂けませんか?
0651デフォルトの名無しさん2008/02/25(月) 02:30:32
>>650
コンパイラのマニュアルか入門書を読みなさい。
0652デフォルトの名無しさん2008/02/25(月) 02:47:52
>>650
http://www.google.co.jp/search?q=C%E8%A8%80%E8%AA%9E+include
上から順に読んでいけばそのうち解説してるサイトにたどり着く
0653デフォルトの名無しさん2008/02/25(月) 07:25:36
>>632
std::string の内部バッファの連続性は次の規格で保証されるようになる。
おそらく現状全ての実装でそうなっていることが、その規格変更を実現したんだろう。
だから一応そう言うことをしても問題は無いはずだが、
メンバ関数でできることはメンバ関数でやった方がいい。
replace 使うといい。
0654デフォルトの名無しさん2008/02/25(月) 09:45:12
例外ねぇ、何も考えずにint型のエラーコードを投げちゃうなぁ
返り値でエラーコード返しちゃうと返り値の型が拘束されちゃうしメンドクサ

結局こういう使い方だと例外のありがたみを半分も得ていない気がする
0655デフォルトの名無しさん2008/02/25(月) 10:00:21
例外はstd::exceptionみたいな基本クラスを決めとかないと
ありがたみが半減する。
0656デフォルトの名無しさん2008/02/25(月) 11:44:36
ガベージコレクションは、標準のC++でつくれますか?ライブラリでは動作するのか不安です
自作したいです
あと、整数変数は、初期化なしでアクセスしてもエラーは出ませんか?
0657デフォルトの名無しさん2008/02/25(月) 11:46:47
素人が自作した方が不安だと思うんだが
0658デフォルトの名無しさん2008/02/25(月) 12:00:29
これ動かすとクラス変数は値がほぼ一定ですが理由はなぜですか? 

#include <iostream>
using namespace std;

class cl{public: int i; cl(){cout<<"class "<<i;} };

int main(){
int n, a[100];
for(n=0; n<100; n++){
cl *x=new cl;
cout<<" arrey "<<a[n]<<"\n";
}
getchar();
}
0659デフォルトの名無しさん2008/02/25(月) 12:09:11
動的確保による違いでした たぶんヒープ領域は値があまり変化しないことが原因かも・・・

#include <iostream>
using namespace std;

class cl{public: int i; };

int main(){
int n, a[100] ;
cl x[100];
for(n=0; n<10; n++){
cout<<"class="<<x[n].i<<" arrey="<<a[n]<<endl;
}
getchar();
}
0660デフォルトの名無しさん2008/02/25(月) 12:12:41
>>656
整数変数を初期化しなくてもエラーは出ませんが、ローカルな場合に不定値なので初期化しましょう。
0661デフォルトの名無しさん2008/02/25(月) 12:37:27
定数文字列は値渡しにして、動的な文字列は参照渡しにしたいのですが、これだとメモリリークしますよね
どうやれば直りますか?

#include <iostream>
using namespace std;

class cl{
char *str;
public:

cl(char* const& x){ str=x; }

template <size_t n> cl(char (&x)[n]) {
str=new char[n]; strcpy(str,x);}

};

main(){
cl str="rrrr";
str="oooo";
getchar();
}
0662デフォルトの名無しさん2008/02/25(月) 12:42:21
値渡しされているかフラグを作って、されていれば解放する様にすればいいのですが、
初期化前にコンストラクタで代入されてしまうとフラグが確認できません
0663デフォルトの名無しさん2008/02/25(月) 12:47:11
>>661は間違えました 定数式が期待する方へ行っていませんでした それもどうやれば直りますか
0664デフォルトの名無しさん2008/02/25(月) 12:56:55
>>661
やりたいことがよくわからん。せめて、コンパイルできるソース(の断片)を貼ってくれ。
0665デフォルトの名無しさん2008/02/25(月) 13:00:43
まとめるとテンプレート関数で、
定数文字列"   "と
固定文字列char [n]と
可変文字列char *を
区別して、上の二つならメモリを確保して値渡しにしたいんです
値を書き換えたいため
0666デフォルトの名無しさん2008/02/25(月) 13:01:40
最近ずっとこいつ出没してるな
0667デフォルトの名無しさん2008/02/25(月) 13:02:01
それと、新たにメモリを確保するときに、以前確保したメモリを解放してメモリリークしないようにしたいです
0668デフォルトの名無しさん2008/02/25(月) 13:06:38
>>667
要は、const char *でコンストラクトするときはメモリを確保して、char *でコンストラクトするときは確保しなければ委員でね?
それと、書き換えのときはconst char *でもchar *でも以前の状態に応じて解放しないといけないんでね?
0669デフォルトの名無しさん2008/02/25(月) 13:07:20
簡略化すると関数の引数で、" "型と、char[]型と、char*型を区別したいって事です
0670デフォルトの名無しさん2008/02/25(月) 13:17:48
>>668
constつけるだけでは無理です

#include <iostream>
using namespace std;

class cl{
char *str;
public:
cl(char const *x) { cout<<"文字列は定数です\n"; }
cl(char *x){ cout<<"文字列は可変長です\n"; }
};

main(){
cl str="xxx"; //定数で初期化
char ch[]="yyy"; str=ch; //固定配列の代入
str="zzz"; //定数の代入
getchar();
}
0671デフォルトの名無しさん2008/02/25(月) 13:19:34
すまん、そもそも char ch[] = "yyy"は固定長でも書き換え可能な配列なんだが
それを定数として扱ってはいけない理由を教えてくれ。
0672デフォルトの名無しさん2008/02/25(月) 13:22:36
あ、聞き方が変だ。

char ch[] = "yyy"は書き換え可能なんだから可変長と同一視すればいいし
const char ch[] = "zzz"は書き換え不可能なんだから定数と同一視すればいいのでは?
0673デフォルトの名無しさん2008/02/25(月) 13:22:41
可変長文字列と {定数文字列、固定長文字列} ( ← 一緒でいいです)
を分類する方法教えてください
あと、すでにメモリが確保してあればそれを解放する方法教えてください
0674デフォルトの名無しさん2008/02/25(月) 13:23:36
長さも書き換えられないといけません
0675デフォルトの名無しさん2008/02/25(月) 13:24:19
こいつ日本人なのかなぁ
0676デフォルトの名無しさん2008/02/25(月) 13:26:00
>あと、すでにメモリが確保してあればそれを解放する方法教えてください
これは簡単。コンストラクト時にメモリを確保したらフラグをセットしておいて、代入オペレータでそれをチェックすればいい。
勿論、代入オペレータも2種類用意して必要ならフラグをセットするのは当然として。
そのフラグはいずれにしてもデストラクト時に必要にナル死ね。
0677デフォルトの名無しさん2008/02/25(月) 13:28:05
あー、ローカルな配列だとコンストラクト時にフラグが立ったら問題か。
ここは一つ、char配列は渡さないと言う運用でw
0678デフォルトの名無しさん2008/02/25(月) 13:28:42
で、この馬鹿はなんで目的を説明できないんだろうなぁ。>675ってことなんだろうか。
0679デフォルトの名無しさん2008/02/25(月) 13:43:23
目的は、参照渡しのできるstringを作りたいんです
現存するやつは値渡しです
0680デフォルトの名無しさん2008/02/25(月) 13:45:33
いやだから、それを(態々)作る目的を聞いているのだが。
0681デフォルトの名無しさん2008/02/25(月) 13:46:27
チャットじゃないんだから要旨をまとめてから書き込め。
0682デフォルトの名無しさん2008/02/25(月) 13:46:53
>>676
クラスの確保と同時に代入されてしまうと、フラグが設定されていないので動作不明になりませんか?
0683デフォルトの名無しさん2008/02/25(月) 13:50:39
>>681
可変長文字列は参照渡しにして、それ以外は値渡しにして、新たな文字列が渡されたら以前のを解放したいんです
0684デフォルトの名無しさん2008/02/25(月) 13:52:58
>>683
>680
0685デフォルトの名無しさん2008/02/25(月) 13:53:25
伸びてると思ったら、また例の日本語が不自由なヤツが現れたのか
0686デフォルトの名無しさん2008/02/25(月) 13:56:58
何をしたいかと言うと

(バイナリ) 文字列 str , p , qに対して

replace(str, p, q)  strの全文でpをqに置換する

という関数を作りたいんです
0687デフォルトの名無しさん2008/02/25(月) 14:03:08
>>665

それぞれの型の応じて関数を振り分ければいいのか?

template<size_t N>
void g(const char (&a)[N]) {
cout << typeid(a).name() << endl;
}

template<size_t N>
void g(char (&a)[N]) {
cout << typeid(a).name() << endl;
}

void g(char *&p)
{
cout << typeid(p).name() << endl;
}

template<typename T>
void f(T& t)
{
g(t);
}
0688デフォルトの名無しさん2008/02/25(月) 14:03:31
//テスト
int main()
{
f("abc");
char a[5];
f(a);
char *p;
f(p);
}
0689デフォルトの名無しさん2008/02/25(月) 14:08:07
ぜんぶcです・・・・

#include <iostream>
#include<typeinfo>
using namespace std;

template<size_t N> void g(const char (&a)[N]) { cout << "a" << endl;}

template<size_t N> void g(char (&a)[N]) { cout << "b" << endl; }

void g(char *&p){ cout << "c" << endl; }

template<typename T> void f(T& t) { g(t); }


int main() {
f("abc");
char a[5]; f(a);
char *p; f(p);
}
0690デフォルトの名無しさん2008/02/25(月) 14:12:45
>>689
そりゃコンパイラがだめなんだろうな。
g++ 4.2.3だとa b cになる。
0691デフォルトの名無しさん2008/02/25(月) 14:12:57
>>686
これでいいのか?
#include <string>
#include <iostream>
using namespace std;
void replace(string& str, string p, string q)
{
int i = str.find(p);
while (i >= 0) {
str.replace(i, p.length(), q);
i = str.find(p, i + q.length());
}
}
int main()
{
string str = "abcdabcd";
replace(str, "bc", "BC");
cout << str << endl;
}
0692デフォルトの名無しさん2008/02/25(月) 14:17:34
>>686
俺だったら、次のどっちかにする。だから、673のようなことをしたくなる理由が理解できない。
1. strは全く書き換えず、置換後の文字列は新しく確保したメモリに書き込んで戻り値に返す。
2. strは書き換えできるという前提でstrを書き換える。(書き換えできない
文字列をstrに渡したければ、書き換え可能な場所へコピーを作ってそれを渡す)
0693デフォルトの名無しさん2008/02/25(月) 14:25:43
STR str="hogehogehogehogehoge"
replace(str, "geho", "(^_^)"); や、

int N=300*1024*1024;
char *ch=new char [N];
for(int n=0;n<N;n++)ch[n]=n; //巨大なバイナリ配列
STR str(ch,N);
replace(str, "geho", "(^_^)");
がしたいんです
0694デフォルトの名無しさん2008/02/25(月) 14:29:10
巨大な配列を扱おうとすると、元のデータをコピーしたり、返却時に新規確保すると、
もとのデータと併せて領域が2倍必要になりますしコピー時間がかかります
>>691 バリナリデータも扱いたいです
0695デフォルトの名無しさん2008/02/25(月) 14:32:38
>>693
できるぞ
>>694
バイナリデータも問題ない
#include <string>
#include <iostream>
using namespace std;
void replace(string& str, string p, string q)
{
int i = str.find(p);
while (i >= 0) {
str.replace(i, p.length(), q);
i = str.find(p, i + q.length());
}
}
int main()
{
string str="hogehogehogehogehoge";
replace(str, "geho", "(^_^)");
cout << str << endl;

int N=300*1024*1024;
char *ch=new char [N];
for(int n=0;n<N;n++)ch[n]=n; //巨大なバイナリ配列
string str2(ch,N);
replace(str2, "geho", "(^_^)");
cout << str2 << endl;
}
0696デフォルトの名無しさん2008/02/25(月) 14:32:39
C++
開発環境 CentOS
コンパイラ g++
関数書き出しプログラムが機能せず。
どうしてでしょうか。
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#define buffer_size 1000
using namespace std;
int main(int argc,char *argv[]){
string buffer;
int count=0;
char *p;
ifstream fin(argv[1]);
if(!fin)return 0;
while(fin>>buffer){
while(count!=1){
if((p=strchr(buffer.c_str(),'{'))!=NULL){
count++;
cout<<buffer;
}
}
while(count!=0){
if((p=strchr(buffer.c_str(),'{'))!=NULL)count++;
else if((p=strchr(buffer.c_str(),'}'))!=NULL)count--;
}
}
fin.close();
return 0;
}
■ このスレッドは過去ログ倉庫に格納されています