【初心者歓迎】C/C++室 Ver.57【環境依存OK】
しまった。コピペしてそのままにしてしまってた・・・。 正しくはこうだな。 ◆ソースのインデントについて 半角やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのが最も良いですが、 直接貼るのであれば、全角空白か に置換しておくことをお勧めします。
int main(int argc, char *argv[]) { FILE *fp; if(fopen_s(&fp, "hoge.txt", "w")) exit(1); fwrite("hoge", 4, 1, fp); fclose(fp); return 0; } これを普通に実行するとちゃんとファイルが作成されるのですが、アイコンにファイルをドロップして始めるとファイルが作成されません。 なにか制約でもあるのでしょうか?
>>4 どこか、あなたの知らないところに作られています。
フルパスでファイルを作るか、カレントディレクトリを指定すると宜しいかと。
>>5 ありがとうございます。わけの分からないところに作られていました。
デフォルトでカレントディレクトリに作られると勘違いしていました。
class Hoge { Hoge() { Init(); } ~Hoge(); Init(); } このようにコンストラクタ時に 初期化用のメンバ関数を用意して使うことはokなのでしょうか。
8 :
デフォルトの名無しさん :2008/07/17(木) 05:48:51
ok
ありがとうございました。 これで長々と書かずに済みます。
>>7 Initはvirtualにしないことだけ気をつけて。
>>6 いや、カレントディレクトリに作られているはずだよ。
カレントディレクトリが予想外な場所になっているだけで。
12 :
デフォルトの名無しさん :2008/07/17(木) 08:43:07
オープンソースのdllなんかを改造して 自分でコンパイルする時 デバッグモードでやるのとリリースモードでやるのでは どういった違いがでるのでしょうか?
デバグ情報 最適化
本当のプロはデバッグモードは使わない。
15 :
12 :2008/07/17(木) 09:34:57
デバッグ情報っていうのは、どういう場面発生して、どうしたら使えるんでしょうか?
デバッグ情報がある場合: gdbとか使ってると、Segmentation Falutなんかが出たときに、 その場所をソースコードの行番号で教えてくれる。
動的解析ツールでも、デバッグ情報があれば行単位で結果を出せるね。 そうでないと、アセンブラのインストラクション単位になってしまう。
18 :
デフォルトの名無しさん :2008/07/17(木) 14:23:26
VC++ 6で作成したものをVC++2005で開いてビルドすると long lTemp = timeStamp.ulSeconds; char* pszTemp = ::ctime( &lTemp ); のところで error C2664: 'ctime' : 1 番目の引数を 'long *' から 'const time_t *' に変換できません。(新しい機能 ; ヘルプを参照) 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 とでてしまいました。 それで char* pszTemp = ::ctime((time_t *) &lTemp ); と書き替えたらビルドは通ったのですが、これで問題ないのでしょうか?
lTempの値次第
>>10 virtualにしてもコンストラクタ内からだと無視されなかったっけ?
>>18 time_t の大きさ確認してみ。最悪変なところ書き換えるかも。
VC2005から、時間関係がデフォで64bitになってる。
32bitにするのはなんかマクロがあった。
>>18 要は、lTempをtime_tにしておけってこった。但し、tieStamp.ulSecondsの仕様に注意な。
>21はどうやらconstが目に入らなかったらしいが。
23 :
デフォルトの名無しさん :2008/07/17(木) 16:21:55
C言語のソースからC++で定義されている関数を呼びたいのですが やはり無理でしょうか?
24 :
23 :2008/07/17(木) 16:25:59
すいません、この場合もextern "C"でいけるんですね。 スレ汚し失礼しました。
インテリジェントエージェントが動的コードスニペットでバグを起こしそうなコマンドや 構文にチェックをする。その段階でメタレベル構文にデバッグ情報が埋め込まれ、メモリリーク や例外のときに情報がセットされる。 君が使うのはまだ難しいと思うよ。 怪しい変数をprintfで表示させるところから初めてはどうだろう?
イミフ
DEBUGでデバッグしたコードをRELEASEしたらクラッシュしてひどい目にあって以来 RELEASE以外でビルドしてない 出来上がるのは別のプログラムだからDEBUGでDEBUGしても何の意味もないよ アホらしいけど
>>27 直接関与はしてないけど
大学の研究室にそういうコードは存在した
なんかコード領域を実行時に書き換えてる風な挙動だった
初期化してないポインタでも使ってるような感じ
初代が作ったものを毎年手を入れていくものだから
何年目でそういうことになったのか不明
初代のコードはすっきりしてたのに、最新版は複雑怪奇w
>>27 たまたまreleaseビルドで動いてるだけだったりしてな。
VSのバージョン上げてプロジェクト変換したら止まったり、
別のPCでexe動かしたら止まったりw
Wallにしたらつらつらと出たりしてな。
31 :
デフォルトの名無しさん :2008/07/17(木) 21:36:18
double hoge[100]; memset(hoge,0.0,sizeof(hoge)); これをするとdoubleからintへの変換っておこられるんですが、何がいけないんですか
void* memset(void*, int, size_t)
memsetはバイト単位でデータを埋めるのにしか使えない。
double hoge[100] = {0.0}; これで全部0.0が入るんじゃね?
>>31 第二パラメータを0にすればコンパイル自体はできますが、0.0で埋めたことになる保証はありません。
大人しく>34の手を使うかC++のstd::fill()を使うか自分でループを回しましょう。
36 :
31 :2008/07/17(木) 22:44:27
わかりました!どうも
>>34 それ[0]は0.0だけど、[1]以降は0で埋めたことになるんじゃないか?
まぁ0.0も0も同じことだと思うけど
38 :
デフォルトの名無しさん :2008/07/17(木) 23:23:45
子クラスにメンバ変数もデストラクタもない場合ときに、 public継承する場合は親クラスのデストラクタは virtualにしないとまずい? class Base { public: Base(int a, int b); ~Base(); private: int m_a; int m_b; }; class A : public Base { public: A(int a); }; これはまずい? やりたいことは、 「親クラスのコンストラクタを制限したバージョン」 を作りたいんだが。
39 :
デフォルトの名無しさん :2008/07/17(木) 23:26:03
何でコンストラクタから仮想関数を呼べるんですか? どうせ誰も得しないんだろうからコンパイルエラーにしちゃえばいいのに。
>>39 呼べるようにしたほうが設計的に美しいんじゃね?
>>38 >「親クラスのコンストラクタを制限したバージョン」
>を作りたいんだが。
それの理由を書いた方が良いかと。
WSAStartup(MAKEWORD(2,0), &wsd); SOCKET sd = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); closesocket(sd); WSACleanup(); それぞれ関数の後ろでGetProcessHandleCount()で プロセスが開いているハンドル数を調べると、 WSASocket()で10個ハンドルが開き、closesocketしても減りません。 この10個のハンドルを閉じる方法はないんでしょうか? WindowsXP Pro SP2、VisualStudio 2008 ExpressEditionです。 スレ違い?
>>41 いや、これ自体に特に意味はないんだが。
環境依存のメモリリークとか発生しないかと思って。
再利用するとかで内部的に完全には解放されてないだけじゃね? WSACleanup()でも消えない?
>>38 基底クラスのデストラクタを virtual にする必要があるのは、派生クラスの
インスタンスを基底クラスのポインタ経由で delete する場合。基底クラスの
デストラクタが virtual でないと、派生クラスのデストラクタが呼ばれない。
Base* b = new Derived();
...
delete b; // Derived::~Derived を呼ぶために、Base::~Base を virtual に!!!
RAII でインスタンスを破棄するなら、virtual である必要はない。
>>42 WSASocket(); closesocket(); を交互に繰り返したら増えつづける?
>>45 それはわかるんだが、
「子クラスにメンバ変数もデストラクタもない場合」
にどうなるのかってのが知りたかった。
48 :
42 :2008/07/18(金) 00:03:33
>>44 WSACleanup()の後でも減ってませんでした
>>46 会社にしか環境ないので
明日それをやってみます。
>>48 ExpressEditionならタダで手に入る…
ってか会社でExpressEdition!
>>49 会社でExpressEditionは別にいいだろ
商用利用可だし、IDEはともかくコンパイラが無料なのが重要なわけだから
その無料のExpressEditionで数百万で売るもの作ってます^^
>>38 それなら FactoryMethod でも使えば。
Base* CreateBase(int a);
54 :
49 :2008/07/18(金) 00:21:25
55 :
デフォルトの名無しさん :2008/07/18(金) 00:23:00
gcc4.2でopenMP使ってforループ並列化しようとすると、 「ループカウンタがunsignedです」って警告される。 ループカウンタってsigned使うのが普通なの? vectorとかsize_typeは大体unsignedだと思うんだけど。
>>55 実装上の都合だとでも思ってください。
0スタートのループを、逆条件にしても大丈夫なようにってことかもね。
signedとunsignedの違いが問題になるような回数のループをやろうとすること自体に問題がある
>>58 通常は size_type (unsigned) に合わせないとコンパイラが警告してくれちゃう
まぁループはsignedにしといたほうが無難だろうね
61 :
デフォルトの名無しさん :2008/07/18(金) 00:58:50
整数値を引数として与えその数値によって文字列を返す関数を作ったのですがうまくいきません const char [2]' から 'charへの変換とかでます。どうしたらよいですか? char abc(int number){ switch( number ) { case 0: return "A"; break; case 1: return "B"; break; ・ ・ ・
"A" → 'A'
63 :
デフォルトの名無しさん :2008/07/18(金) 01:04:50
2文字以上の場合もあるんですよ
char* abc(int number){}
まちがい const char* abc(int number){} か
66 :
デフォルトの名無しさん :2008/07/18(金) 01:08:52
constがなぜいるんですか??
文字列リテラルを書き換えてはイケナイ以上、 constを付けて防禦を計っておくべき、みたいな
68 :
デフォルトの名無しさん :2008/07/18(金) 01:23:05
>>61 #include <stdio.h>
#include <stdlib.h>
char * abc(int number){
int rank = 1;
int num = number;
char *numarray;
while(num){
num /= 10;
rank++;
};
numarray = (char *)malloc(sizeof(char)*(rank+1));
sprintf(numarray,"%d",number);
return numarray;
}
int main()
{
char * ans = abc(123);
printf("%s \n",ans);
free(ans);
return 0;
}
ループカウンタはsignedが普通って事は、 int size = static_cast<int>(instance_of_vector.size()); for (int i = 0; i < size; ++i) ...; ってやればいいの?
それだとINT_MAXを超えた値が返ってきたらsizeは-になるぞ。 いやまぁ2億を超える要素なんてないだろうけどw
71 :
デフォルトの名無しさん :2008/07/18(金) 01:49:37
>>69 要はさ
for(unsigned int i = 10; i > 0; i -= 2)
みたいなことやっちゃったら無限ループになるから
ちゃんと解ってるならunsignedでも良いでしょう
>>71 だから、OpenMPで警告が出るんだってばさ。
理解してるなら警告は無視していい
>>47 そんな条件は関係ない。デストラクタに virtual が付いてない基底クラスへのポインタが
実際には派生クラスを指している場合、 delete すると未定義動作になる。
virtualな関数が増えると、ポリモーフのコストって増える?
77 :
デフォルトの名無しさん :2008/07/18(金) 04:49:34
GNUのライブラリを使って、ソフトやライブラリを作ったら 元のGNUのソースを同封しないといけませんか??
78 :
デフォルトの名無しさん :2008/07/18(金) 04:52:32
元のソースに手を加える改良の場合は変更後のソースを入れないと駄目なんですよね 改変せず利用するだけならば、入れなくて良いですか? GNUのライブラリを使用していると明記する必要ありますか?
>>77-78 ライセンス嫁。あと GPL なら GPL FAQ 日本語訳とか。
80 :
デフォルトの名無しさん :2008/07/18(金) 05:25:33
GNUのコード使ったら、
81 :
デフォルトの名無しさん :2008/07/18(金) 05:29:24
GNUを利用したら、改変のある無しに関わらず、ソースコードもうpせよ ってことでOK? 具体的には、GNUコードから、WindowsのスタティックリンクかDLLを作って それを自分のソフトで使用した場合は、自分のプログラムのコードをうpするって事?
82 :
デフォルトの名無しさん :2008/07/18(金) 08:47:02
初心者質問てここでいいのですかね? もしスレ違いなら誘導お願いします。 private継承について質問なのですが、親から継承したメンバはすべてprivateになり 子クラスからアクセスできないものと思っておりますが、違うのでしょうか。 実際コードを書いて確認してみたところ、アクセスできないぽいのですが サイトによってアクセスは可能と書いているところもあるので混乱しています。 アクセスする方法があれば教えていただきたいです。 それと、private継承を調べると「実装の継承」という言葉がたいてい出てくるのですが、 これの意味がよくわかりません。 「実装の継承」の実際の使い方など教えていただけませんか。
書物はまだしも、サイトの記事なんて鵜呑みにする方がどうかしている。
getHoge(),setHoge()のような関数(アクセサ)を継承元で書かないとアクセスできないよ。 private継承、実装の継承というのは、基底クラスで定義された関数など「実装」のみを継承し、 インターフェイスや性格については基底クラスと同じものを持たなくて良い =基底クラスのオブジェクトではあれができたから継承先でも出来るだろうという期待が出来ない継承のことかな。 逆にpublic継承というのは、DerivedクラスはBaseクラスの一種であるとみなして操作できなければならなくて、 BaseがCry()と言う関数を持ってたらDerivedも持っていなくてはいけないし(鳴き声は違うにしても)同じような動作をしなくてはいけない。 …という話がEffective C++に詳しく書いてあるので読んでおこう。
>>77 ,78
LGPLかGPLで扱いが変わって来るはず。
glibcとリンクしただけで全てのプログラムが公開されなければいけないなら、
Unix系で商用ソフトなんて作れなくなるよ。
>>81 再配布条件と利用条件は区別して考えてる?
作ったプログラムを公開しないのであれば、何もUPする必要は無いよ。
>>83 鵜呑みしないで疑っているからここにいるわけで
87 :
デフォルトの名無しさん :2008/07/18(金) 16:33:35
[1] 授業単元: プログラミング [2] 問題文(含コード&リンク): 配列の要素を昇順にソートしたときの、添え字の順番を配列に記憶するプログラムを書け。 data = {2,6,3,1,2} なら, index = {3,0,4,2,1}である。 元の配列は書き換えてはならない。 qsortなどのライブラリを用いて構わない。 [3] 環境 [3.1] OS: Windows [3.2] コンパイラ名とバージョン: gcc [3.3] 言語: C C++ [4] 期限: 明日
88 :
デフォルトの名無しさん :2008/07/18(金) 16:52:11
誤爆しました・・・
そいじゃ、誤爆で int [] data = { 2, 6, 3, 1, 2 }; int [] index = data.Select((a, i) => new { a, i }).OrderBy(x => x.a).Select(x => x.i).ToArray();
90 :
デフォルトの名無しさん :2008/07/18(金) 20:53:48
>>84 回答ありがとうございます
実装への直接的なアクセスをできないようにすることで
実装については変更させず、他の部分のみ変更可能にする
ということなのですかね
Effective C++も探して読んでみます
91 :
デフォルトの名無しさん :2008/07/18(金) 21:44:50
>>71 だなあ。
結局unsignedのメリットって1bit表現範囲が広がるくらい?
unsignedだとオーバーフローで鼻からなんか発生しない。
>>91 signedな整数は符号拡張がウザいこともあるし
ビット演算や何かとの相性も良くない
まあ、適材適所で使い分けろ
いつ誰がsignedに書き換えるかわからないんだからそこはちゃんと比較しとけよ 本当にunsignedなら最適化してくれる
そうですよね いつ誰が構造体に書き換えるかわからないですもんね
なんでこれで while( *d++ = *s++ ) 文字列コピーできるんですか?
while(( *d++ = *s++) != 0)
演算子の優先度が分からないのか、ポインタのインクリメントの意味が分からないのか
102 :
デフォルトの名無しさん :2008/07/19(土) 20:21:47
std::vector<CTest> hoge; void testFunc() { for(int i=0; i<10;i++){ CTest test; test.i = i; hoge.push_back(test); } } int main(){ testFunc(); for(int i=0; i<hoge.size();i++){ printf("%d\n",hoge[i].i); } こんなことしても問題ありませんか?一応表示はされたのですが。 std::vector<int>とかはそのまま数値いれてますけど、 std::vector<クラス>の時もnewしないで入れても平気なのかなって思いまして。
CTestの実装による push_back内でnewしてコピーしてるのでnewはいらない で、そのコピーのときにCTestのコピーコンストラクタでメンバのコピーがされる デフォルトコピーコンストラクタでも問題ないなら特にコーディングしてなくてもおk デフォルトコピーコンストラクタじゃだめなら自分で書く必要あり
104 :
デフォルトの名無しさん :2008/07/19(土) 20:38:08
なるほど。ありがとうございました。
105 :
デフォルトの名無しさん :2008/07/19(土) 21:04:33
Cを書いてるとエディターの機能で色分けしてくれて表示 されるのは便利なのですが、さらに進んで ある行にカーソルを置くとどういう階層のとこに いるかって機能がついたエディタとかってありますか? 例 main() { if(a==1) { while(b>1) { … if(c==0) { ここ } } } } 「ここ」にカーソルを置くと main()->if(b==1)->while(b>1)->if(c==0) みたいに表示されるやつ
それを見たくなるってのは、もしかして、 1つの関数に詰め込みすぎのサインだったりするんじゃないかな。
「そういうコードは書かない方がいい」じゃだめですか
関数の形でかかれているものを問答無用でインラインに展開する方法があればいいな、と思うのですが。
VCにそんなオプション有った気が
>>108 思うだけにしておいたほうがいいと思います
>>108 闇雲にインライン展開しても速くならないんだな。
>>105 1画面に収まらない関数は書かないのが鉄則ですう
そんなこといっても行数が増えてくると 関数呼び出しだけでも一画面におさまんなくなって 便利な機能な気がするけど… ウィンドウプロシージャとかでかい関数はどうしてもできるわ(´・ω・`) 一つのファイルにいっぱい関数詰め込むととか あとアルゴリズムを激しく書く人はいる気がする。 何千行ものコードを一画面に収まるくらいに 分けたら関数出来過ぎ君だわ なんかおれ必死な感じだけど、便利な気がするけど… ないってことは作るしかないんかな。
ウィンドウプロシージャをCで書くならメッセージクラッカ必須だろ。
>ウィンドウプロシージャとかでかい関数はどうしてもできるわ 出来ねぇよ、関数分けろ
ファイルで分割しても二桁とか
>>713 OK,読み間違えてた
ダイビング土下座しながら吊ってくる
誤爆
>>115 inlineにしててもインライン展開しないこともあるんだったよな確か?
121 :
デフォルトの名無しさん :2008/07/20(日) 02:50:40
なるべく最新版のやつで最適化するしかないよ マクロにすれば確実にインラインになるけど、デバッグが困る
>>120 inlineにしなくてもインライン展開されることもあるしね。
クラッカ使ってないな そういうのあるんだ 古い人だから#defineとか いっぱい使うとわかんなくなるから カーニハンとリッチーだっけ? あれの本だとcはシンプルで なんとかってのってたけど いいねそれ。 ただ今の時代では違うのかもだけど。 とりあえず今1万7千行くらい switchcase文がいっぱいあるわ。 c標準のデータ型以外は 最低限のやつしかwindows.h系のは 使ってない。 でも昔よりは関数で分けるようになったかも
>分けたら関数出来過ぎ君だわ それくらいがむしろ普通
ウィンドウプロシージャには 関数分けするためのマクロが用意されているくらいなのにな。
VCでマルチバイトというとUTF-8、UNICODEというUTF-16ですよね? SJISで作ったテキストファイルも普通に読み込んでいると思うのですが何故でしょう?
マルチバイトというと(一般的な日本語Windows環境では)CP932だと思うが。
CP932、ググるSJISの拡張ということで互換性あるのかな どうもUTF-8だと思ってたのは勘違いのようですね 文字コードってユーザーとして意識したことないから難しい...
あるよ。井戸の外には
「愚かな一貫性は小人物に憑いたおばけである」 という言葉があってのう
1画面なんて言われたら、250桁×100行でも許容しろってことかよ。 冗談じゃねぇ。
133 :
デフォルトの名無しさん :2008/07/20(日) 13:49:48
分かり易ければ1画面に収まる必要まったくなし こだわってるやつはたいてい頭悪い
>>132 1600x1200?w
寧ろ、3分割して80桁x300行とか嫌そうだw
A4一枚とかはよく見聞きする話
明日から7ptフォントで開発しとけよ。
初心者には一画面以内 must で教える 上達したら一画面越えてもいいよと教える
マクロで質問です。 #pragma message("hogehoge") をマクロにしたいんですが... 次のやり方でコンパイラが怒ります...。 #define _message( str ) #pragma message( str ) どう登録すれば良いんでしょうか?
139 :
デフォルトの名無しさん :2008/07/20(日) 14:22:41
プラグマをマクロにした例はみたことないなぁ できないんじゃないの?
できないよ。
だからC99で_Pragmaが追加された。 VC++も2008から__pragmaという名称で同じ機能を用意している。
プラグマをマクロ化って。 誰が得するんだ…。
>>142 処理系によってプラグマの書き方が異なる場合
>>143 いや理論的にはそんなんだけど、俺の未熟な経験からは
使った方が便利だってケースが思い当たらない。
そんで誰が得するのかな、と。
>>144 処理系A #pragma align packed
処理系B #pragma pack(1)
だとすると、構造体の定義のたびに、
#if defined(_IMPL_A)
#pragma align packed
#elif defined(_IMPL_B)
#pragma pack(1)
#endif
struct S {...}
#if...さらにアライメントを元に戻すpragma
と書かないといけない。
さらに処理系C #pragma options align=packed
を追加したくなったら、もううんざりだ。
includeでやるのはどう?
>>146 うん。実際そうやってた。
でも美しくないんだよねえ。構文的に
VC++2005EEで作成しています。 有る関数の中でループを毎に乱数を発生させ、配列に値を保存させようとしたのですが 実行画面では同じ数値に成ってしまいました。デバックをしてみたところ @1から見ていくと、配列にちゃんと違う数値が入っていき、ループを抜けた @2までみても違う数値が保存されていました。 @2にブレークポイントを設定し、そこで値を確かめるとListの値には 同じ数値が配列に保存されていました。 全て値がう値が保存されている様にしたいのですが、何が問題になっているのか見当がつきません。 何か対策とかあるのでしょうか srand( (Uint32)time(NULL) ); m_Tmp = new Object(); @1 for ( Uint32 i=0; i<MAX; ++i ) { m_List.push_back( *m_Tmp ); m_List[i].SetNum( rand() % 10 ); } @2 ※SetNumは与えられた値を保存させるだけのメソッドです。
STLのstd::vector<int>とか使ったらいいとおもうよ。
m_Listは std::vector<Object> m_List;で宣言してあります。
Object()のコピーコンストラクタとか、どっか実装がおかしいんじゃね?
153 :
デフォルトの名無しさん :2008/07/20(日) 17:27:51
>>149 ちょwww
これはだめでしょ
Object は最初に1回 new しただけでしょ?
そこに値をどんどん入れて行ったら、当然同じインスタンスに値をどんどん突っ込むわけで、
最後には、一番最後に代入した値ばっかりのリストになるよwww
>>149 Object の定義が怪しい。 SetNum の値をポインタの先に保存してて、 Object のコピーでは
ポインタがコピーされてるとか。
>>153 push_back(*m_Temp) だから、そこが問題じゃないでしょ。
済みません。事故解決しました。 SetNumで違う変数に値を保存してました。お騒がせしました orz
156 :
149 :2008/07/20(日) 17:30:23
そっか、push_back でコピ^コンストラクタが動くのか、 じゃあ152が正しいか。
現在自作ゲームで文字の時間差表示をしようとしているのですが、 string script="abcde"; string strbuf=""; int moji=0; for(int i=0;i<script.size();i++){ strbuf+=script[moji]; //ここでstrbufの内容を表示 //ここにwait処理が入る moji++; } strbuf=""; moji=0; scriptの中身が1バイト文字だと正常に表示されるんですが、 2バイト文字だと文字の背後に・(黒点?)が表示されてしまいます stringは2バイト文字は使えないんでしょうか?
wstringとか
マルチバイト文字列用のルーチン使って文字を切り出すか、UTF-16をつかう。 おそらくstd::stringで1バイトづつ出力させてるんだろうけど、それやっちゃうと2バイト文字は半分ちぎれたりするから正常に表示できない。 ちゃんと2バイト文字は2バイトづつ出力させるか、2バイト固定のUTF-16使えばOK。 荒技としては逆に1バイト文字を使わないという手もある。(全角数字、全角アルファベット、全角記号で代用)
なるほど、要はscript[moji*2]とかループを1/2回にするなり 数字は全角で書くなりすれば良いわけですね ありがとうございます
>>159 UTF-16だから2バイト固定なんてことが許される時代はもう終わっているよ。
サロゲートなんて捨ててOK
C/C++って、マルチバイト文字の、先頭か二番目以降かって判定する関数なかったっけ? 標準でなくても、それぞれのプラットホームには必ずあると思うけど。
[゛], [゜] も捨ててかまわないってことで。
>>163 そんなレガシー技術に頼るぐらいならUnicodeにしとけよ
UTF-8では先頭バイトと後続バイトはMSB側の2bitを見るだけで簡単に区別できるし
先頭バイトだけで後続バイト数は判断できるし
後続バイトがASCII文字と重なるようなこともない
マルチバイト処理は必要だが、レガシーなエンコーディングスキームよりは
ずっといい性質を持っている
168 :
166 :2008/07/20(日) 23:04:30
補足。
euc-jpやiso2022系では、「lead byteかどうか」は特定の2バイトを見ただけでは
判断できない。
行頭なり何なりから順番に舐めるしかないはずだよ。
>>163 の言っているような"iskanji"風のレガシーなクソマクロは、特定の条件でしか
役に立たないものだ。
>>168 先頭から見ないとわからないってのは、EUCのほうじゃなくてShift JISのほうでは?
なんで文字コードごときの話でそんな偉そうにできるんですか?
>>170 皆、思い思いに書いてるだけだよ。
偉そうに見えるのはおそらく・・・
>>169 EUCで簡単なのは1byteコードと2byteのコードの識別だけで、
lead byteとtrail byteの識別は難しいのでは?
入出力(ファイル、パイプ)はともかく、 内部コードにUTF-8, UCS2, UTF-16, UTF-32以外を使うのは止めておけ。 マジで。
wchar_tはC/C++の定義上1文字なので、 固定サイズであるUCS2/UTF-32と考えるのはそれほど問題でないが、 可変サイズであるUTF-8/UTF-16として扱うのは完全にNG
VC++で、ソースコードをUTF-8で保存してコンパイルしたら、"文字列" がUTF-8になってくれればいいんだけどね
VC++(UCS2)/gcc(UTF-32)での可搬性を考えると、 wchar_t=UCS2と想定するのが良い UTF-16、UTF-32はC++0xが出てくるまで我慢
177 :
176 :2008/07/20(日) 23:53:11
もちろん、ICUなどで提供されている型や関数を使っている人は除く
どーでもいいよそんなの
printf("aaa\b\b\b"); とかやってるコードを見かけたのですが、 \b\b\bはどういう意図でやっているのでしょうか? \bはバックスペースのようですが…
次に書いた文字がaaaを上書きする。
182 :
180 :2008/07/21(月) 14:40:00
>>181 さんありがとうございます。
ファイルコピーの進捗状態をコンソール上の同じ位置で
パーセント表示する際などに
使うわけですね。なるほど。
char *p; char **pp = malloc(sizeof(char*) * 100); という式はcharのポインタのポインタを100確保したという意味でいいのですか? pp[0]はpと同じ意味ですか?
char*を100個格納できるエリアへのポインタを返していて、そのポインタをppに入れている あくまでも指定されたサイズのエリアを確保しているだけで、ポインタを確保している訳ではありません。 上記コード上ではpとpp[0]には何の関連もないけど、 p = pp[0];ができる?という意味なら、できる。
>>184 同じ意味とは型が同じかという意味でした。
VCで作ってタソーすをgccでコンパイルしようとすると tchar.hがないってエラーになるんだが、 Linuxでは何てヘッダを読み込めば_TCHARとか_T()とか使える? 自分で定義するしかない?
当たり前だ
そのための_TCHARだ。
gcc だと何と定義すりゃいいんだろうな。 wchar_t が UCS4 だったりすることもあるんじゃないのか。
そもそもAPIにAとWの区別もないのに何の意味があるんだろう。
>>189 UCS2でも4でも動くように書くしかないかと
あるいはライブラリを使うか
wchar_tの中身がUnicode系ではない環境もあるのでよろぴこ。
>>194 その処理系の名前教えて。
いや、煽りとかじゃなくて普通に知りたいので。
>>195 Linux以外のほぼすべてのUNIX。
すくなくとも、Solaris FreeBSD NetBSDはUnicodeではなかったはず。
そうなのか。dクス
LinuxをUNIXと言うと基地外が来襲するので ちゃんとUNIXライクOSと言いましょう
その辺に載ってる話はさすがに古くねえか? gcc 2.xだろ?
gccのwchar_tは昔からうんこ あまりにも有名すぎる話
>>201 いやその、今のgccはinput-charsetだのexec-charsetだのwide-exec-charsetだの
指定できるだろ?
*i |= 3; はちゃんと *i = *i | 3; に展開されるのでしょうか?
いいえ、前者と後者では意味が違います。
>>203 「展開される」の意味が分からない
Cだと結果は動作は等しくなる
C++だとoperatorのオーバーロードがあるのでなんともいえない
class test { string* p; public: test() { p = new string; } ~test() { delete p;} } main() { test obj1; test obj2 = obj1; } 2度目のdeleteにてセグメンテーション違反で落ちるコードです 教科書ではコピーコンストラクタを上書きして ポインタの指す先までコピーするようにしてるのですが delete時にチェックする方法はあるんでしょうか? 実用性は考えていませんが、興味があります 環境: Linux kernel 2.6-686 GNU C++ compiler 4.1.1
ローカル変数とは定義された順にスタックに積まれるのですか?
>>206 obj2.pはobj1.pと同じだから落ちて当たり前。
何がしたいのか分からないけど、ポインタにNULLポインタを入れておけば
それがdeleteされても問題なく動く。
>>206 > delete時にチェックする方法はあるんでしょうか?
参照カウンタをどこかに持つとか。
あー、参照カウンタにしても、けっきょくコピーコンストラクタをオー バーライドしなきゃいけないか。
>>208 どこでNULLをセットすればいいですか?
>>209 なるべく簡単な方法がいいんですよね
catchしちゃえばいいのかな
このアドレスは使っちゃ駄目みたいなのは
カーネルに聞けば教えてくれるのかなと思ったんですが
>>206 あくまでチェックしたいってことなら、方法は無い。
ヌルをセットするとかして、とにかく落ちないようにするなら auto_ptr でも使っとくのが簡単。
#include <memory>
#include <string>
using std::string;
using std::auto_ptr;
class test {
auto_ptr<string> p;
public:
test() : p(new string) {}
};
int main() {
test obj1;
test obj2 = obj1;
}
>>207 規格ではスタックが使われるのかすら決まってなかった気がする
>>211 string*ではなくstringをメンバに持たせる
215 :
デフォルトの名無しさん :2008/07/23(水) 16:25:27
class hoge{ private: int fuga; public: void setfuga(int a){ fuga = a; } int getfuga(){ return fuga; } }; class foo{ private: std::vector<hoge> var; public: void sethoge(hoge hage){ var.push_back(hage); } std::vector<hoge> getvar(){ return var; } }; int main(){ foo foo0; hoge hoge0; hoge0.setfuga(1); foo0.sethoge(hoge0); std::vector<hoge>::iterator itr; itr = foo0.getvar().begin(); std::cout << foo0.getvar().at(0).getfuga() << std::endl; std::cout << (*itr).getfuga(); return 0; } これを実行すると、一つ目のcoutは正常に出力(1)されますが、二つ目はでたらめな値が出ます。 itr = foo0.getvar().begin()はfoo0.getvar().at(0)を指すiteratorだと思うので、同じ結果になると 思っているのですが…。どなたかお教えいただけると助かります。
>itr = foo0.getvar().begin(); getvarの戻り値はfoo0.varそのものではなくfoo0.varの一時的なコピーで、次の文に移る前には破棄される getvarはfoo0.varのコピーを返すのではなくfoo0.varへの参照を返す必要がある
217 :
デフォルトの名無しさん :2008/07/23(水) 16:38:55
>>216 その通りでした。ちょうど思いついたところでした。
すみません、どうもありがとうございます。
HOGEという構造体がtypedefされているとします。 HOGE *hoge;と宣言します。 void function(HOGE *hoge){ }という関数に function(hoge)と渡すと参照渡しになってますか?
>>218 それはC++でいうところの参照ではありません
アドレス私ですか?
?
アドレス渡しですか?の間違いです
「自分宛のレスですか?」という意味だと勘違いしたのは、 俺だけじゃないはず。
foo(HOGE fuga){ } bar(HOGE* pFuga){ } baz(HOGE& fuga){ } func() { HOGE hoge; HOGE *pHoge; // 値渡し foo(hoge); // ポインタ渡し(アドレス渡し) bar(pHoge); // 参照渡し baz(hoge); }
foo(HOGE fuga) foo(HOGE &fuga) HOGE hoge; foo(hoge); この場合どっちが優先されますか?
自分で試してください。 俺は試しました。VC++2005EE XXX.cpp(19) : error C2668: 'foo' : オーバーロード関数の呼び出しを解決することができません。(新機能 ; ヘルプを参照) XXX.cpp(11): 'void foo(HOGE &)' の可能性があります。 XXX.cpp(7): または 'void foo(HOGE)' 引数リスト '(HOGE)' を一致させようとしているとき
もし環境依存だったら自分で試しただけでは分からないし
それは試してうまくいった後に質問すべきこと。
230 :
デフォルトの名無しさん :2008/07/23(水) 22:08:24
g++でプリコンパイル済みヘッダが使えないって聞いたんだが、 stdafx.hみたいに一つのヘッダファイルでSTLやboostとかのヘッダ 全部読み込むのはやめたほうがいい?
いつのg++の話?
232 :
デフォルトの名無しさん :2008/07/23(水) 23:54:09
>>224 225は自分じゃないです。
ポインタ渡しした場合はbar関数の中で値を書き換えても、元には影響ないんですか?
>>232 ポインタを引数に指定しないとだめか、そうでないかの違いで、影響あることには変わりないよ
225は違う人だったのか… ポインタ渡しは影響する 参照渡しも影響する 値渡しだけは影響しない
クラスは参照型なのでゴニョゴニョ
>>232 bar(HOGE* pFuga){
*pFuga = ...; //影響する
pFuga = ...; //影響しない
}
>>230 そういう理由もあるだろうし、依存関係は最小限にしたほうがいいと思うよ。
g++ でもプリコンパイル済みヘッダ自体は使えたような気がする。使い方が
全然違ったはずだけど。
あれ? クラスもコピーコンストラクタ呼ばれて値渡しされるよね?
240 :
デフォルトの名無しさん :2008/07/24(木) 13:39:58
コピーコンストラクタ呼ばれて値渡しされるし、逆にコピーコンストラクタが定義されていないと コンパイルできないはず
241 :
240 :2008/07/24(木) 13:42:25
値渡しの話だよね?
コピーコンストラクタがなければ勝手に丸ごとコピーします。 でないと、struct A a, b; a = b;というC由来のコードがコンパイルできなくなってしまう。
243 :
240 :2008/07/24(木) 13:44:40
あ、そっか、そうだね、失礼
244 :
240 :2008/07/24(木) 13:47:05
あ、よくがんがえたら、クラスのメンバーに、コピーコンストラクタが定義されていないオブジェクトが含まれている時と 勘違いしてた。 自分がよくコンパイルエラー出すもんで。。w
実際 中間インスタンス生成+コピーコンストラクタ呼んだ後は 参照でわたしてる? 呼び出し元のインスタンスには影響を与えないけど、スタックに実体を積んでいるわけではない みたいな構造
それぞれ想定している状況が違っている悪寒。
247 :
デフォルトの名無しさん :2008/07/24(木) 13:55:27
VC2008 VC6 BCC MinGW でboostいれたいんですけど バイナリ配布しているVC2008しか成功しません 1.35のそれぞれのバイナリ置いてある所無いですか?
248 :
デフォルトの名無しさん :2008/07/24(木) 14:17:41
darwinってmacのことだぞ
boost::regex で,置換する時に置換フォーマットが $10 だと 10 番目のキャプチャ要素に置換されるんだけれど, これを一番目のキャプチャ要素 $1 + 0 にするにはどうしたらいいの?
すいません 2 回呼ぶと言うのはどういう意味でしょうか?
${1}0でいけたような気がしたけど、どうだったかなあ
1.35のregexでいまためしてみた。 "\\10"で大丈夫。sed format string syntaxってやつだ。 "${1}0"はだめ。 #include <iostream> #include <string> #include <boost/regex.hpp> int main() { boost::regex re("(.)(.)(.)(.)(.)(.)(.)(.)(.)(.).*"); std::string s ="abcdefghijklmn"; std::cout << boost::regex_replace(s, re, "\\10") << std::endl; return 0; }
そういう意味か!
257 :
250 :2008/07/24(木) 20:38:51
258 :
デフォルトの名無しさん :2008/07/25(金) 10:23:37
boost_serializationを画面やメモリに出力したいのですが教えて下さい test_classは別に定義してあるとします。これだとファイル出力です #include <fstream> #include <string> int main() { std::ofstream fp("XXX.xml"); boost::archive::xml_oarchive oarchive(fp); test_class Z; Z.a = 22; Z.b = 7; oarchive << boost::serialization::make_nvp("Root", Z); }
>>258 よくわからんが
ofstreamのかわりにcoutやsstreamを使えばいいだけなんじゃないの?
260 :
デフォルトの名無しさん :2008/07/25(金) 10:35:02
追記 型 const boost::serialization::nvp<T>の出力方法がわかればいいのですが
261 :
デフォルトの名無しさん :2008/07/25(金) 10:36:58
トンクス これでいけました! xml_oarchive oarchive(fp); → xml_oarchive oarchive(cout);
262 :
デフォルトの名無しさん :2008/07/25(金) 10:41:06
メモリに格納したいのでstringにしたらエラーでました。 メモリに入れる良い方法ありませんか? string s; boost::archive::xml_oarchive oarchive(s); 1番目の引数を 'std::string' から 'std::ostream &' に変換できません。
264 :
デフォルトの名無しさん :2008/07/25(金) 10:50:32
トンクス
参照を使うべきかポインタを使うべきか悩んでいるのですが、 参照なんて使わない!もしくはできる限り全て参照を使う!って方いますか? どうもポインタと参照の違いが分かりません(使いどころとして)
>>265 C++では、ポインタを使わないといけないケース以外はポインタを使わない。
使うとしても、大抵はイテレータと言う形で使っている。
必要に迫られれば、ポインタを使うこと自体は吝かではない。
C++だと関数にヌル終端文字列を渡すときも、const char * とか使わず、 全て const char & とか const std::string & を使うの?
const char & を渡してどーすんだ
俺は、参照を使わざるを得ないときと、値渡しの代わりとしてコピーのコストを抑えるためにしか、参照を使ってないな それ以外はポインタ
void test(const char& s){ if(&s==NULL){ std::cout << "(NULL)" << std::endl; } else{ std::cout << &s << std::endl; } } int main(){ test(*"aaa"); test(*static_cast<const char*>(NULL)); return 0; } --結果--- aaa (NULL) 扱えないことはない。 でもまぁ正直言って、これはないw
271 :
265 :2008/07/25(金) 14:12:35
値渡しのコピーを省くためなら、参照でなくともポインタでできそうですけど、 それをわざと参照でやる理由はなんでしょう? c++まだ勉強中で、ざっと見た感じ、以下のようなものしか有用性はないような気がしてます。 ポインタでの煩わしい明示を省ける、視覚的に区別する以外のメリットはあるのでしょうか? int n; int &func(); void main() { int i = 0; func() = i; } int &func() { return n; }
ポインタは参照と違ってNULLを渡すことができるらしいよ。 参照はポインタと違っていい一般保護例外を起こすようなアドレスを排除できるらしいよ。
>>271 少なくともread-onlyな引数を、効率のためにconst参照渡しがしたいケースなら、
素直にreference使ったほうが便利だよ
>>272 の言うような問題もないし、呼ぶ側としても
ただの値渡しと同じように記述できて、型変換や何かが必要な場合もコンパイラが面倒
見てくれるからな
ユーザ定義演算子などでは、意図した記法を実現したければ、
事実上参照以外に選択肢が無いこともある
>>272 やってやれんことはないな
void hoge(double &d) { }
hoge(*(double *)NULL);
hoge(*(double *)123);
>>271 const参照になるけど、
・良いかどうかは別にして、コンストラクタの暗黙呼び出しが使える。
・一時オブジェクトが渡せる。
という利点はある。
struct IntX {
int n;
IntX():n(0){}
IntX(int argn):n(argn){}
};
void test(const IntX& a){
std::cout << a.n << std::endl;
}
void test2(const IntX* a){
std::cout << a->n << std::endl;
}
int main(){
test(IntX());
test(10);
//test2(&IntX(20)); //左辺値でないのでコンパイル不可
return 0;
}
あと、
>>272 がツッコミ入れてくれた通り、
>>270 で書いた *static_cast<const char*>(NULL) みたいなネタは
実際のプログラムでやったら(無効な参照を作ったら)駄目だからね。
276 :
265 :2008/07/25(金) 14:47:48
ふむふむ、なるほど。よく分かりません\(^o^)/ もう少し理解を深めてから出直したいと思います。
このスレか別のスレかわからないが最近同じネタをやってて、 参照が追加になったのは演算子のオーバーロードやコピーコンストラクタで 必要に迫られたからということらしい。 通常では戻り値はいいとして引数で使うと変数の変化が追いにくくなるので 多用はしないということだった。
278 :
265 :2008/07/25(金) 14:55:17
C++の機能拡張に合わせて追加された、ということでしょうか。 同じネタが上がるということは、同じ疑問を持つ人がいるということですかね。 オーバーロードやコピーコンストラクタのあたりも見直してみます。
>>274 その場合は呼び出し元に問題があることが確定するのが、参照にしとく利点になるかな?
ポインタだと、渡された側でヌルチェックすべきかどうか気になってしまう。
>>276 まだ勉強中って書いてあったね、ごめん。
慣れるまで、参照でなければならない箇所以外は
ポインタで良いと思うよ。
たぶん、経験が自然に教えてくれる。
281 :
デフォルトの名無しさん :2008/07/25(金) 14:57:42
hoge(*(double *)NULL); こんなん落ちないの?
落ちると思って良い。 ちなみに言語規約違反な。
間違った。規約じゃなくて規格。
C++でC言語のキャスト使うのやめれ
そういうときは未定義動作っていうんだ。コンパイルはできちゃうからね。
#define NULL reinterpret_cast<void*>(0)
BCCでの質問です。 ファイル間のインクルードの関係が以下の時、変更してないファイルも毎回コンパイルされるんですが回避策ってありますか? A.h B.h(include A.h) A.cpp(include A.h) B.cpp(include A.h,B.h) オナがいします。
>>287 ヘッダを変更しなければいいだけじゃないの?
289 :
デフォルトの名無しさん :2008/07/25(金) 17:31:40
C言語勉強中なのですが、理由が知りたいです。 簡単なプログラムなのですが、回答よろしくお願いします void hogefunc(char *); void main() { char a[256] = "abc 0001"; hogefunc(a); } void hogefunc(char *tmp) { char b[256]; strcpy(b,tmp); } ////////////// デバッグを行うと、bの中身が"abc"のみでaの中身"abc 0001"が文字列コピーできていません。 予想だと、aの中身とbの中身は同じになると思ってました。なぜ0001が切られたのでしょうか? よろしくお願いします
290 :
289 :2008/07/25(金) 17:34:42
全て打つ前に転送してしまいました・・ このプログラムの場合、aの中身とbの中身を同じにするにはどうすればいいでしょうか?
そんなはずがない。なんかの見間違いなんじゃないか
void hogefunc(char *); void main() { char a[256] = "abc 0001"; hogefunc(a); } void hogefunc(char *tmp) { char b[256]; strcpy(b,tmp); printf("%s",b); } で試したけどちゃんと表示されてました
>>287 どうやってコンパイルしてる?
make 使ってるのなら makefile 見せてみ
"abc 0001" ^ 実はこれが\0というオチを予想
>>288 ,294
どうやらファイル名が長すぎるのが原因のようでした。
最小限の再現作ってたらincludeのみのヘッダファイルが二個だけになったので^^;
297 :
デフォルトの名無しさん :2008/07/25(金) 19:11:07
一様乱数を生成する関数のソースについて質問があります。y=1/sqrt(2)*exp(-1/2*x*x)の計算で In function `GaussRandom':: undefined reference to 'sqrt’と In function `GaussRandom': : undefined reference to `exp'というエラーがでて実行できません。もちろん<math.h>は定義しました。 レポート課題なのでマジで困ってます。是非教えてください。ソースを下に載せておきます。 ちなみにxが一様乱数で、yが正規乱数です。 double GaussRandom() { double x; double y; x=UniformRandom(); y=1/sqrt(2)*exp(-1/2*x*x); return y; } double UniformRandom() { double x; int r=1; r=1229*r+351750; x=r/1664501; return x; }
>>289 変数寿命が切れてるから上書きされているんじゃないの?
クラス内の関数ポインタでつまづいた。 分からない、全然分からない。 どこが分からないのかすら分からない。
普通の関数ポインタはわかるのか? じゃあメンバ関数ポインタでぐぐるんだ
ええ、それで調べているんですけど、どうしてこんなに難解なのかと小一時間(ry 関数ポインタをメンバに含めると初期化できませんよね?こんな風に void (*pf[])() = {hoge, piyo, foo}; もう普通に関数にした方がいいのかな……。
オーバーロード演算子関数のポインタって取れないんですか? X (*f)(X &, X &) = +; X (*f)(X &, X &) = &+; X (*f)(X &, X &) = ::+; X (*f)(X &, X &) = &::+; X (*f)(X &, X &) = *::+; X (*f)(X &, X &) = operator +; X (*f)(X &, X &) = &operator +; X (*f)(X &, X &) = &::operator +; とか色々試したんですが「;が足りません」だの「operatorの位置が不正です」だのなんだの 構文に文句付けられて通りません 取り方があれば教えて下さい
それってただの関数ポインタじゃないか?
>>303 これでいけたぞ
#include <stdio.h>
struct X{}x;
X operator+(X&, X&){printf("x");return X();}
int main(){
X (*f)(X&, X&) = operator+;
f(x,x);
}
>>302 #include <stdio.h>
class A{
static void (A::*pf[])();
public:
void hoge(){ printf("hoge"); }
void piyo(){ printf("piyo"); }
void foo(){ printf("foo"); }
void call(){ for(int i = 0; i < 3; i++) (this->*pf[i])(); }
};
void (A::*A::pf[])() = { &A::hoge, &A::piyo, &A::foo };
int main() {
A().call();
}
俺には解読不能な文字列が多すぎて、目眩がしそう。
308 :
デフォルトの名無しさん :2008/07/25(金) 21:24:13
質問があるんですが,C++プログラムの変数の中に入っているデータをJAVAで取得することは可能なんでしょうか? データベースやファイルに書き込むなどの方法を取らずに、出来る方法があれば是非知りたいです。
Javaって他のJavaプログラムの変数の中のデータを取得することできるの?
>>306 ありがとうございます。
あとはゆっくり中身を理解したいと思います。
>>310 普通にclassファイルがあれば、望みは全て叶うでしょう。
実行中のプログラムとかCORBAとかその他みたいなプロセス間通信の事を言っているのなら、そういうインターフェースを自分で作ってください。
>>297 #include <math.h> と書いてありますか?
手元のコンパイラで試しますので、全文をどこかにアップロードしていただけますか?
ビット演算で文字列中の大文字を小文字にしようとしてるのですが一文字目は出来ますがふた文字目以降ができません。 この場合ってループで回して一文字ずつ処理するしかないんですかね?
>ビット演算で文字列中の大文字を小文字にしようとしてる 言ってる意味が分からないのでソースで。
str |= 0x20; としか・・・
OK、では次はこれをソースで。 >のですが一文字目は出来ますがふた文字目以降ができません。
OKってようするに、わからないなら答えなくっていいです。 ソースだせソースだせってわからないだけでしょ?それをソースだせって馬鹿なの?
ソースが無くてトンカツが食えるか!
w
1レス目でソース出してれば1レスで問題点が返ってくるレベルと予想
文字列がマルチバイトを含まないことを祈るばかりです。
一文字目は出来てる
>>316 さんがマルチバイト文字くらいで困るわけ無いじゃないか
326 :
デフォルトの名無しさん :2008/07/26(土) 12:59:33
>>309 JNIを調べて試してみましたが,自分の場合は使えなさそうです.
JAVAソースを書いて→ヘッダー作成→C++ソース作成
という順序のようですが,今の状態ではC++ソースとJAVAソースが全然別のアプリケーションとして完成していて,
C++アプリで使っているデータをJAVAで扱いたいという事なんですが…。
C++でデータを自分自身のIPに送って,JAVAでそれを取得するというのを今考えているんですが….
テキストファイルに書き込む→読み込む
自前でシリアル化して通信すれば
>>10 (2)だと、クッキーの設定はちゃんとしてるのに書き込み確認画面のまま止まってる。
つまりクッキーの設定がうまくいってないみたいなんだが、デバッガで文字列を確認してみても正常だし
そのデバッガで確認した文字列を手動で書いて送信するとうまくいく。
すみません誤爆しました。
331 :
デフォルトの名無しさん :2008/07/26(土) 14:00:26
>>327 それでも一応可能なんですが,
取得したデータに対応した動きみたいなモノを作らないといけない為,
JAVA側でテキストファイルをずっと参照し続け,更新があった場合○○する.
といった風な感じになってずっと参照し続けるというのが気持ち悪いから避けたいんです.
>>326 プロセス間通信とか、XMLでシリアライズしたのを渡すとか。
1〜10までの偶数を書き出すプログラムでもっと簡単なコードがあったら教えてください。 自分で書いたのは↓です。 #include <iostream> using namespace std; int main() { int i; cout << "1〜10までの偶数を出力します\n"; for(i = 1; i <= 10; i++){ if(i % 2 == 1){ continue; } cout << i << "です\n"; } return 0; }
for(i = 2; i <= 10; i+=2){ cout << i << "です\n"; }
335 :
デフォルトの名無しさん :2008/07/26(土) 14:58:06
for(i = 1; i <= 5; i++) cout << 2*i << "です\n";
cout << "2, 4, 6, 8, 10です\n";
ウケタw
そんなに面白くはない
340 :
デフォルトの名無しさん :2008/07/26(土) 15:08:35
↓次の方どうぞ
繰り返し文を利用して ☆ ☆☆ ☆☆☆ ☆☆☆☆ ☆☆☆☆☆ と表示させるコードを書いてみたのですが、もっと簡単に書く方法ありませんか? #include <iostream> using namespace std; int main() { int i; for(i = 1; i <= 5; i++){ if(i == 1){ cout << "☆\n"; } else if (i == 2){ cout << "☆☆\n"; } else if (i == 3){ cout << "☆☆☆\n"; } else if (i == 4){ cout << "☆☆☆☆\n"; } else if (i == 5){ cout << "☆☆☆☆☆\n"; } } return 0; }
ひょっとしてそれはギャグで言っているのか?
普通の小学生ならカウンタの値と☆の数に関連性を見出せる筈
>>341 cout << "☆\n☆☆\n☆☆☆\n☆☆☆☆\n☆☆☆☆☆";
>>341 そこはif文じゃなくて、switchで場合分けするべきだと思うんだ。
346 :
デフォルトの名無しさん :2008/07/26(土) 15:42:47
>>345 いやswitchにしてもまだおかしいだろwwww
少し考えるので時間ください
hoshiHyouji(size_t nannko)という関数を作ればいいんじゃに
関数はまだ習ってないのでわからないです。 #include <iostream> using namespace std; int main() { int i; int j; for(i = 1; i <= 5; i++){ for(j = 1; j <= i; j++){ cout << "☆"; } cout << '\n'; } return 0; } これでも同じように表示されたましたけど 考え方はあってますか? それとも、もっと簡単な方法があるのでしょうか?
あってると思うけど 個人的に for(i = 0; i < 5; i++){ for(j = 0; j < i; j++){ の方が好き
>>350 なるほど0からのカウントですか。
もっと分かりやすいコードが書けるように頑張ってみます。
>>349 そこは繰り返しじゃなくて再帰を使うべきだな。
void print_hosi(int num);
void print_hosi(int num)
{
if ( num <= 0 ) { return; }
for ( int i = 0; i < num; i++ ) { cout << "☆"; }
cout << endl;
print_hosi( num - 1 );
}
>>350 すいません、自分が指摘するのはあれなんですが
☆
☆☆
☆☆☆
☆☆☆☆
☆☆☆☆☆
と表示させるなら
for(i = 0; i < 5; i++){
for(j = 0; j <= i; j++){
だと思います。
俺なら for(i = 0; i < 5; i++){ for(j = 0; j < i+1; j++){ にするかな、気分の問題だけど
355 :
デフォルトの名無しさん :2008/07/26(土) 16:17:28
for(i = 1; i <= 5; i++) for(j = 0; j < j; j++)
俺には j < i であってるように見える。
>>356 それで実行したら
-----------
改行
☆
☆☆
☆☆☆
☆☆☆☆
-----------
でした。
まぁ
for(i = 0; i < 5; i++){ cout << "☆";
for(j = 0; j < i; j++){ cout << "☆";
}
cout << "\n";
}
でも出来るけど、
>>355 が正解だろうな。
でもこの手のはCSVやURLクエリのように区切りが出てきて for(int i=0; i<5; i++){ std::cout << "☆"; for(int j=0; j<i; j++){ std::cout << ","; std::cout << "☆"; } std::cout << "\n"; } みたいな感じに落ち着くことも多い。
#include <iostream> #include <iomanip> int main() { int i, j; std::cout.fill('☆'); for(i = 1; i <= 5; i++) std::cout<<std::setiosflags(std::ios::right)<<std::setw(i)<<""<<std::endl; return 0; }
('☆')←何この顔バカにしてるの?
std::string str; for(int i=0; i < 5; i++) { str += "☆"; std::cout << str; } std::cout << "\n";
366 :
デフォルトの名無しさん :2008/07/26(土) 19:54:58
サービスとして動くプログラムのサンプルをやってるんですが上手くいきません StartServiceCtrlDispatcher()で失敗します GetLastError()で1063が取れるんですけど、どうすればいいんでしょうか? 環境はxp sp2、vc++2005でやってます void ErrorHandler( char *s, DWORD err ) { std::cout << s << std::endl; std::cout << "Error number: " << err << std::endl; ExitProcess( err ); } void WINAPI ServiceMain( DWORD argc, LPTSTR *argv ) { // 空 } void main() { char *SERVICE_NAME = "BeepService"; SERVICE_TABLE_ENTRY serviceTable[] = { { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain }, { NULL, NULL } }; // SCMで登録する BOOL success = StartServiceCtrlDispatcher( serviceTable ); if( !success ) ErrorHandler( "In StartServiceCtrlDispatcher", GetLastError() ); }
>>366 よくわからんが、ちゃんとサービスとしてSCMのデータベースに登録済みで、
SCMからサービスとして起動されたときにそういうエラーが出ているの?
ただのコンソールアプリとして普通にキックしたときに
StartServiceCtrlDispatcher()が失敗するのはただの仕様なんじゃないの
double型の変数を文字型の変数に疑似変換するプログラムを書けと教授に言われたのですが、 全く方法が解りません・・・。 誰か助けてください。 その際関数のオーバーロードを必ず使用する事、と言われました。 実は問題の意味があまり分かってなかったり。疑似変換とは・・・?
問題の意味は出題者に訊くしかない
今から教授に電話して聞いてみます。
sprintf? でもオーバーロードなんか必要ないしなぁ・・・
留守電だったので諦めました。 とりあえず考えられる事をいくつかプログラムしてみます。 疑似変換・・・・か。
char型の固定小数で表せって事だろJK
>>368 こんなん?
真夜中の電話、不吉な感じがイヤン
#include<iostream>
#include<string>
//ここでオペレータをほげほげ
int main(void){
double x=1.2345;
std::string str;
str=x;
std::cout << str << std::endl;
return 0;
}
オーバーロードを入れるとややこしくなりそうだな〜
関数のオーバーロードをする必要性がわからん・・
inline関数を使う場合は関数の宣言と関数の定義で2回記述しないといけないんですか? #include <iostream> using namespace std; //関数の宣言 inline int square(int x); inline double square(double x); int main() { int i; double j; cout << "整数を入力してください\n"; cin >> i; int sum1 = square(i); cout << i << "の二乗は" << sum1 << "です\n"; cout << "小数を入力してください\n"; cin >> j; double sum2 = square(j); cout << j << "の二乗は" << sum2 << "です\n"; return 0; } //関数の定義 inline int square(int x){ int num1; num1 = x * x; return num1; }inline double square(double x){ double mum1; mum1 = x * x; return mum1;}
>>377 inline なら定義が無いと意味無いし、定義は宣言を含むから、定義だけ書いとけばいいよ。
すいませんもう1つだけ質問です。 テンプレート関数は templat <class T>
すいません誤爆で途中で投稿してしまいました。 スレ汚しすいません;;
すいませんテンプレート関数は template <class T> T square(T x){ 処理 } と記述できると書いてあったんですが 宣言と定義みたいに分けて記述することはできないんですか? 試しに //宣言 template <class T> T square(T x); main関数 return 0; //定義 T square(T x){ 処理 } とやったのですがエラーが出ました。要するに無理ってことでしょうか?
>>382 無理です。使う時点で定義が読み込まれている必要があります。
>>383 ありがとうございます。
不思議に思っていたことが解決しました。
>>382 分けて書くこと自体は可能。その感じだと、たぶん定義のほうに template <class T> が足りないだけ。
390 :
デフォルトの名無しさん :2008/07/27(日) 01:35:03
「aaaaiiiuuueooあああああいいいしてるるるる」 みたいに、 ・昇順で並んでいる ・同じ文字がたくさん入ってる ・あとから変更されることはない ・wchar_t ・一文字あたりの繰り返しは少ない(5個くらいまで) ・長い文字列もある(10MBytesくらい) という文字列を扱うんだが、 ・「N番目の文字」を高速に取り出せる ・「N種類目の文字と個数」を高速に取り出せる 条件を満たすデータ構造ってどんなのがある? 配列を2つ用意するしかない? てかこのスレでよかった?
391 :
390 :2008/07/27(日) 01:36:00
すまん矛盾してた > ・同じ文字がたくさん入ってる これは無視してくれ。
>>390 struct { int start; wchar_t c; } を start でソートした配列、でいいんじゃないかな?
その例だと {{0, L'a'}, {4, L'i'}, {7, L'u'}, {10, L'e'}, {11, L'o'}, {13, L'あ'}, ...} って感じで。
>>390 昇順に並んでるってのは、文字コードが昇順にならんでるってわけじゃないの?
>>394 例にでてる文字列が文字コード順に並んでないけど、それは例が間違いってことだな。
>>395 ひらがなが先だっけ?
なら例が間違ってるわ。
すまん
>>396 いや、アルファベットをローマ字で昇順に並べても、文字コード順にはならんよ。
#include <iostream> using namespace std; //関数addの宣言 void add(int *px, int *py, int *pz); //点数を加算するプログラム int main() { int x1; int x2; int a; cout << "2科目の点数を入力してください\n"; cin >> x1 >> x2; cout << "加算する点数を入力してください\n"; cin >> a; add(&x1, &x2, &a); cout << "科目1は" << x1 << "点です\n"; cout << "科目2は" << x2 << "点です\n"; return 0;} //関数addの定義 void add(int *px, int *py, int *pz){ *px += *pz; *py += *pz;}
2科目のテストの点数(x1,x2)にa点を加算する関数add()を、ポインタを使って定義しなさい。 という宿題が出たのですが、これで実行したら成功したのですが。 これは無駄過ぎるという所はありませんか? あったら指摘お願いします
宿題スレに書かずにここに書く辺りが無駄。
402 :
デフォルトの名無しさん :2008/07/27(日) 15:00:46
>>400 まあパッと見pzはポインタにする必要はまったくないな。
宿題スレは〜のコード書いてくださいとかだと勝手に解釈してたので こっちの方に書き込んでしまいました。 ご迷惑おかけして大変申し訳ございませんでした。 この場を借りて謝罪いたします。
405 :
デフォルトの名無しさん :2008/07/27(日) 17:59:33
template<class T, class U> void f(T t, U u) { ... } template<class T> void f<T, int>(T t, int u) { ... } こういうことってできないんだっけ? error C2768: 'f' : 明示的なテンプレート引数を使用することはできません。 って出るんだが。
<T, int>いらない
408 :
405 :2008/07/27(日) 18:07:53
template<int I, int J> void f() { } template<int I> void f<I, 0>() { } これは無理? J=0の場合のみ特殊化。
テンプレート使った際の演算子オーバーロードで悩んでいます。 コンパイルエラーは以下のように出ます。 ------------------------- Test.cpp:13: error: expected constructor, destructor, or type conversion before ‘Test’ ------------------------- このエラーを理解できないため、デバグできません。 どうしたらいいのでしょうか? 教えてください。 ソースは以下。
// Test.cpp #include<iostream> using namespace std; template<typename T> class Test{ public: T value; Test(){}; Test operator+(const Test& t); }; template<typename T> Test Test<T>::operator+(const Test<T>& t) //←13行目 { Test tmp; tmp.value = value + t.value; return tmp; } int main() { Test<int> test1, test2; test1.value=100; test2.value=200; Test<int> test3 = test1 + test2; return 0; } -------------------------
Test<T> Test<T>::operator+(const Test<T>& t) じゃない? const Test<T> Test<T>::operator+(const Test<T>& t) このほうがいいかな
412 :
410 :2008/07/27(日) 18:25:03
おお! ありがとうございます m(_ _)m 続けて質問して申し訳ないのですが、 const をつけると付けないとではどのようなちがいがあるのでしょうか?
クラスのメンバ変数をポインタ型にすると メンバ変数が定義されていないとか言うんだけど 何これ…
414 :
413 :2008/07/27(日) 18:41:51
間違えた メンバ変数じゃなくてメンバ関数をポインタ型にすると メンバ変数が定義されていないって出る
class hoge{
直感で static付けたらどうでしょうと言ってみよう
メンバ関数をポインタ型? メンバ変数をメンバ関数ポインタの型にするって事か?
>>417 class A{
praivate:
int *a;
public:
void *get_a();
}
void A::*get_a()
{
return a;
}
aが定義されていない識別子です
ってなる
void* A::get_a()
voidじゃなくてintだった…
>>419 解決した。ありがとう!
421 :
デフォルトの名無しさん :2008/07/27(日) 18:59:27
すみません。。。お尋ねしたいのですが、 GDBでUTF-8の内容を表示させるにはどうすればよいのでしょうか? ご存知の方がいらっしゃいましたら何卒ご教授下さい。 よろしくお願いいたします。
TCHAR pString[64] ; std::wcin.getline(pString, 64) ; が入力を待たずに終わってしまいます。 プロジェクトを別に作って試したんですが他ではちゃんと入力を待ってます。 どういう状況の時だと処理を待たずに終了してしまうのでしょうか?
>>422 現象とは関係ないけど、それ、wchar_tかWCHARを使ったほうがいいよ。
>>422 直前で数値や文字列を入力したときに改行が残ったままになってるとか
文字列に指定した文字がいくつあるか調べる関数を作成して、実際にキーボードから文字を入力して文字の個数を調べるコードを書いたのですが。 include <iostream> #include <string> using namespace std; //関数countの宣言 int count(char str[], char ch); //指定した文字数を調べるプログラム int main() { char str[256]; //入力する文字列 char c; //調べる文字 int sum; //文字数 cout << "文字列を入力してください\n"; cin >> str; cout << "探したい文字を入力してください\n"; cin >> c; sum = count(str, c); cout << str << "の中に" << c << "は" << sum << "個あります\n"; return 0; }
//関数countの定義 int count(char str[], char ch){ int j; //文字列の文字数 int i; int num = 0; //カウントする変数 j = strlen(str); for(i = 0; i < j; i++){ if(str[i] == ch){ num++; } } return num; } これで実行してちゃんとカウントできたのですが、無駄過ぎる文はありませんか? 指摘お願いします。 連投すいません;;
>>426 sum = std::count( str.begin(), str.end(), c )
std::string と std;;wstring で template を使って関数を共通化したいんだけど, 文字列リテラル ( "hoge" と L"hoge") や,文字型の違い ( 'a' と L'a') を吸収するには どうやったらいいの? 例えば,バックスラッシュを付け足す場合とか. template <typename string_type> string_type& AddBackSlash(string_type& str) { return str += '\\';//← wstring の場合は L'\\' にしたい, }
おすすめのエディタ教えてください! 今までC言語を始めよう!というフリーソフトを使ってきました
432 :
428 :2008/07/27(日) 21:13:16
>>430 ありがとうございます.特殊化するということはコピペして,wstring に置換して, L を付ける作業をするしかないですかね…
template <typename string_type>
string_type& AddHoge(string_type& str)
{
string_type strInternal = "foo";
return str += "Hoge";
}
//特殊化
template<>
std::wstring& AddHoge<std::wstring>(std::wstring& str)
{
std::wstring strInternal = L"foo";
return str += L"Hoge";
}
>>423-424 ありがとうございます、
>>424 さんが言われたとおり直前で数値をwcinにて
受け取ってます。それをコメントアウトしたらgetineのとこで処理が
止まりました。
原因はわかったのですがどうやって回避してよいのでしょうか?^^;
std::vector<double> v(100); このとき確保されるメモリは実装しだい?
はい。sizeof(double)*100かもしれませんし、*128かもしれません。
>>431 結局は好みだから使ってみて気にいったのを使えよ。
因みに俺はemacs使ってる。
>>426 strlen(str) で文字列の末尾まで '\0' を検索した後に,
再び文字を検索するのが無駄と言えば無駄かも.
int count(const char str[], const char ch)
{
int num = 0; //カウントする変数
while( *str != '\0' ) if( *str++ == ch ) num++;
return num;
}
int count(const char * const str, const char ch) { unsigned num = 0; for (char const * p = str; (p = strchr(p, ch)) != NULL; ++p) ++num; return num; }
nul終端文字列ってほんと頭悪い仕様だよな。色々非効率だし。
440 :
437 :2008/07/28(月) 01:14:04
>>438 そんなに変わらないだろうと思ってたけど,ずいぶん速いな
>>439 PASCAL stringを授けよう。
442 :
デフォルトの名無しさん :2008/07/28(月) 02:20:14
メッセージプロシジャでWM_CHARが送られてきた時、 OnKeyDownという関数にwpとlpをそのまま渡しています。 そして、押されたキーが"v"だった時だけ処理をしたいのでstrcmpを使ってみたのですが そこで強制終了してしまいます。正しくはどう書いたらよいのでしょうか? 教えてください。お願いします。 OnKeyDown(WPARAM wp, LPARAM lp) { switch(wp) { case VK_RETURN: break; 〜 略 〜 default: if(strcmp((char*)wp,"v") == 0) { //キーがvだった時の処理 } }
>>443 MessageBoxに表示させようと
wpをchar*にキャストしたら同じように落ちました・・・
とりあえずそっちで聞いてきます。
ありがとうございました。
初心者ですがC言語を覚えるには数学ができないと駄目ですか?
C言語だけなら算数が出来れば十分 3Dやら暗号やら圧縮やらを扱いたいなら数学が必要になってくるかも
446さんありがとうございます。
C言語で仮に3Dアクションゲームを造るとすると最低限高校1年の数学と物理が理解できればチャレンジしても無謀ではないですか? 数学:sin cos tan(三角関数?)等 物理:ベクトル等
うん、あと行列がわかってれば 物理演算しようってわけじゃないんだから、完全な理解も必要なし
ライブラリ使えば自分で計算する必要ももちろんないしね
まぁ行列分かってれば中学生でもできるよ。
まぁそれをいったら ベクトルが分かっててプログラミングができるなら小学生にもできるよ、って話だけどな
ベクトルも行列もプログラミングも分からない大学生にはできないといいたい訳だな
分からなきゃ勉強するまでさ。 今までだってそうやってきただろ?
スレ違いだと思いますが流れ的に質問させてください。 CとC++とwindowsプログラミングを一通り勉強したので 次にDirectXの勉強をしようと思っているのですが、勉強する前に三角関数・ベクトル・行列を復習してから(曖昧なので) DirectXの勉強をしたほうが理解が深まると思うのですがどう思いますか? 先輩方アドバイスよろしくお願いします。
先にDirectXのチュートリアルでもやった方が良い
>>456 目的にもよりますが Direct3D を勉強しながら分からないところを調べるほうがオススメ
DirectX進めながら解らないところが出るたびに数学の教科書を見るのでも別に構わんとは思う
1からやるわけでもないしな。 思い出すのなら必要なことが出てからでも、今やってることが止まることも無いでしょう。
DirectX=3Dじゃないと思うんだけど
>>461 そうなんですか?
勘違いしていたみたいです・・。
もう少し調べてみます。
>>461 DirectXの描画は基本3Dじゃなかったっけ
Drawが葬られたからね。
実はDirectSoundだけ使いたい・・・なんてことはないか
>>464-465 そうだった
昔2D描画用のがあったんだけどもうなくなったんだね
あれ結構評判良かったのに
今でもDirectDrawは使えるし、地味にアップデートもされてる(もうされないだろうけど) ドキュメントが無くなったけどな
引数←読み方インスウだと思ってたけど ヒキスウって最近知った
returnされる値は カエリチ?ヘンチ?
返り血
独学でやってたってことかな 授業とかでやったら確実に発音するでしょ
普通、戻り値だよな
オレも返り値は返り血に聞こえるから戻り値
477 :
デフォルトの名無しさん :2008/07/28(月) 17:05:45
リターンチだろ
どれも同じだ
スタックの血を浴びて 〜社会不適応者のデスマーチ奮闘記〜
新ジャンル:仕事人間サスペンスホラー
ああ、よく考えたら俺も戻り血だったわ。
オレは「戻り値として0を返す」とかいう。 でも「返り値として0を戻す」はいったことないな。
俺は「返り値として」には違和感がある 返り値を使うなら「返り値をaに戻す/返す/当てる」とかは言う 返り値の値に言及する時は思いつかない
const std::string& GeRefOfFuncStaticString(int n) { static std::string str = boost::lexical_cast<std::string>(n); return str; } const std::string g_strNotFound("NotFound"); const std::string& GeRefOfFuncStaticString2(int n) { static std::map<int,std::string> mapStr; if( mapStr.empty() ) { mapStr.insert( std::make_pair(100, "100") ); mapStr.insert( std::make_pair(101, "101") ); } std::map<int,std::string>::const_iterator itrFound = mapStr.find(n); return itrFound != mapStr.end() ? itrFound->second : g_strNotFound; } int _tmain(int argc, _TCHAR* argv[]) { std::cout << GeRefOfFuncStaticString( 100 ) << std::endl; // 表示: 100 std::cout << GeRefOfFuncStaticString( 101 ) << std::endl; // 表示: 100 ← 関数内の static 変数の参照を取り出せない std::cout << GeRefOfFuncStaticString2( 100 ) << std::endl; // 表示: 100 std::cout << GeRefOfFuncStaticString2( 101 ) << std::endl; // 表示: 101 return 0; } map を使った場合の GeRefOfFuncStaticString2( ) は意図した動作になるんですが,たまたまでしょうか?
>std::cout << GeRefOfFuncStaticString( 101 ) << std::endl; // 表示: 100 ← 関数内の static 変数の参照を取り出せない 関数内のstatic変数の参照を取り出してますよ。
>>485 解答ありがとうございます.恥ずかしながら static に関してすごい勘違いをしていたようです.
初期化が一度しか行われないんですね.以下のようにして GeRefOfFuncStaticString() でも望みどおりの
動作が出来るようになりました.
有難うございました.
const std::string& GeRefOfFuncStaticString(int n)
{
static std::string str;
str = boost::lexical_cast<std::string>(n);
return str;
}
487 :
デフォルトの名無しさん :2008/07/29(火) 03:24:06
a
static変数が緊急対応以外で必要になったときは設計ミス。
何故static変数にいちいち保存しているのかが謎。
便乗質問なんだけど
const std::string& GeRefOfFuncStaticString(int n)
{
static std::string str = boost::lexical_cast<std::string>(n);
return str;
}
これ static のところ、いつ初期化されるんだ? 今までプログラム
起動時(main以前)だと思ってたんだが、nが関数の呼び出し時に
決まるじゃん。
内部で
if(関数の初回呼び出しなら){
str = boost::lexical_cast<std::string>(n);
}
みたいなコードにコンパイルされるわけ?
>>484 の挙動見ているとそう見えるんだが…
>>490 それであってる。
ちなみに初期化についてスレッドセーフである保証は無いので、
マルチスレッドのプログラムで排他せずにstatic変数使ったら、
いつ異常動作してもおかしくない。
492 :
デフォルトの名無しさん :2008/07/29(火) 10:07:55
標準ライブラリのメンバ関数までが詳細に載ってるページってありますか? 探したけど俺の目が悪いんだろうか、見つかりません;; だれか教えてください もしくは、この質問に答えてください。 istringstreamのオブジェクトに、文字列を代入(?)するとき、 istringstream is(string("abc")); のように初期化ではなくて、あとから代入することはできますか? やり方を教えてください。
>>491 いつの間にそうなったんだ…
関数呼び出し時に初回判定が入るんじゃあパフォーマンス
に悪影響があるだろうが。
func(){
static int a = 100;
}
は昔どおり初回判定なんか入らないよな?
>>493 昔から変わってないよ。その int の例でも、関数内で値の変更があったり、
ポインタや参照を外に渡してしまっている場合は初回判定が必要になるでしょ。
昔どおりも何も、単に最適化で判定が消えてるだけだろ
>>492 istringstream ではなくて stringstream を使ってみては?
定数での初期化なら、初回実行時でなくmainの前にされたりするよ。 その辺の最適化は処理系定義。 引数で初期化したら、まず確実に判定が入る。
std::wofstreamを使ってテキストに書き込む時自動的にファイルの 頭にBOMを追加してくるみたいなものって存在しますか? 自分で先に書くのが普通でしょうか? 自分でFF FE をファイルと開いて書き込んでから wofstreamを使うと先に書き込んだ2バイトが消されてしまい途方にくれて おります・・・・
自分で先に書くのが普通。
std:ios::app だっけ?
>>499 つまり、関数内のstatic変数の初期値が定数じゃない限り、初回確認用のフラグもstatic領域に用意されるわけだな。
>>494 一連のレスは理解できるのだが、
> int の例でも、関数内で値の変更があったり、
>ポインタや参照を外に渡してしまっている場合は初回判定が必要
これが分からん。
プログラムロード時にaが100になるでしょ。それで、関数内で
値の変更があったり、 ポインタや参照を外に渡してしまっている
場合はどうして初回判定が必要になるの?
>>505 例えばこんなケース。
int func(int n)
{
static int a = n;
return a;
}
int main()
{
for (int a = 2; a <= 5; ++a) {
printf("%d, %d\n", a, func(a));
}
return 0;
}
507 :
494 :2008/07/29(火) 12:23:54
>>505 変数宣言通過時に初期化されるんなら初回判定が必要かと思ったんだけど、
プログラム起動時に初期化してもいいみたい。
ってことで >494 は間違いで、初回判定が必要になるのは初期値が定数式じゃないときね。
ごめんよ
>>506
横から失礼します ファイル中のN個の値で、配列a[N]を作りたいんですが うまいやり方が思いつかないので、どなたか教えていただけませんか?
malloc( new? ) を使えば出来るんですね。やってみます。
std::vector<型> a(N);でもよいぞ
ワイマール憲法を構造体で記述せよ という夏休みの課題が出たのですが、何から始めていいかさっぱりわかりません・・・・。 だれか御助けを・・・・。
イクイク、ワイマール憲法
struct kenpoo { int Y; int O; };
>>512 残念ですが、その課題を出した先生は脳に異常をきたしています・・・。
まともな対話は不可能でしょう。課題の提出は諦めるほかないでしょう。
みんなイクイク、ベルサイユ条約
ああ、1919か
518 :
デフォルトの名無しさん :2008/07/29(火) 22:26:11
class hoge{ private: std::list<int> foo; public: void setfoo(std::list<int> foo){ this->foo.clear(); std::list<int>::iterator itr; for(itr=foo.begin();itr!=foo.end();itr++) this->foo.push_back(*itr); } std::list<int> getfoo() const{ return foo; } }; int main(){ hoge hoge0; std::list<hoge> hogehoge; std::list<int> tmp; tmp.push_back(1); tmp.push_back(2); hoge0.setfoo(tmp); std::list<int>::iterator tmpitr = hoge0.getfoo().begin(); hogehoge.push_back(hoge0); std::list<int>::iterator itr = (*hogehoge.begin()).getfoo().begin(); std::cout << *itr << "," << *(++itr); } このコードで、最後に"1,2"と表示されて欲しいところが、"0,0"となってしまいます。 どこが悪いのかがわからず困っています。よろしければ教えていただけないでしょうか…。
ほう、それがワイマール憲法か。なるほど
getfooの戻り値であるhoge::fooの一時コピーが次の文に移る間までに破棄されてしまうからと、 ひとつの式の中でitrを代入と参照の両方してるから
521 :
518 :2008/07/29(火) 23:03:49
>>520 ありがとうございます。
最後にcoutするところで、itrが無効化してしまってるということでしょうか。
一時コピーが破棄されるタイミングがイマイチわかりません。
たびたびすいません…。
だれか、C++のえろい人
百聞は一見にしかずだから
>>518 のコードを希望通りに動くように修正汁!
すまん、俺C++わからんから><
getfoo()の戻り値を参照型に換えたら?
525 :
デフォルトの名無しさん :2008/07/30(水) 00:02:27
C言語勉強のためにプログラムを作成しました。
が、printf("hello")の時点で壁にぶちあたりました。
正しくコードを入れたはずですが、実行して表示されるのは、
2chアップローダ:
http://www-2ch.net:8080/up/download/1217343270379299.ZNkHRl です。exeと、badが同時に出現するのは何故?さらHELLOが表示されていないのは何故?
「苦しんで覚えるC言語」を参考にやってみたのですが、いきなり苦しいです。
神様助けてください。。。
コンパイラ:Borland C++ Compiler
エディタ:CPad for Borland C++Compiler
さらに
std::cout << *itr << ",";
std::cout << *++itr;
と二行に分けると動く。
その理由は、((std::cout.operator<<(*itr)).operator<<(",")).operator<<(*++itr)
というようにちょっと考えるとインクリメント演算子は後から適用されるように思えるが、
インクリメント演算子は副作用完了点に達するまでのどの段階で働いても
構わない事になっているからである。
もっと言えば
>>518 の動作は未定義である。
>>525 なんで start ってするの?compile したのは a.exe とかじゃない?
ところでその本には int main(void) 推奨なの?
start.cをコンパイルしたからstart.exeなんじゃないの
start.cなんだからbcc32ならstart.exe吐いてくれるはず まあたぶん./startってやったら動くんじゃない
例えば #include <iostream> int main() { int i = 1; std::cout << i << ' ' << ++i << std::endl; } のようなプログラムは "1 2" と出力しそうであるが、実際は未定義動作であり、 無理矢理動かすと大抵のコンパイラでは直感に反して"2 2"と表示されるのも 同じ理由による。
531 :
デフォルトの名無しさん :2008/07/30(水) 00:25:04
読み返して言葉足らずでした。補います。 printf("hello");では上記URLのようにexeと、badが同時に出現し、また何も表記が無い状態でしたが printf("hello\n");では「HELLO」が改行ありで表記されました。 また、printf("%d",100); printf("円\n");では改行ありで「100円」が表記されました。 私の見解では、ただ単に参考にした構文が間違っている(\nが必要だが書かれていなかっただけ) のだと思いますが。。。意見を聞かせてください。
コマンドプロンプトにstartってコマンドあるから start.exeはまずくない?
533 :
デフォルトの名無しさん :2008/07/30(水) 00:26:14
>>531 printfのあとに
fflush();つけたらどうなるかな?
534 :
533 :2008/07/30(水) 00:27:06
いろいろ間違えたごめん忘れてください
(なぁなぁ、badって何?)
536 :
デフォルトの名無しさん :2008/07/30(水) 00:32:52
unixでtestという実行ファイルを作ってハマった当時の俺
あるある うん。あるある
539 :
デフォルトの名無しさん :2008/07/30(水) 00:44:46
batやらbadやら恥ずかしいことばかり書き込んでしまいました。
セキュリティーホールがあれば入りたいです。
startをaに変更すると、
http://www-2ch.net:8080/up/download/1217345861729515.WpasSs な感じになりました。これで夜も安心して眠れます。
>>527 startにしたのは無知だからでした。「手始めにスタート」のつもりでした。
この本というかサイトではそうでした。他のサイトを見てみると他の記述もありましたが、
最初に見たこのサイトの記述で貫こうと思います。
>>532 決定的な回答ありがとうございます。小鳥の1歩ほど前進することができました。
終わりなきC言語を心ゆくまで堪能したいと思います。親切にしてくださってありがとうございます。
>>534 いっしょにセキュリティーホールに入りませんか。
>>535 完全に撃ち間違いです。申し訳ありま栓。
すいません質問です。 ソラリスでは使えてたのですが、Linuxだとエラーが出てしまってgoogle検索したのですがいい対応策が見つかりません。 newとdeleteは演算子なのですが、 例 string * aaa; というのを.hで宣言し .ccにて コンストラクタでNULLクリア main処理にて値を入れる場合と入れない場合があるのですが、 値を入れない場合に、 デストiラクタでaaaをdeleteしようとすると、落ちてしまいます。 SolarisからLinuxに入れ替えようとしているので、Solarisでは通るのにLinuxでは通らないという事はあるのでしょうか。 簡単にプログラムの例を classで、 string * aaa; を宣言しておき、 コンストラクタで、aaaをNULL初期化します。 mainルーチンで、aaaにファイルから文字列を取得するのですが、 該当しない場合はaaaはNULLのままとなっています。 デストラクタで、 if(aaa){ delete aaa; } とやっているのですが、そこで落ちてしまいます。 よろしければアドバイスお願いします。
コンパイラはgccです
542 :
デフォルトの名無しさん :2008/07/30(水) 02:19:37
VC++を使用しているのですが、 char ItemObject[1024]; ItemObject = "TEST"; listBox->Items->Add(ItemObject); とするとコンパイルできません。 プログラミング初心者で、どうすればいいのか分からず困っています。 どなたか、助けて下さい。よろしくお願いします。
delete演算子は対象のポインタが 0 の時は何もしないで 戻るようになっている。 従って if文は不要。原因は他の所にあるのではないか。
>>542 listBox->Items->Add( gcnew System::String(ItemObject) )
はじめから System::Stringを使え。
それより、このスレはC++/CLIはOKなのかな?C++/CLIはC++とは別物だから明記しておくように。
>>543 >>delete演算子は対象のポインタが 0 の時は何もしないで
>>戻るようになっている。
これは知ってはいたのですが、チェックしてしまうクセがついてしまっています。
>>従って if文は不要。原因は他の所にあるのではないか。
やはり原因は他にあるのですかね。
Soralisで通っててLinuxでは通らないので、規格の違いかと思い質問させてもらいました。
(LinuxはSoralisと比べて厳しいので
もうちょっと調べてみます。
アドバイスありがとうございます。
>>540 クラスも無いのにコンストラクタとか言ってるのがおかしい。ソース晒せ。
memsetでクリアしてたりする?
>>546 class hoge{
string * aaa;
}
mainでaaaに文字列を取得
(ない場合は取得しない
hoge::hogeでaaaにはNULLを設定
oge::~hogeで
if(aaa){
delete aaa;
}
としています。
>>547 >>memsetでクリアしてたりする?
memsetはやっていないですね。
文字列取得にはc_str()を使用しています。
>>548 hoge にデストラクタもコンストラクタもねーじゃねーか。
ソースを省くな。問題が再現する完全なコードを貼れ。
>>549 すいません、完全なコードを張る事ができないので省略してました。
何かしらヒントでもあればと思い質問しました。
SoralisとLinuxの互換性がまだ完全に把握できていないので
分かる人がいればと思い。
もうちょっと自分で調べてみます。解決したら役に立つかわかりませんが書き込みます。
>>550 問題が再現する最小のコードを作ってもらわないと、エスパーでもなけりゃわからない。
OS間の互換性に原因があると思ってるようだが、どうせ違う。
そういうコード作るのは相談のためでもあるが、基本的な調査の方法でもあるんで、
たいていは作ってる間に自分で気づくんだけどな。
全くのあてずっぽうだが、 hogeが意図せずコピーコンストラクタでコピーされてて、 2箇所でaaaがdeleteされているとかないだろうか。 deleteしたばかりで領域が再利用されていない場合に 2回目のdeleteでもエラーにならない処理系は存在する。 Soralisが落ちない処理系で、linuxが落ちる処理系だとすると・・
>>552 一応gdbでも処理追ってみたのでコンストラクタが2度通ってる事はないみたいです。
privateでコピーコンストラクタをきってみたら? デフォルトのコピーコンストラクタが使われているなら、 普通のコンストラクタは通らないよ。 stringがstl::stringだったらポインタで持つ意味があるのかは検討したほうがいいな。
>>554 なるほどprivateもありですね。試してみます。
stringはstd::stringです。
OSが違ったら通らないではなくて、Solarisではたまたまエラーが 出なくてLinuxではしっかりチェックされて落ちるってオチだろうな。 多分ソースにバグがある。
>>556 その可能性大ですね。
Solarisはチェックが甘いからたまたま通ってただけな気がします。
時間あるから作り直そうかな。他にもありそうですし。
元々作った人が逃げて改修まかされて困ったもんです。
Solarisはdeleteした領域を触っても落ちないからね。
linux gcc(4.0)は2回deleteでセグメンテーション違反を確認。 vc++2008は落ちないのを確認。
#include <string> int main() { std::string* str = new std::string; delete str; delete str; } BCC5.9.3(C++Builder2007付属品)+CodeGuardで次のログ出力。 Error 00004. 0x100630 (スレッド 0x0C24): 解放済みメモリの アクセス : アドレス 0x00D743E0+16 から 4 バイトを参照しました。. | C:\Program Files\CodeGear\RAD Studio\5.0\Include\dinkumware\xstring line 1757: | else if (_BUF_SIZE <= _Myres) | { // copy any leftovers to small buffer and deallocate |> _Elem *_Ptr = _Bx._Ptr; | if (0 < _Newsize) | _Traits::copy(_Bx._Buf, _Ptr, _Newsize); 呼び出し履歴: 0x00401477(=double_delete1.exe:0x01:000477) C:\Program Files\CodeGear\RAD Studio\5.0\Include\dinkumware\xstring#1757 0x004012FE(=double_delete1.exe:0x01:0002FE) C:\Program Files\CodeGear\RAD Studio\5.0\Include\dinkumware\xstring#561 0x00401205(=double_delete1.exe:0x01:000205) double_delete1.cpp#8 0x328876DE(=CC3280MT.DLL:0x01:0866DE)
他にも解放済みリソースを参照したとのエラーログがたくさん 出力されましたがあまりに長いため省略します。 Linuxにはこの手のデバッガはありませんか?
562 :
>>542 :2008/07/30(水) 04:24:09
お礼を忘れてました。すみません。 お答えを下さった方、助かりました。どうもありがとうございました。
>>560 gdbがある
zeroとかなんとかそういう感じのもあった気がする
>>561 前述したようにdeleteの2重はありませんが、
そのプログラムで
str に NULLを代入し、str に対して delete を行うとLinuxでは落ちてしまいます。
デバッガはgdbが標準でついてるはずなのでそれで可能です。
gdbのコマンドとしては、
落ちた時のcoraファイルを取得し
gdb main.o coreファイル名
で、デバッグ可能です。
main.oはLM名です。
gdbのプロンプトに変わりますので、そこから解析は可能ではあります。
>>564 素朴な疑問なんだけどNULLと0が違うんかもしれんね。
0を代入してdeleteしてみ。
いやいや。C++でそれはありえないでそ
つーか、gccのバージョンはいくつよ?
>>564 の書き込みが正しいとすれば
ユーザー定義のNULLが存在するのかもしれない
調べてみては?
>>564 #include <string>
int main() { std::string* str = new std::string; str = NULL; delete str; delete str; }
↑これで落ちるってこと?
ヌルポインタの delete で落ちるんならコンパイラが腐ってる。
>567 も挙げてるけど、コンパイラは何?
>>564 再現する最小ソースが作れないほどの規模らしいから
str に NULLを代入し、
:
*ここに何かいっぱい処理がある
:
str に対して delete を行うとLinuxでは落ちてしまいます。
strに副作用のある部分を二分探査でブレークポイントなりデバッグ出力なりを掛けてどこが問題か探すんだ。
例外処理のサンプルソースを見てたのですが、 #include <iostream> using namespace std; int main() { int num; cout << "1から9までの数を入力してください\n"; cin >> num; try{ if(num <=0){ throw "0以下を入力しました\n"; } if(num >=10){ throw "10以上を入力しました\n"; } cout << num << "です\n"; } catch(char* err){ cout << "エラー:" << err << '\n'; return 1; } return 0; } catchブロックのreturn 1というのは異常に終了したから1を返すという意味ですか? 試しに0で実行しても同じ結果だったので気になりました。
>>572 実行した後に、何が返ったのか調べることができる。
どうやって調べるかは実行したシェルによる。
調べなきゃ何もかわらない。
>>572 お使いのコマンドインタプリタに終了ステータスが渡されています。
その値を見ることができれば、0だったり1だったりするのが判ることでしょう。
#include <stdio.h> #include <stdlib.h> #include <tchar.h> int main() { FILE *fp; wchar_t buf[16] = {0}; if(_wfopen_s(&fp, _T("hoge.txt"), _T("w, ccs=UTF-8"))) exit(1); fputwc(_T('あ'), fp); fputwc(_T('イ'), fp); fputwc(_T('菟'), fp); fclose(fp); if(_wfopen_s(&fp, _T("hoge.txt"), _T("r"))) exit(1); for(int i = 0; i < 3; i++) { buf[i] = fgetwc(fp); } fclose(fp); wprintf(_T("%s"), buf); return 0; } このようにUTF-8で入出力すると、出力はうまくいくのですが入力で文字化けが起きてしまいます どうすればいいのでしょうか。環境依存のものですが、よろしくお願いします。 WindowsXP + VC2005です。
_T("r, ccs=UTF-8")だったというオチ?
どう化けるのさ。 入力したものの画面出力、じゃないの? ロケール設定してみては。
入力でもccs=UNICODEとccs=UTF-8で試しましたが駄目でした。 入力では文字コードのフラグがなくてもBOMで勝手に判断してくれるとのことなのですが……。
>>578 ええ、コンソール出力したものが化けます。
そちらが問題なのでしょうか。
wprintf(_T("%s"), buf);←ここがUTF-8じゃない
ちょっとやってみたよ "r, ccs=UTF-8" にして、 #include <locale.h> 追加して setlocale(LC_ALL, "japanese"); 追加したら出たよ。
>>577-578 ,581-582
ありがとうございます。
setlocaleの使い方が分からなくて手間取りましたが無事出ました。
ということは入出力はちゃんと行われているんですね。
ロケールについて少し調べてみます。
584 :
540 :2008/07/30(水) 22:24:54
こんばんは。先日の者です。寝てあたますっきりしたところでもう一度処理全体を追ってみました。
簡略すると下記のようなソースになります。
@で、aaaの初期値にnull_stを代入しており、
その後ifを通らなかった場合に、
Aのdeleteで同じ箇所を2度行おうとし、落ちているみたいでした。
>>558 さんの言う通りSolarisはdeleteした領域を触っても落ちないのですね。
解決策として、Bの記述を
null_st = NULL;
に変えようかと思うのですが、これは大丈夫なのでしょうか。
質問ばかりですみません。
main()
{
string* aaa;
string* null_st;
int cnt;
null_st = new string(""); // B
aaa = null_st; // @
// cntは別の所で操作されると思ってください。
if(cnt == 1)
{
aaa = new string("AAA");
}
delete null_st; // A
delete aaa; // A
}
…だったら、null_stっていらなくね?
std::stringをポインタで扱うのがそもそも間違い
587 :
540 :2008/07/30(水) 22:47:16
なるほど。 規模が結構大きくて全部改修するには手間がかかるので必要最低限だけを変えたいんですが、 string* null_st; を消して、NULLにするだけで大丈夫ですかねぇ
NULLじゃなくてカラ文字として扱いたいからそうしてるんだろ?どこかでヌルポにならないか。 aaa = new string("AAA"); のあと aaa = new string("BBB"); 別の文字を代入することあったら、 "AAA"がメモリリークをおこしてるようなことはないだろうか。
589 :
540 :2008/07/30(水) 23:08:10
aaa = new string("AAA"); のあと aaa = new string("BBB"); は、みたところありませんでした。 別の文字列を入れる場合は必ずdeleteが走る仕組みになってます。
既存のソースを扱ってるなら可哀想だけど、 自分で書いたのなら、何故入門書なり入門サイトを見ずに書いたのかと・・・
aaa = new string("AAA");の後に aaa = new string("BBB");があったら、そらメモリリークですよ… string* aaa = NULL; if(cnt == 1){ aaa = new string("AAA"); } if (aaa != NULL && aaa == "") { //カラ文字の時の処理 } if (aaa == NULL) { // カラ文字どころか存在さえしない時の処理 } delete aaa; aaa = NULL; // ←これは別に必要ではない
仮にaaa->empty()に加えてaaa == NULLという状況も扱いたいのなら、 素直にboost::optional使ったほうがいいと思う。 そうには思えないけど。
生のメモリを扱えない他の高級言語から移ってきて なんとなくメモリの扱いをわかった気になっているだけ、という匂いを感じる。
594 :
591 :2008/07/30(水) 23:33:17
え?おれ?
だれだてめえ
貴様らに名乗る名前はないっ!
とりあえず、null_stで初期化してるとこをNULLで初期化するように変更しようと思います。 null_stは削除の方向で。 何か弊害ありそうでしたら教えてくださったら幸いです。
if(*aaa == *null_st)とかif(*aaa != *null_st)があるかどうかかなぁ あったらnull_strは消さない方がいいかも あと590のカラ文字かの判定間違ってるわね ×if (aaa != NULL && aaa == "") { ○if (aaa != NULL && *aaa == "") {
>>if(*aaa == *null_st)とかif(*aaa != *null_st) この判定は試してませんでした。 その条件で大丈夫そうなら使ってみます。 このプログラム作った人がいたら、何を意図して作ったのか聞きたいんですが、 もういないので、聞くに聞けずここをいじったらまた別のが出てくるのではないかと 怖いんですよね。 ただでさえ、SolarisとLinuxのポーティングに苦労してるので・・
ここでいいのか分からないんですが、マクロの質問です。 TCHARを使ったプログラムを書いていて、ヘッダ側とソース側で何故か TCHARの定義が変わってしまい、 外部シンボル 〜が未解決 というエラーが出てしまいます。どうすればこれを回避できるのでしょうか?
>>598 あ、判定にそのコードを使ってるかって事ですね。
それは使ってないです。
deleteする時にその条件使えばいいかなと思ったので、
>>599 の解答になりました。
ていうかさ、一口に「Linux」と言っても、いろいろあるわけよ。 gccのバージョンとかglibcのバージョンとか含めてね。 その辺のことすら示さないで、何が「挙動の違い」だか。
gccのバージョンは3.4.6です
同じコード
>>584 main()
{
string* aaa;
string* null_st;
null_st = new string("");
aaa = null_st;
delete null_st;
delete aaa
}
これで落ちると落ちないの違いがあるので挙動の違いじゃないんですか?
上記をコンパイルして実行してみるると、Solarisでは落ちます。Linuxでは落ちません。
挙動の違いじゃないなら何があるか逆に教えてください。
まだ互換性についても詳しくないので。
すいません、逆でした。 Solarisでは落ちません。Linuxでは落ちます。
そりゃ二重解放なんてしちゃ落ちてもしかたがなかろう
だから、オレがやったんじゃないんだって・・ それを乗せ換え時に改修してるだけ
>>584 昨夜からまだやってたのか
string* aaa;
int cnt;
aaa = new string("");
if(cnt == 1) {
delete aaa;
aaa = new string("AAA");
}
delete aaa;
class foo { string aaa; public: void set_aaa(const string& s) { aaa = s; } const string& get_aaa() { return aaa; } }; // どうしても aaaをポインタにしたいならいろいろとやることが増える class bar { string * aaa; public: bar() { aaa = new string(""); } ~bar() { delete aaa; } void set_aaa(const string& s) { delete aaa; aaa = new string(s); } const string& get_aaa() { return *aaa; } bar(const bar& o) { aaa = new string(*o.aaa); } bar& operator=(const bar& o) { aaa = new string(*o.aaa); return *this; } };
あくまでも挙動の違いとして捉えたいなら「Solarisでは間違ったメモリ解放でも落ちないようになっている」か「
>>603 のコードではたまたま落ちてないだけ」としかいえない
言語のルールとしては明らかにおかしいんだから、さらに情報が欲しければそれぞれのスレで聞いたほうがよいのでは?
で、おかしいコードを改修してるんだよね
その改修ポイントのアドバイスとしては
>>605 はピンポイントで教えてくれてるんだからそんなにつっかからなくてもいいんじゃない
つっかかってるわけじゃないんですが、すいません。 aaaはポインタじゃない方がいいんですね。 その場合どうするべきなのでしょう。
同じオブジェクトを二度以上解放しないように改修すればすむことじゃないのか・・・
もし本当に2重解放が原因と考えているのなら 全てのdeleteの直後にNULL代入のコードを追加して確認してみろ
>>610 根本的なこと聞きたいんだけど、自分でプログラム組む時に
他人に質問しないでやり遂げられるくらいのレベルにはなってるの?
それともC/C++そのものがはじめて?
やり取り見てると何がしたいのかイマイチ意味不明。
確実なのは、Solarisのその落ちない状況が「たまたま」
だということで、「挙動の違い」というのが何を欲して
そういう風に言ってるのか分からない。
環境移してバグが表面化してるだけだから、解決方法は
ひとつしかない。二度開放するソースを直すしかない。
>>610 >aaaはポインタじゃない方がいいんですね。
>その場合どうするべきなのでしょう。
string自体が文字ポインタとその先の文字配列を管理してるクラスなんだから
それをさらにポインタにしてそのインスタンスを管理するのは愚の骨頂。
>>584 のコードはこれだけになる。
main() {
string aaa;
int cnt = ... ;
if(cnt == 1) { aaa = "AAA"; }
}
つ〜か
>>608 に解答があるじゃん。
別に愚の骨頂と言うほどでもない。
コピーをあんまり発生させたくないならポインタで引き回すのもありかな。 そのときはauto_ptrかshare_ptrを使おうぜ。 それなりにカオスな予感がするけど std::auto_ptr<std::string> aaa(new std::string())
617 :
デフォルトの名無しさん :2008/07/31(木) 12:47:28
改行と空白で区切って単語をvectorに格納したいです。教えて下さい。 ポインタと単語長を格納します。 class tango { public: char *p; int L; }; string str="abc defg hijkl mn\n opq \r\n rstu"; vector< tango > tng;
宿題スレへ
>>617 相談したいんなら、まず自分で書いたコードから。
620 :
デフォルトの名無しさん :2008/07/31(木) 13:11:01
自分でできた class tango { public: char *p; int L; output(){string x(L+1,'\0'); memcpy(&x[0],p,L); cout<<x<<endl;}}; chk(char c){ return (c==0 || c==' ' || c=='\r' || c=='\n');} int main() { string str="abc defg hijkl mn\n opq \r\n rstu"; vector<tango> tng; int i=0,L,sz=str.size(); for(;i<sz && chk(str[i]); i++); while(i<sz){ for(L=1; L<sz && !chk(str[i+L]); L++); tango x; x.p=&str[i]; x.L=L; tng.push_back(x); i+=L; for(;i<sz && chk(str[i]); i++);} for(i=0;i<tng.size();i++) tng[i].output();}
>>620 chk のループは、 string の find_first_of() と find_first_not_of() で置き換えるのがおすすめ。
>>620 関数の戻り値省略しちゃダメ。
> output(){string x(L+1,'\0'); memcpy(&x[0],p,L); cout<<x<<endl;}};
これは
void output() const {cout<<string(p, L)<<endl;}};
でいい。
そもそも tango 自体が string でいいような気もするけど。
sstream
>>603 あくまで二重deleteにしか問題がない、ってことを他のソースコード
に一切手をつけないで確かめたいなら方法が無いこともないよ
625 :
デフォルトの名無しさん :2008/07/31(木) 13:49:21
アドバイスありがとうございます。ソースが単純になりました。 class tango { public: char *p; int L; output(){cout<<string(p,L)<<endl;}}; int main() { string str="abc defg hijkl mn\n opq \r\n rstu"; char dem[]=" \r\n"; vector<tango> tng; int i=0,j; while(1){ i=(int)str.find_first_not_of(dem,i); j=(int)str.find_first_of(dem,i); if(i==-1 || j==-1)break; tango x; x.p=&str[i]; x.L=j-i; tng.push_back(x); i+=j-i;} for(i=0;i<tng.size();i++) tng[i].output();}
626 :
デフォルトの名無しさん :2008/07/31(木) 13:52:10
>>622 stringだと参照ではなくコピーになるので元のメモリかファイルの量の倍になってしまいます。
Returnはエラーでない限りは省略してました。voidとかreturnはコンパイラに依存しますね
>>626 C++ の標準規格では戻り値の省略はできない。
そのソースがコンパイルできることがコンパイラ依存。
「voidとかreturnはコンパイラに依存」こっちは意味不明。
628 :
デフォルトの名無しさん :2008/07/31(木) 14:05:13
mainだけはありだろ?
629 :
デフォルトの名無しさん :2008/07/31(木) 14:05:56
ごめん
auto output(){ }
>>626 tangoの中身をstringにすれば、625のコードで言うとこのstrが
空白区切りを終わった後は不要になるから、
何も考えずに倍のメモリを使うと決め付けるのは早計。
632 :
デフォルトの名無しさん :2008/07/31(木) 14:29:37
でもファイルから読み込んだ場合、サイズが3Gとかあれば位置を記録した方がいいですよね
3ギガオクテットちゃん?
>>632 「サイズが3Gとかあれば」なんて事情があるなら、そのとおりだが、
その場合は元データを string に入れるのが間違いだろ。
istream で読んで、空白区切りの単語をそれぞれ string に入れたほうがいい。
まぁそんなことは正直どうでもよくて、読み手はエスパーじゃないんだから、
そういう特定の事情に依存する話をあたりまえのようにするなってことだ。
635 :
デフォルトの名無しさん :2008/07/31(木) 18:12:39
ファイルの分割も作りました。 添削してもらえますか? ふたつに分けます。 あとstringのfind_first_ofはバイナリに対応出来ないので自作しました。 #include <string> #include <iostream> #include <vector> #include <windows.h> using namespace std; string delimiter=" \r\n\0"; class tango { public: char *p; int L; output(){cout<<string(p,L)<<endl;}}; class file2array { HANDLE fp, mp; char *p; DWORD sz; public: file2array(string); ~file2array(); char* operator[](unsigned int); DWORD size();}; int find_of(file2array &p, string dem, int n){ unsigned int i,j; for(i=n;i<p.size();i++){ for(j=0;j<dem.size(); j++)if(dem[j]==*p[i])return i;} return -1;} int find_not_of(file2array &p, string dem, int n){ unsigned int i,j,s; for(i=n;i<p.size();i++){ s=0; for(j=0;j<dem.size(); j++)if(dem[j]==*p[i])break; else s++; if(s==dem.size())return i;} return -1;}
636 :
デフォルトの名無しさん :2008/07/31(木) 18:13:17
int main() { file2array p("text.txt"); vector<tango> tng; int i=0,j; while(1){ i=find_not_of(p,delimiter,i); if(i==-1)break; j=find_of(p,delimiter,i); if(j==-1)break; tango x; x.p=p[i]; x.L=j-i; tng.push_back(x); i+=j-i;} for(i=0;i<tng.size();i++) tng[i].output(); return 1;} file2array::file2array(string name){ fp=CreateFile(&name[0], GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0 ); if(fp==INVALID_HANDLE_VALUE){cout<<"file load err\n";return;} sz=GetFileSize(fp, NULL); mp=CreateFileMapping( fp, 0, PAGE_READONLY, 0, 0, "memmap" ); if( mp <= 0 ){cout<<"mapping err\n";return;} p=(char*)MapViewOfFile( mp, FILE_MAP_READ, 0, 0, 0);} file2array::~file2array(){ UnmapViewOfFile(p);CloseHandle( mp );CloseHandle( fp );} char* file2array::operator[](unsigned int n){ return (p+n); } DWORD file2array::size(){return sz;}
637 :
デフォルトの名無しさん :2008/07/31(木) 18:29:20
質問なんですがメモリマップドファイルって効率良いですか? 順次アクセスしたときキャッシュにデータ乗るかと言う事です。 毎回HDDにアクセスしたら鈍いです。 自分でキャッシュ管理した方が確実で汎用性が上がりますか?
>>637 share しなきゃ OS がよきに計らってくれると思う
639 :
デフォルトの名無しさん :2008/07/31(木) 19:19:34
漠然とした質問で申し訳ないのですが、 あるオブジェクトのポインタを取得する関数が2通りあって、 どちらで取得したかによって、そのオブジェクトにアクセスできたり、 アクセスできずに落ちたりする現象が起こって困っています。 gdbで追っていくと、一方で取得したポインタは (hoge *) 0x8f1d48 ←ポインタを返す関数で取得 もう一方で取得したポインタは (hoge *&) @0x8f1b10: 0x8f1d48 ←ポインタのvectorを返す関数で取得後、at()で欲しい要素を取得 となっています。 同じアドレスを指しているのは間違いなさそうですが、 (hoge *)と(hoge *&)で異なった型?になっているようです。 これが原因かとも思うのですが、意味がよくわかりません。 もしお分かりになれば、教えていただけないでしょうか。
640 :
639 :2008/07/31(木) 19:29:03
元コードは大きすぎて載せられないのと、 再現する小さいコードが上手く作れない(再現しない)ので コードがありません。申し訳ありません。
ポインタが自動変数で、その参照を返してるとか?
>再現する小さいコードが上手く作れない(再現しない)ので バグはそこじゃないとこにいるんじゃね?
独自のファイル形式のアイコンを変更させるプログラムを組みたいのですが、参考になるサイトはありますでしょうか。 検索しても実行ファイルのアイコンの変更が引っ掛かり、目的のページが見つからず困っています。 現在VC++2005(c++)で組んでいます。
> 独自のファイル形式のアイコンを変更させる 何に変更させるの?
>>644 何でもいいのですが、例えば.aaa形式のファイルのアイコンをこちらで用意してある32x32の真っ黒のアイコンに変えたりなど。
拡張子を表示させている人はいいのですが、ファイル名だけを表示している人にとって全て未定儀形式のアイコンだと分かりずらくて。
>>643 検索ワード
関連付け アイコン レジストリ
647 :
643 :2008/07/31(木) 19:55:20
>>646 ありがとうございます。
レジストリ関連だったのですね。
しかも、それC/C++に関係ないどころかプログラムも関係ないWindowsの機能
まぁ、初心者のうちは切り分け出来なくてもしょうがないさ
初心者で申し訳ないのですが、 人のプログラムを見てて、 new演算子を使用しているのにdelete演算子で開放していない場合としている場合がありました。 newとdeleteはセットで使うものだと参考書には書いてありましたが、 下のソースではp2をdeleteしていません。 deleteしなくてはいけない場合と、deleteしなくても良い場合があるのでしょうか? hoge() { int *p1; int i =0; p1 = new int(); *p1 = 123; 〜中略 if(j==1) { int *p2; p2 = new int(); { delet p1; }
バグです
他に渡してるとか bar() { int *p1 = new int; int *p2 = new int; foo(p2); delet p1; } foo(int *p) { // なんかいろいろ処理 delete p; }
ズボラさんが小物プログラムを書く場合、 どうせすぐ終了するからとdeleteをサボる場合があります。 でもホントはいけないことなので、必ずdeleteするクセをつけてください。 あと、他の関数に渡してその中でdeleteしている場合もありますが、 これも一ヵ月後の自分が見たときに混乱する原因になるだけなので控えるべきです。
っていうか、生のポインタの使用をなるだけ控えるって方向性のほういいと思う。
学習上ある程度触れておいたほうがいいんじゃね。 スマートポインタ使っても、中で何やってるか分かってないと詰まる事あるし。
やはりdeleteは行うべきなのですね。 ありがとうございます。
もう一つ質問なんですが、 deleteしなくてもプログラム的には大丈夫なのですか? もちろん悪い事なんでしょうけど、実行しても落ちたりしないですし。
>>657 メモリが解放されないこと以外何の問題も無い
プログラム終了時にはきちんと解放される(ごく一部のOSを除いて)
いずれnewでメモリ確保できなくなってエラーになるんじゃん? 動かないプログラムって存在意義なくね?
なるほど。ありがとうございます。
見たのはLinux上で1秒もかからずに終わるプログラムなので
>>(ごく一部のOSを除いて)
これに該当しない限り大丈夫なわけですね。
>>659 ずっと動いているようなプログラムではまずいんですね。
deleteしないと、デストラクタも呼ばれないな。
ファイルポインタについて質問があります。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { FILE *fp; int i; char buff[256]; memset( buff, 'Z', 256 ); if((fp = fopen( "nekoneko.txt", "w")) == NULL ) { fprintf(stderr,"ファイルオープンエラー\n"); exit(EXIT_FAILURE); } printf("ファイル位置(書き込み前) = %ld\n",ftell(fp)); for (i=0; i<10; i++){ fputc('A',fp); } fputc('\0', fp); printf("ファイル位置(書き込み後) = %ld\n",ftell(fp)); rewind(fp); printf("ファイル位置(rewind後) = %ld\n",ftell(fp));
663の続き // fclose( fp ); // fp = fopen( "nekoneko.txt", "r"); fread(buff, sizeof(char), 5, fp); *(buff + 5) = '\0'; printf("%s \n", buff); fclose(fp); return(0); } ○実行した結果 AAAAA とならずにあらかじめ初期化していた文字が表示されました。 Aを10個書き込んだのでrewind関数でファイルポインタを先頭に戻したので ファイルの先頭からAを読み込めると思っていたのですがダメでした。 試しにfread関数の前で一度、ファイルをクローズ、読み込みモードで再度オープン (コメントアウトした部分)を行えば AAAAA は表示されました <質問>ファイルポインタの操作の仕方に問題があるのではないかと思いますが どうして上手くいかないのかが解りません。 ファイルに書き込むことにより移動したファイルポインタを先頭に戻せば ファイルの最初から読み込めると思ったのですがこれは間違いでしょうか? ・作成したファイル(nekoneko.txt)にはAは10個書き込まれている ・rewind関数の代わりにfseek(fp,0L,SEEK_SET) またはfgetpos関数、fsetpos関数で ファイルポインタを先頭に戻しても駄目でした。 ・ファイルから読み込むのにfread関数の他、fgets関数、fgetc関数を試したが 駄目でした。 ・Visual Studio 2005でコンパイルしました。
fopen(・・・, "w")じゃなくてfopen(・・・, "rw")でやってみたらどうなる?
"rw"なんてあったっけか・・・? "w"で開くと読めない気がする それをやりたいなら"a+"じゃないの?
rwなんて無いか。 ファイルを開いて、読み書き同時にやることなんて、やったこと無かったな。
668 :
663 :2008/07/31(木) 23:13:01
読み書きしたいんならよく使うのは"r+"か"w+"だと思う tmpfile()はモード"wb+"で一時ファイルを作成してくれる "w+"だと既存のファイルがあるならtruncateして作成する "r+"はファイルがない場合は失敗する 読み書きを切り替えるときは間にfseek()/fsetpos()を挟むように汁
670 :
663 :2008/07/31(木) 23:29:49
>>669 ファイルの読み書きの時には + が必要なんですね
今までそんなことも気に掛けずにC言語の勉強してきました。
ありがとうございました。
初心者本では余り見かけないが、役に立つ課題。 空欄を埋めよ モード 目的 ファイルがあるとき ファイルがないとき "r" 読み込み 開く "w" 書き込み 開いて空にする "a" 追記 "r+" 読み書き "w+" 読み書き "a+"
Linuxについて質問があります。 コンパイル時に↓のようなメッセージが出ます。 *** glibc detected *** free(): invalid pointer: アドレス *** 調べてみると、 GCCのバージョンがC++アプリケーションと互換がない場合に起こると。 InkscapeまたはそのC++ライブラリ(libstdc++, libsigc++, libglibmm および libgtkmm)を同じバージョンのGCCで再コンパイルすれば、問題は解消する。 いうのは分かったのですが、「ライブラリを同じバージョンのGCCで再コンパイルすれば」というのが分かりません。 ライブラリは提供されているものだと思っているのですが、自分でもコンパイルできるのでしょうか? gccのバージョンは346で上記の記述されいるライブラリを使用していると思われるのは libstdc++ なのですが、 libstdc++のバージョンは詳しくわかりません。 libstdc++.so.6だとは思うんですが・・ 行き詰ってしまったので解決策あればよろしくお願いします。
同一人物か。
>>672 > ライブラリは提供されているものだと思っているのですが、自分でもコンパイルできるのでしょうか?
そうだよ。
できるんだすね どうやるのでしょうか ソースがないと無理だと思ってました 良かったら教えてください。
そうだよ。libstdc++のソースをダウンロードしてコンパイルする。
677 :
デフォルトの名無しさん :2008/08/01(金) 02:17:40
わかりました。 やってみます。 どうもです。
こんばんわ。夜遅くにすみません ネットゲームの解析等をやってみたいのですが デバッガ?数値?C言語?な状態です・・・ 一から勉強したいのですがどこで教わればいいのかわかりません わかりやすい講座サイトを知ってる方いませんか?もしよければ教えて頂きたいです。 返事お待ちしてます
スレ違いでしたら申し訳ないです。どのスレに行けばいいと一言頂いてもいいでしょうか…
681 :
デフォルトの名無しさん :2008/08/01(金) 05:07:42
>>679 つまり規約違反なことして俺TUEEEしたいんですねわかります
682 :
デフォルトの名無しさん :2008/08/01(金) 05:08:25
>>680 ネトゲのチーとスレでもいけば?そこにもなんの情報も無いけどw
チート板ってあったかの〜
・夏厨 ・ネトゲ厨 ・学生 ・ルール違反 ・文盲 三つ当てはまるだけで既に罪 五つも当てはめてるんじゃないぞコラ☆
すみません。 visualc++2008 をつかってるんですがコンパイルするときに 1>.\Debug\cal.exe.intermediate.manifest : general error c1010070: Failed to load and parse the manifest. U_U!$kLdK 1>~[ って出ます。 これはなんなんでしょう。 スレ違いでしたらすみません。
>>685 マニフェストが壊れてる。
それは新規に別のプロジェクトを作ってもでる?
>>686 プロジェクトを新しく作り直したらでなくなりました。
ありがとうございました。
688 :
デフォルトの名無しさん :2008/08/01(金) 09:11:56
Visual C++ 2008を使っています。 次のようなファイル名をドライブ名付きのフルパスに 変換する方法を教えてください。 %CommonProgramFiles%\test.dat
689 :
デフォルトの名無しさん :2008/08/01(金) 09:13:53
Visual C++ 2008を使っています。 次のようなファイル名をドライブ名付きのフルパスに 変換する方法を教えてください。 %CommonProgramFiles%\test.dat
>>672 それはライブラリの互換性を気にするより前に、アプリケーションプロ
グラムのバグを疑うべき。free()におかしなアドレスを渡しているって
いうのが直接の問題だから。
691 :
デフォルトの名無しさん :2008/08/01(金) 09:21:26
Visual C++ 2008を使っています。 次のようなファイル名をドライブ名付きのフルパスに 変換する方法を教えてください。 %CommonProgramFiles%\test.dat
692 :
デフォルトの名無しさん :2008/08/01(金) 09:22:31
Visual C++ 2008を使っています。 次のようなファイル名をドライブ名付きのフルパスに 変換する方法を教えてください。 %CommonProgramFiles%\test.dat
>>690 いやいや、リンク時の話
.so と .a のバージョンが違うぜって事
>>691 GetEnvironmentVariable
SHGetSpecialFolderPath
695 :
540 :2008/08/01(金) 09:49:50
おはようございます。
必要ないかもしれませんが、経過と報告を。
結局2重開放しないように修正しました。
>>598 まさしくその判定を使っているところがあったので、
削除はやめました。
>>613 初心者に毛が生えた程度です。
会社から2ch見れないので返事遅くなりすいません。
ありがとうございました。
696 :
デフォルトの名無しさん :2008/08/01(金) 19:13:42
struct { float x[100], z[100]; } formation; void init() { float MIN=20; int baseX[] = { 0, -1, 1, 0, -1, 1, 0, -1, 1, -2, 2, -2, 2, -2, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2 }; int baseZ[] = { 0, 0, 0, -1, -1, -1, 1, 1, 1, 0, 0, -1, -1, 1, 1, -2, -2, -2, -2, -2, 2, 2, 2, 2, 2 }; for(int i = 0; i < 25; i++) { formation.x[i] = baseX[i] * MIN; formation.z[i] = baseZ[i] * MIN; } } int main() { init(); return 0; } 実行するとエラーが出て、その原因がわかりません。文法がおかしいのでしょうか? VC++2008です >.\main.c(11) : error C2143: 構文エラー : ';' が '型' の前にありません。 1>.\main.c(11) : error C2065: 'i' : 定義されていない識別子です。 1>.\main.c(12) : error C2143: 構文エラー : ';' が '{' の前にありません。 1>.\main.c(13) : error C2065: 'i' : 定義されていない識別子です。 1>.\main.c(14) : error C2065: 'i' : 定義されていない識別子です。
int i; for(i = 0; i < 25; i++)
>>696 main.c を main.cpp に変更してみては?
699 :
デフォルトの名無しさん :2008/08/01(金) 19:17:46
もしくはc99モードでコンパイルしてみては?
700 :
デフォルトの名無しさん :2008/08/01(金) 19:30:07
(質問) 同じ配列を表すのに下記のように違う書き方があります。 書き方によって処理の速度に違いなど出てくるのでしょうか? int a[100] = { 1, 2, 3, 4, 5,・・・・,100 }; int *po; int cnt; po = a + 10; (1) for( cnt = 10 ; cnt < 100 ; cnt++ ){ printf( " %d", a[ cnt ] ); } ^^^^^^^ (2) for( cnt = 10 ; cnt < 100 ; cnt++ ){ printf( " %d", *(a + cnt) ); } ^^^^^^^^^ (3) for( cnt = 10 ; cnt < 100 ; cnt++ ){ printf( " %d", *(po++) ); } ^^^^^^^
>>701 出る場合もあるし出ない場合もある
個々のコンパイラの出来による
>>701 それを気にしないといけない状況ではないと思う
実測すればいい。
>>702 >>703 書き方によって処理の速度に違いがあるのなら
その書き方を意識して勉強していこうと思っていましたが
コ、コ、コンパイラとかそんなもん全然手が出せないので
地道に勉強していきます。
ありがとうございました。
>>701 VCだとデバッグ時に範囲チェックしてるせいで、[]より+の方が速かった。
「デバッグ時の」性能差になんか意味あんの?
最近のVCはデバッグ時とはいえ、配列の範囲チェックまでしてんのか? と思って、逆アセンブルでコード見てみたけど、範囲チェックらしき処理はなかった。
わざわざ逆アセンブルしなくても/FAオプションでよくね?
>>710 見たい箇所にブレイクポイントを入れて、逆アセンブルのウインドウ開くだけだから、
わざわざって言うほど手間じゃないよ。
そういうのがあるんだ。オールドタイプでスマヌ。
配列だと、範囲外にトラップしかけているってだけじゃないの?
ためしに、配列の範囲外に書き込んでみたら、ちゃんと実行時にエラーになったね。 int dmy1[10]; int tbl[100]; int dmy2[10]; tbl[100] = 1; ポインタ経由で書き込んでみても同じエラーがでた。 int *p = tbl; *(p+100) = 1; どうやってトラップしてるんだろ。
普通にデバッグレジスタ(DRn)使ってんだろ
>>714 こんな感じの処理
int tbl[100]; int trap; // tbに続けて配置
trap = 121212; // 適当なmagic number
int *p = tbl; *(p+100) = 1;
if (trap != 121212) abort(); // 書き換わってないかチェック
なもんで
*(p+110) = 1 と大きく跳ぶと引っかからない。
>713と>715は推測しか書いてない件。
CL /RTC1 でそのチェックがかかるはず。 VisualStudioを使ってるならデフォルトオンになってると思うよ。それで見解に差が出ている。
>>718 「脳内が如何に多いのか」、多少無理のある誤読でもいいから、
とにかくわかりたくて仕方がないんだよ。
思春期の自尊心ってそういうもんでしょ?
vector<string>の宣言時に一括して配列へ文字を 代入したいのですがそういう事は可能でしょうか? javaとかだとこんな感じの事です。 var s1 = ["【", "】"]; 散々調べたのですが見つからなくて。
つ boost::assign
#include <iostream> #include <string> using namespace std; int main() { string s1("【" "】"); cout << s1 << endl; } まあ、そういうことじゃないのは分かってるけど。
725 :
724 :2008/08/03(日) 00:36:05
あれ、なんか俺全然勘違いしてるorz orz orz
vectorなくなてるww
static const char * const initial_strings[] = {"boo", "foo", "woo",}; std::vector<std::string> > strings(initial_strings, sizeof(initial_strings) / sizeof(* initial_strings));
>>717 709だけど、おれは別に脳内じゃないぞ。
関数を抜けるときにある範囲チェックを見逃してたけど、それは「範囲チェックで配列アクセスが遅くなる」って
話題とは関係ないから。
気にするな、技術的考察が出来ない
>>717 はどうせ初心者だろう
730 :
デフォルトの名無しさん :2008/08/03(日) 10:09:58
template<int N> class Test { public: Test() { ??? } private: double values[N]; }; このvaluesをコンストラクタで全て0.0にしたいとき、 どんな方法が環境非依存でベター? std::fill_n?
731 :
デフォルトの名無しさん :2008/08/03(日) 10:18:06
1994年の参考書で #include "stdio.h" main( ) { int ans=10; printf("%d\n",ans); retrun 0; } と書いてあったんですけど、これであってますか?
もっと新しい本読もうぜ・・・
>>730 パソコンなら問題ないんじゃね。
組込み機器で使おうと思ってるなら、標準ライブラリが存在しない場合も考慮して
for ( int i = 0; i<<N; i++ ) { values[i] = 0.0; }
とか?
>>731 あってるというのはどういう意味?
コンパイラを通してみれば、文法があってるかどうかは確認できるよ。
人間の目でチェックするより信頼できる。
動作があってるかどうか確かめるなら、実際にコンパイルして動かしてみるといいよ。
にちゃんねらの脳内で実行するより信頼できる。
> #include "stdio.h" > main( ) その参考書は捨てて良い。
>>733 標準ライブラリとかは使えるとして、
なんか定番の初期化の方法とかあるのかな〜と思って。
tnks
737 :
デフォルトの名無しさん :2008/08/03(日) 11:22:23
何度も文字の型変換をしなければならないのですが、最終的に文字化けしてしまいます。 何処がおかしいでしょうか? font->draw()は画面に文字表示する関数です。 void draw(const wchar_t* text, Point position,Color color) ---------------------------------------------------------- std::string stdstr="自民党総裁"; const char* cstring = new char[256]; cstring = stdstr.c_str(); wchar_t wcstring[sizeof(cstring)*2]; MultiByteToWideChar( CP_ACP, 0, cstring, strlen(cstring), wcstring, sizeof(wcstring)); font->draw(wcstring,Point(0,0,0,0),0xFFFF0000); ------------------------------------------------------------ ↑では「自民党総裁 」の後ろに意味不明な文字が何個か表示されてしまいます。 単純に font->draw(L"自民党総裁",Point(0,0,0,0),0xFFFF0000); とした場合はきちんと表示されます。
>const char* cstring = new char[256]; >cstring = stdstr.c_str(); char[256]分がメモリリーク >MultiByteToWideChar(CP_ACP, 0, cstring, >strlen(cstring) '\0'が含まれないので、wcstringにもL'\0'が付かない
739 :
デフォルトの名無しさん :2008/08/03(日) 11:34:29
>>738 ありがとうございます。
して、、どう書けばよろしいのでしょうか・・・
>>737 wchar_t wcstring[sizeof(cstring)*2];
やりたいことはわかるけど、ポインタのサイズの2倍の個数の文字分
を確保するというコードになっている。(32btiプロセッサなら8文字)
"自民党総裁"は五文字だからたまたま納まっているけど、意図したい
のはそうじゃないでしょ?
741 :
737 :2008/08/03(日) 11:47:35
すいません、要するにどう書けばいいかをおしえてください。 その方が、どこがおかしかったか理由が類推しやすいので 理解しやすいです。 今のところ原因が全く分からないので 途中の理由を書かれても何のことか理解できないです;;
ちなみに wcstring[sizeof(cstring)*2] ='\0'; などと最後にくっつけてみましたが 変な文字が減ったものの完治はしませんでした。
std::string stdstr = "自民党総裁"; wchar_t wcstring[256]; MultiByteToWideChar(CP_ACP, 0, stdstr.c_str(), -1, wcstring, sizeof(wcstring));
>wcstring[sizeof(cstring)*2] ='\0'; おいおいメモリ壊してないか?
746 :
デフォルトの名無しさん :2008/08/03(日) 11:58:18
>>743 ありがとうございます。
でも
>>737 の変換は全部通さないといけないので省略はできないのです。
実際のソースは関数に渡してたりしていて、そのせいでこの変換が必要なんです。
>>744 wchar_t wcstring[strlen(cstring)*2];
MultiByteToWideChar(
CP_ACP, 0, cstring, strlen(cstring), wcstring, sizeof(wcstring));
wcstring[strlen(cstring)*2] ='\0';
としたらコンパイルできませんでした;;
747 :
デフォルトの名無しさん :2008/08/03(日) 12:03:05
あと、 const char* cstring = new char[256]; とか wchar_t wcstring[256]; みたいに適当に決め打ちするのってよくないですよね?
>全部通さないといけないので省略はできないのです。 言ってる意味がわからないんだが・・・
>>748 std::string → const char* →wchar_t
という順序で必ず変換をしないといけないということです。
>>747 もうちょっとC言語の基本しっかりしてから見直したほうがいいと思う。
確かに決めうちはよくないけど、それ以前に言語の動作が分かってない。
現状の知識でプログラム書いても正しいものにならないよ。
const char* cstring = stdstr.c_str(); std::vector<wchar_t> wbuf(stdstr.length()*2+1); MultiByteToWideChar( , , stdstr.c_str(), stdstr.length(), &wbuf[0], wbuf.size()); font->draw(&wbuf[0],Point(0,0,0,0),0xFFFF0000);
>>749 意味がわからん・・・
>>743 は実質、const char* → wchar_t なわけだが。
ATLのCSringぐらいのものが標準に含まれて欲しい・・・・
std::stringがあるだろ。CSringはstd::stringが無かった頃の遺産だよ。
>>752 実際のソースは関数を跨いでるので、
その引数にあわせてあの順序で変換しながら渡さないといけないんです。
>>749 宿題?
std::string → const char*なんて、c_str()でしかないと思うけど
std::wstring mbstowcs(const std::string &s) { int len = MultiByteToWideChar(CP_ACP, 0, s.data(), s.size(), 0, 0); std::vector<wchar_t> vec(len); MultiByteToWideChar(CP_ACP, 0, s.data(), s.size(), &vec[0], len); return std::wstring(vec.begin(), vec.end()); } こんな感じかね エラー処理省略してるが 標準C++の範囲でも一応エンコード変換できるっちゃできるけど 実装や信頼性がまちまちだったりするのがどうもな
>>755 std::string str = "a";
const char* cs = str.c_str();
f(cs);
と
std::string str = "a";
f(str.c_str());
が同じってことは分かる?
>>754 multibyte<->widechar変換の機能がほしいとか
CStringAのようにmbsをケアしてほしいとかいう意味じゃないの
だから順序守ってください・・・ なんで質問の条件無視して話し勧めようとするんですか・・・
>>760 ここはべつに君のための場所ではないからだよ
2chをカスタマーサポートセンターか何かだと思ってるのかい?
その順序ってのが意味不明だからだろ
要するに
>>737 の形は崩さずに少し弄って直したいってことだろ
>>751 で何が不満なんだよ?
自民党総裁とか書いてる時点で厨くせぇと思っていたが
あはははは おもすれー
std::string str = "a"; const char* cs = str.c_str(); f(cs); と std::string str = "a"; f(str.c_str()); これが同じなのは分かります。 ですがとりあえず下の順序を守ってください。 stdstrからスタートして、 const char*を必要最小限用意してそれに代入し、 最終的に必要最小限のwchar_tに出力してください。 std::string stdstr="自民党総裁"; const char* cstring = new char[256]; cstring = stdstr.c_str(); wchar_t wcstring[sizeof(cstring)*2]; MultiByteToWideChar( CP_ACP, 0, cstring, strlen(cstring), wcstring, sizeof(wcstring));
>>767 >これが同じなのは分かります。
下の文章・ソースを読む限り、分かってないです。
ポインタとsizeofの勉強しておいでよ。 そのソースでどれだけバカなことやってるか分かるから。
wchar_t wcstring[sizeof(cstring)*2];ってなんだ
とりあえずなおったのでもういいです。
>>770 それを言う理由ってなんですか?
おかしいのは分かってるんで、だから質問してるわけですが。
>>769 じゃあもうこのスレいりませんね。
どの質問も勉強して来いで終了ですね。
先生にconst char*型の変数を使うよう言われたんだと予想
何ムキになってる?カワイイw
const char* cstring = new char[256]; cstring = stdstr.c_str(); ここでnew char[256]で確保した領域へのポインタは上書きされちゃってるけど どうやってdeleteするつもりなんですか newの意味ちゃんとわかってる?
>>775 >>746 の「そのせいでこの変換が必要なんです」のようなことを言うには、
知識が足りなさ過ぎるってことだよ
もういいって言ってるんだからいいんじゃね?
sizeof(cstring)っていくつになると思う? 256を期待してるなら間違いだぞ 4か8になるはずだ(環境による) どうしてかはちゃんと調べることだ
>>775 人の話を聞いて理解を深めていこうとする人、ちゃんとコミュニケーションが取れる人には
ちゃんと教えてくれると思うよ。教えたがりも多いし。
説明はいいから俺の望む形で答え教えれ、なんていうからこんな流れになる。
しかもその望む形が意味不明だしなw
理解はしてます どう書けばいいかだけ教えてくれればいいんです バカにしないで下さい
本人でない釣りの可能性に注意
実際はこんな感じです。
クラスのメンバとしてstd::string stdstrを持ってます。
これにはstdstr = "自民党総裁";などと代入してあります。
で、引数がconst* charの関数にそれを渡します。
その際は、単純にstdstr.c_str()を使って渡します。
でその関数の中で文字表示font->draw()を実行しますが
それはwchar_tを要求します。
というわけでconst* charへはc_str()を使うだけでいいのは分かるのですが
質問するに際し、関数の受け渡しの部分を省略するために
>>737 のように書いてみたわけです。
だから無駄なことをやってるのは分かるんですが、
もし実際書くとしたらどう書いたらいいのかということが気になります。
>>787 質問する時はなるべく省略するべきではないこと、やむをえず省略した場合は、
その部分の都合は相手には伝わらないのが当然だということを理解してください。
>>787 もう一度言うが
std::string str = "a";
const char* cs = str.c_str();
f(cs);
と
std::string str = "a";
f(str.c_str());
は同じなんだよ。少しは考えろ。
>>788 わけあってこういう事がしたい、って何度も何度も何度も何度も断った上で
お願いしてるんですから、別にそれ以上詮索する必要なんて無いですよね。
田代趣味があるならともかく。
>>789 だからそれは知ってるって言ってるでしょ。
少しは考えろ。
南風受けながら
もう触るなよ。
「とりあえずなおったからもういい」んじゃないのか
めんどくせえな
std::string stdstr = "自民党総裁";
const char *cstring = stdstr.c_str();
wchar_t wcstring[256];
MultiByteToWideChar(CP_ACP, 0, cstring, -1, wcstring, sizeof(wcstring));
これでいいか?
>>743 と意味は全く同じだがな
>>789 いや、同じじゃないし。
前者はありがちなミス。
>>787 ,
>>791 MultiByteToWideChar(CP_ACP, 0, stdstr.c_str(), -1, wcstring, sizeof(wcstring));
を
const char* cstring = stdstr.c_str();
MultiByteToWideChar(CP_ACP, 0, cstring, -1, wcstring, sizeof(wcstring));
にする理解力/応用力すら無いならプログラム書くのは諦めた方が良い。
const char* cstring = new char[256]; これって何を意味しますか? これは不正ですか?
おまえらつられすぎw
おまいらの優しさに全俺が泣いたwwww
>>797 勝手に他人のやることを規定するなどという
思い上がりも甚だしいお前は人間諦めたほうがいいんじゃね。
>>796 いや、同じだし。
おそらくc_str()の結果の有効期間を勘違いしてるよ。
>>798 char型256個分の領域を確保して、そこへのポインタをcstringに納める
そこに文字列を入れたかったらstrcpy(cstring, stdstr.c_str())とかする
cstring = stdstr.c_str()はポインタを上書きするだけだからアウト
>>790 char 型で要素数256の配列の領域をnewで確保した。
cost char * 型の変数cstringを宣言・定義した。
その確保した領域の先頭アドレスをcstringの初期値として設定した。
その一文自体は不正ではない。
うははははー おもすれ
>>803 >そこに文字列を入れたかったらstrcpy(cstring, stdstr.c_str())とかする
ならそういう書き方を教えてくれたらよかったのに・・・。
わざわざ領域確保して云々って条件で聞いてたんだから。
初心者未満なのに何故あれほど強気なんだろうな
宿題は宿題スレへ、としか・・・w
strcpyすら知らないくせに教えてもらっといてケチ付けるなんてどんだけ傲慢なんだ ゆとりこえー
馬鹿すぎる
>>811 strcpyで書けるならその書き方で教えればよかっただけじゃん。
かたくなに秘密にする意味って何www
>>802 仕様書再確認しちまったじゃねぇか!
やっぱ違うぞ。
>>813 「const char*の領域を新たに確保すること」という条件が付いた課題で無い限り、
>>737 ,
>>787 にstrcpyを使うのは馬鹿でしかないから。
どうでもいいけど使った後はちゃんとdelete[] cstringしろよ delete cstringじゃないからな
それ以前にconst char*じゃstrcpyのdstにできない 何のためにconst付けてんの
>>814 何がどう違うんだよ・・。
str.c_str()の戻り値は、strの非constメンバ関数が呼ばれるまで有効だぞ。
>>815 だから何度も何度も何度も何度も”あえて”そう書くとしたらって断り入れたのに。
>>820 つまりお前の説明が下手過ぎたってことだ。
それから宿題なら最初からそう言え。
>>820 const付けてる時点で中身変えるつもりないんだろ(とみんな理解したはずだ)
MultiByteToWideCharを呼ぶまでに中身が変わらないならnewだのstrcpyだのは全く必要ない
中身変えたいならconst消せよ
const char* cs = str.c_str();//※
f(cs);
※の時点でEOSが来てるからc_str()が作った一時オブジェクトが消えてるかもしれない
f(str.c_str());
fにc_str()の戻り値が渡されて、fの実行が終わってからEOSだからfの実行中は一時オブジェクトが生きてることが保証される
こうですかわかりません
c_strってstring内のメンバへのポインタ戻すだけなの?一時オブジェクト作るの?
前者なら
>>819 の言う通りだし後者なら上で書いた通りになると思うんだけど
>>824 コンストラクタ/デストラクタを持たない型の値を
一時オブジェクトとは普通言いません。
>c_strってstring内のメンバへのポインタ戻すだけなの?一時オブジェクト作るの? どっちもありうる。 が、実際はポインタ返すだけの実装ばっか。
一時オブジェクトは作らない。
>>824 >819 の言うとおり、次の非 const メンバ関数を呼ぶまでの間有効なポインタを返す。
一時オブジェクトは作られない。
やっぱり >814 が何を言ってるのかわからない。
仕様上はどっちとは書いてない。 でも一時オブジェクトを作るのだとしても非constメンバ関数が呼ばれるまで有効なようになってなきゃライブラリが規格違反ってこった。
戻り値const char*でどうやって一時オブジェクト返すんだよ。 作れねぇよ。
そうですね char配列の一時オブジェクトなんか作れるわけないな。勘違いしてた だったらstrの非constメンバ呼ばれるまでは大丈夫そうだけど
>>830 一時オブジェクトを返すんじゃなくて、
stringが内部的に一時オブジェクトを作ってその中で確保した領域のポインタを返すことはありえる。
でも、そんなことはどっちでもいいよな。
>>832 お前も要勉強だなw
それやったら f(str.c_str()); でf値が渡る前に
その一時オブジェクトはデストラクトされてるよ。
std::stringの内部表現がC文字列ではない場合は、C文字列に格納し直してその先頭ポインタを返すという可能性がある。
(現存するstd::stringにそんな実装は無いかも知れないけど)
故にc_str()はthrow()ではない。
何で今更こんな話題で盛り上がってるのかと思ったが、
>>814 のおかげということが分かった。
const_cast<char*>(str.c_str())[0] = 'a';とかやってもstrが無事であるようにとか 別に決められてるわけじゃないんだろ
何このスレ… 初心者は歓迎だが、 質問のしかたも分からない馬鹿は帰れ
>stringが内部的に一時オブジェクトを作ってその中で確保した領域のポインタを返すことはありえる。 仮にこうなるとすると、それが開放されるチャンスはどこにあるの?
>>832 一時オブジェクト ≠ 一時的に存在するオブジェクト
一時オブジェクトは規格の用語なので他の意味に転用しないように
>>837 次にc_strが呼ばれて作り直すときとか
string自体のデストラクタとかじゃないの
>>834 それと戻り値の有効期間や一時オブジェクトの話は関係無いぞ。
その実装ならstringのメンバに保持しておく必要がある。
>>839 質問あっての回答だろうw
エスパーじゃないんだからw
>>837 実装を考えてみると、stringのメンバにcchar*戻値用のvectorとかchar*とか
あって、そこに確保して返すことになるんじゃないか。
解放タイミングはstringのデストラクト時で。
一時オブジェクトってのは語弊があるね。 テンポラリオブジェクトとか読みかえれ
語弊がない単語キボンヌ
戻り値用のメンバ変数
で、仮にそういう変な仮メンバを中に持ってる実装だとしても、単に先頭返すだけだとしても、 非constメンバ呼ばれるまでは有効なことには変わりないんじゃないの
>>849 そうなんだけど一部の人が違うと言い張ってる。←いまここ
>>814 も仕様書確認してって言ってるから、
その仕様書書いた奴が元凶かと。
やはり仕様書としては「The C++ Programming Language」の
PDFを持っておくべき。
あと関係無いけどD&Eオヌヌメ
なんという盛り上がり・・・ レス速度を見ただけでワクワクしてしまった 俺は間違いなく出遅れ / ̄\ | ^o^ | \_/
規格書なんて普段よまんから読み方わかんねえ Requires: The program shall not alter any of the values stored in the array. Nor shall the program treat the returned value as a valid pointer value after any subsequent call to a nonconst member function of the class basic_string that designates the same object as this. 「nonconstなメンバ関数呼び出しのあとは返されたポインタをさわっちゃいかんよ」 とは書いてあるけど「それまでは大丈夫だよ」ともはっきり書いてないな でも、この書き方だと大丈夫だと受け取っていいんだろな
>>814 が仕様書のどこを典拠にしてそう言っているのか聞きたいな
やっぱりC#が最強だな
スレ違い
std::stringに"abccbaabc"という文字列が入っているとします。 このstringから"abc"を取り除く(つまり"cba"にする)には、どうやればいいですか?
string& replace(string& s, const string& from, const string& to) { string::size_type m = 0, n; while ((n = s.find(from, m)) != string::npos) { s.replace(n, from.size(), to); m = n + to.size(); } return s; } こんなもんでいいと思うが boost::regexでも使っとけ
boost::algorithm::erase_all(s, "abc");
861 :
858 :2008/08/03(日) 15:49:44
>>859 ,860
どうもです。
STLの範囲だけでやろうとすると結構めんどくさいんですね。
erase_allがぴったりでした。
862 :
デフォルトの名無しさん :2008/08/03(日) 15:51:37
864 :
デフォルトの名無しさん :2008/08/03(日) 15:54:32
すまんさっきからageっぱなしだった
867 :
デフォルトの名無しさん :2008/08/03(日) 15:55:23
どっちが正しいんだよ!!!!!!!
自虐的だな。
やっぱりC#が最強だな
俺が正しい。
すまんさっきからageっぱなしだった こうですかわかりません><
どっちが正しいんだよ!!!!!!!
ここまで全部俺の自演。
どっちって何と何か分からなくなったよ
>>730 VCならTest() : values() {}
で規定値で初期化されるみたい
ただしC4351が出る
(「環境非依存で」って書いてあるのにね)
#ifdef XXX // Debug用コード #else // Release用コード #endif こんな感じでDebug用とRelease用をわけるときのXXXの部分に入るマクロが思い出せないです。 何か標準であったと記憶しているのですが何でしたっけ?
VCだったらDEBUGとか_DEBUGとかかしら コンパイルオプション見てみたらいいんじゃ C/C++のプロパティで-D_DEBUGとか書いてあったら_DEBUG
>>887 thx
コンパイラ依存なんですね。
環境はVC2008EEで、_DEBUGでした。
>>886 標準で決められてるのは assert() の有効無効を切り替える NDEBUG 。
890 :
886 :2008/08/03(日) 19:48:17
>>889 あー標準にもやはりありましたか。
そっち使うことにします。
ありがとうございました。
891 :
デフォルトの名無しさん :2008/08/03(日) 19:50:51
#include <stdio.h> #include <winsock2.h> int main() { TCHAR str[1024]; WSADATA wsaData; WSAStartup(2 , &wsaData); printf("バージョン = %d.%d\n記述 = %s\n状態 = %s\n" , (BYTE)wsaData.wHighVersion , wsaData.wHighVersion >> 8 , wsaData.szDescription , wsaData.szSystemStatus ); WSACleanup(); return 0; } 超初心者です。丸写しのコピーです。VC++2008でwindowsアプリケーションで貼ったら4つエラーが出たのですが、プロジェクトの設定が悪いのでしょうか。 アドバイスお願いします。っていうかWinsockの質問はここで良いですか?スレ一覧にも無いようですが、人気が無いのでしょうか。
エラーが出たときはエラーメッセージも貼った方が 他の環境使ってる人も答えてくれやすい winsockもここでいいんじゃね? 俺ここで教えてもらったことあるよ
どうせws2_32.libだろ
WinMainにしたら1>c:\users\documents\visual studio 2008\projects\作る!\作る!.cpp(4) : error C2632: 'int' と 'int' の 2 つの型指定子のあ このエラーだけに成りました。ws2_32.libについてはよくわかりません。
プロジェクト右クリック−プロパティ 構成プロパティ−リンカ−入力 追加の依存ファイルにws2_32.libと書いてOK もっかいビルド
896 :
643 :2008/08/03(日) 20:17:09
教えていただいた単語を組み合わせて色々調べてみましたが、結局各ユーザーによる手動設定の方法しか見つかりませんでした。 これをCやC++のプログラム中で実行することを解説したサイトは無いのでしょうか。 もしかして一般に公開できないほど価値のあることだったり・・・?
delete this ってできます? 今自分のいる足元を壊すみたいな。
>>896 レジストリキーが分かってるなら
それをRegOpenKeyExとかRegSetValueExとかで追加したり変更したりはできるじゃん?
そういう意味じゃないのきゃ?
>>897 できる
WindowアプリでWM_NCDESTROY受け取ったらdelete thisで自殺するような コードはわりと見かけるな
>>896 RegSetValueEx HKEY_CLASSES_ROOT DefaultIcon
IUnknownの実装とかでもdelete thisは使う
904 :
643 :2008/08/03(日) 20:27:57
>>899 ,902
レスありがとうございます。
その関数の存在自体分からない状態でしたので、加えた上で改めて検索してみたら求めていたサイトが出てきました。
本当に助かります。
delete thisは、以降にメンバに触らなければ問題無い。 ただし行儀悪いコードには違いない。
よく分からんけど無意味にグローバル変数使ってるのと int mainじゃないのがちょっと気持ち悪いと思った。
908 :
897 :2008/08/03(日) 21:30:49
delete thisはメモリ戦略を限定しちゃうからね スタック配置不可、スマートポインタに格納不可、配置new不可、と。
自殺クラスはそれをしないと手の届かないものに限定的に使うのであって、 自動変数にしたりスマポに入れたり配置newしたりするようなクラスには不要だろ。
RAII技法に合わないのが致命的
それをしないと手の届かないものってどんなのだろ? いや、普通に思いつかなくて。
>>913 ゲームのタスクシステムみたいなもので、リストでつながってる要素が
自殺したい時など。外部に消滅を管理する部分を設けなくても済む。
915 :
デフォルトの名無しさん :2008/08/04(月) 17:05:47
C++で、 0からiまでの整数を入力させ、それ以外の数や、文字が入ったときはもう一回入力させることで、 確実に0からiまでの整数を戻す、以下のような感じの関数を作りたいんですが… int nyuryoku(int i=1){ int a=0; do{ cin>>a; }while(a<0 || i<a); return a; } 数字以外の文字が入力されたときに固まったり無限ループになってしまいます。 istreamの問題だと思うのですが、対処が出来ません;; どなたか教えてください
>>915 そんな横着しないでgetlineしてパース汁
Cの勉強を始めたいのですが、入門書でバイブル的なものってあったリするんですかね? それとも書店に売ってる本や雑誌の中から良さ気なのを適当に買ってきて始めても問題ないのでしょうか スレチだったら申し訳ないです…
本の最初のほうでmain関数というものが紹介されますが、 void main() とか void main(void) と書いてある入門書は避けてください。 あとは第一印象でいいんじゃね。
俺は 「柴田望洋」 って人の本を図書館で数冊読んで勉強したよ. かなり判り易く書いてあったと思うけど,だいぶ昔の話だから今は もっと良書があるかもね.
main(argc, argv) int argc; char *argv[]; { と書いてあったら古すぎ。K&R初版レベル。
望洋はISO C++の本一冊も出してなかった気がするが。 今となっては絶対買ってはいけない地雷の一つじゃね
マナ本はどうよ
924 :
918 :2008/08/04(月) 21:10:22
皆さんレスありがとうございます。 やっぱり特にこれがいいってのはあんまりないみたいですね。買う際の参考にさせてもらいます。
newで割り当てメモリサイズを、後から調べることってできないのでしょうか? char *ptr = new char[10]; 〜〜〜 //ptrのアドレス先に、いくらメモリを割り当てているか知りたい
vectorみたいに割り当て時にサイズを記録するしか無いのでしょうか
そうです。サイズを記録しておいて下さい。 慣れてくると、サイズでなくbeginとendで扱うようになるでしょう。
たぶん無いんじゃないかなぁ 前にVCで探したけど見つからなかった 見つかったら教えてください
うんこが苦いのはどうしてですか? 下痢便や軟便は特に超苦いです。
苦い事自体初めて知りました、はい次
>>926 空でないデストラクタのある型なら調べられない事もない場合があるが、
素直に vector 使っとこうぜ。
CString みたいなひねった記録のしかたをすることもできるが、
あれは可変長引数に渡せるようにするためのトリックであって
普通は必要になんない。
(まあ、空でないデストラクタのある型の場合
自動的にそんな感じにするコンパイラもあるわけだが)
HeapSize _msize
やっぱりCString最強だな
>>935 いやそれさあ、newの返値に対して使えるの?
>_msize は,アドレスが block である割り当て済みのヒープブロックのサイズを返します。
>このブロックは,malloc,calloc,または realloc を使って割り当てられている必要があります。
>最初にブロックを割り当てるときに要求したバイト数より大きなサイズが返される場合があります。
しかもmallocに要求した数字より大きい数字が返ることがあるって。
まあ本人が良いなら良いかw
>しかもmallocに要求した数字より大きい数字が返ることがあるって。 極めて普通に感じるけど。 9byte要求して その環境でのalign(4byteや8byte)に適合するサイズに調整されて 12byteなり16byteなりを確保したのと全く同じように振舞った。 その結果、9ではなく12なり16なりの 要求した数字より大きい数字が返るってことだけど。
多分そういう意味じゃないw
>>926 の時に10が帰ってくることを期待するなら使えないってことを言ってるんだろ。
想像力無さすぎる。
>>926 char (&ptr)[10] = (char(&)[10]) new char[10];
で sizeof(ptr) は 10 になるがお友達にはなりたくない。
胆汁は苦い
だから下痢便も茶色くて苦い
とんだ糞スレだわ
夏ですなあ
質問が無いと言うことは困っているプログラマもいない,平和でいいじゃないか
>>937 配列のアクセス範囲が知りたいのじゃなく、使用してるメモリ量が知りたいので
>要求した数字より大きい数字が返ることがある
ってのは問題なし。
newで割り当てた全ての型に、正常に使えるのかは気になるところですが。
いやそれ以前にnewに対して使えるんだ。 なんかnewの返り値をfreeに渡すみたいで気持ち悪いんだよね。
まぁ、newのメモリ確保部分は大抵mallocだしね。 デバッグに使う分には良いんじゃない?
950 :
デフォルトの名無しさん :2008/08/05(火) 13:57:44
関数の呼び出た回数を出力するにはどうしたらいいですか? 関数内でcount=0;とし、count++;で数えていくのはわかるのですが…
>>950 そこまでわかって何が知りたいの・・・?
countをstaticにしておけばいいでしょ
基本型ではない配列newに対して使える? デストラクタ回す関係で、総サイズ以外に確保要素数もどこかに 書いてありそうなんだが…、コンパイラの実装依存か
// 1 int count = 0; void hoge(void) { ++count; } // 2 void fuga(int * pCount) { ++(*pCount); } // 3 void hage(void) { static int count = 0; ++count; printf("%d", count); } さあ選べ。
954 :
951 :2008/08/05(火) 14:05:06
>>952 YOU、これ使っちゃいなYO
A* p = new A[3];
std::cout << reinterpret_cast<int*>(p)[-1] << std::endl;
delete[] p;
もちろんデバッグ目的限定で。
>>955 VC++7.1とgcc3.4.4で試したけどどっちも駄目だった
それが動くのってどういう処理系?
>>956 vc++8(2005)と記憶の中のvc++6。
>>957 え?
#include <iostream>
int main()
{
char *p = new char[10];
std::cout << reinterpret_cast<int*>(p)[-1] << std::endl;
}
これ、俺のVC++8では、917968
とか印字されるけど。
>>958 そりゃデストラクタ無い型なら出ないよ。
持つ必要無いから。
ああ、そういう意味か。 理解した。
ついでに。 デストラクタがある型の場合、 mallocで確保したメモリの先頭を要素数に使う(実装が多い)ので HeapSize, _msizeにはそのアドレスを渡さないといけない。 ちなみにVC++のmallocは実質HeapAlloc。 A* p = new A[3]; HeapSize(GetProcessHeap(), 0, reinterpret_cast<int*>(p)-1) _msize(reinterpret_cast<int*>(p)-1)
WINAPIのシリアル通信のSetCommState()なんですが、ボーレート115200までは成功するんですが、230400でパラメータが正しくないと出ます。 COM1でこれ以上の速度はむりなんでしょうか?
c/c++スレに書く内容じゃなくね?
>>962 そもそもCBR_115200はあるけどCBR_230400なんてないんだが。
スレ違い失礼しました
stringに格納されている文字列を全部小文字にするには、tolower関数で1文字ずつ変換していくしかないのでしょうか?
>>966 boost string_algoのto_lower/to_lower_copy使えばいい。
中でやっていることは結局1文字ずつstd::tolowerなんだけどね。
Boostが嫌なら自分でそういう関数を作るが由。
968 :
966 :2008/08/05(火) 23:51:23
969 :
966 :2008/08/05(火) 23:52:06
970 :
966 :2008/08/05(火) 23:52:49
2重書き込みになってしまいました。ごめんなさい。
std::mapのメンバ関数のfindですが、std::find_ifのように関数オブジェクトを使って比較することはできないのでしょうか?
>>971 mapの仕組み上できない。
mapは構築時に指定された比較方法で内部的にソートしているので、
違う比較方法に対してはソートされていないvectorとかと同程度かそれ以下の効率しか出ない。
例えばあるクラスAをnewでインスタンス化して、このインスタンスのメンバとして newで生成したインスタンスBを保持していた場合、Aのインスタンスをdeleteする前に、 デストラクタなどでBをdeleteしなければなりませんか?
>>972 なるほど。
でも、この関数オブジェクトって大小比較ですよね。
findの時はどんな仕組みになっているのでしょう?
まさかcomp(a, b)とcomp(b, a)の2回調べているのですか?
operator <じゃなかったっけ
>>974 そういわれれば二回比較しないと確定できませんね
>>974 まぁ実装のアルゴリズム次第としか言いようがないんだが、
findの大抵の(効率の良い)実装ではoperator<だけでも(operator==を使わなくても)
検索に必要な比較回数の期待値は精々1回ぐらいしか増えないはず。
試しに二分探索をoperator<だけで書いてみるようなコードとか、
書かなくてもいいから頭の中でどうなるか考えてみると面白いかもね。
>>980 次スレよろ
>>977 比較回数が1回程度しか増えないとは、うまいアルゴリズムがあるもんなんですね。
二分探索について調べてみます。
どうもありがとうございました。
979 :
sage :2008/08/06(水) 18:18:37
new で確保したクラスオブジェクトをdeleteした際、 そのクラスオブジェクトの、newで実体を確保したデータメンバ(ポインタ)は、同時に自動的にdeleteされるのでしょうか?? ご教示頂けると幸いです。
されますん
>>979 メンバで保持してるポインタはdeleteされない。放置。
確保したクラスがデストラクタでdeleteして無い限り、ポインタは解放されません。
「されます」の変化形なのか「されません」の変化形なのかわかりません><
984 :
979 :2008/08/06(水) 18:23:40
ありがとうございます!
struct hoge { fuga *pointer_; }; で hoge *p = new hoge(); p->pointer_ = new fuga(); delete p; とやったときに、自動で(見えないところで) delete (p->pointer_); も実行されるかってことだよね? されません。 最近shared_ptrにべったりで、deleteなんて見てないや…。
986 :
979 :2008/08/06(水) 18:30:05
>>985 そんな感じです。
ありがとうございましたm(_ _)m
言語そのものの質問じゃないのですが、WIN32APIとDirectXを 使用したソースをG++でMake可能でしょうか? 現在VC++Express使ってるんですが、将来的にMSがExpress配布 しなくなったときに、ソース(ほぼ)そのままでフリー環境に逃げれるのか気になって。
心配しなくてもそのころにはコンパイラを気軽に買えるようになってるよ。 まあAPIやDirectXは結局はDLL呼び出しなんで、DLLが呼べればどこからでも使える。 ライブラリは互換性が無いので、gcc用に作るか作られたものをもってくればいい。
将来Expressを配布しなくなっても、 今配布してるExpressが使えなくなるわけじゃないんだから、 DVDに焼いて大事に取っておけばいいんじゃない
なるほど、可能なんですね。 取り越し苦労かもですけど、一安心しました。thx
携帯の俺が言うのも何だけど、 そろそろ次スレ立てた方が良い。
>>987 インポートライブラリをreimpで変換するだけだす。
>>987 DirectX9 関係では苦労します
DirectX10 は知りません
D3DX**** 系の関数を使用するときに注意が必要です
d3dx9.lib がスタティックライブラリなので vc 専用で g++ からは利用できません
g++ からは d3dx9_??.dll を使用できますが ?? 部分の数値が一致するものが対象のPCに存在しないと動きません
できれば vc を使ったほうが余計な苦労が無いと思います
ifstreamで開いたファイルのサイズを取得するにはどうすればいいですか?
std::ifstream f("test.txt", std::ios::binary); f.seekg(0, std::ios::end); std::size_t size = static_cast<std::size_t>(f.tellg());
>>996 どうもです。
サイズ求めるだけなのに結構めんどくさいですね。
stat()かそれに類する関数が大抵のシステムでは使えるはずだが、 標準ではないからな boost::filesystemにはそのものズバリのfile_size()という関数があったと思う
3行で面倒とか言ってたら何も作れんよ
面倒というか、ちょっと回りくどい感じはするね。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。