【初心者歓迎】C/C++室 Ver.49【環境依存OK】
1 :
デフォルトの名無しさん :
2008/02/20(水) 12:33:41
2 :
1だけど :2008/02/20(水) 12:36:25
>>2 一度だけ使った事があるよ
複数ファイルに分けないと説明できない事があったので
あと、スレ立て乙
newとか使ってきてて今さら思ったんですが int hoge; hoge = 1; や int hoge = 1; なんかはどっかにint1個分の領域が確保されているわけですよね?
5 :
デフォルトの名無しさん :2008/02/20(水) 12:57:15
あげとくよ
>>6 なるほど・・・スコープを抜けたら破棄されるわけか
ああ、それでnewにはdeleteが必要なのかなるほどー
すごい納得ありがとうございいます
ある言語のソースコードをCのソースコードに変換した後、 cstdioのsystem関数を使い、内部でbccを呼び出して Cのソースコードをコンパイルするプログラムをつくったのですが、 コマンドラインからだとコンパイルが通るCソースコードが、 このプログラムを使ってコンパイルするとエラーが発生して通りません。 プログラムの一部です -------------------------------------- string Command = ""; //略 if(system(Command.c_str()) == -1){ cout << "Error" << endl; } -------------------------------------- ここで、コンパイルが通るはずの"test.c"のようなファイルを作り、 Command = "bcc32 test.c"として実行すると、 「Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照)」 というエラーが発生します。 解決策をお願いします。 ちなみにこのプログラムはVisualC++2005Expressで作成しています。
>>8 コマンドプロンプト上で
bcc32 test.c
は成功する?
もし、失敗するなら bcc32.cfg または ilink32.cfg の設定ができていない可能性あり
どうすれば設定すればいいかは検索すればすぐ分かるはず
>>「Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照)」 main関数が無いって言ってるように見える・・・
11 :
9 :2008/02/20(水) 13:20:51
追記:エントリポイントを WinMain にするならコマンドラインオプション -W を追加しないといけない
>>9 コマンドラインで bcc32 test.c は成功します。
あと、別に、
#include<cstdio>
void main(){
system("bcc32 test.c");
}
だけを書いたプログラムを実行したところ今度はtest.cのコンパイルが通りました。
>>8 プログラムのカレントディレクトリとtest.cのパスの関係はどうなってますか。
〜\debug がカレントディレクトリで
debug\bfc.exe(作ったプログラム)
debug\system_test.exe(
>>12 のプログラム)
debug\test.c
となってます
>>14 system 関数を呼び出した時点では
test.c への書き込みが完了していないんじゃない?
コマンドの bcc32 の部分を type に置き換えて実行してみて
何も表示されないようなら system 関数の前にストリームをフラッシュするかクローズする
17 :
デフォルトの名無しさん :2008/02/20(水) 19:08:43
質問させてください キーボードの「ろ」のところにある記号は「U」で合ってますか? 半角じゃないので違うような気がするのですが 初歩的な質問ですみません よろしくお願いします
キーボードにも色々種類があってだな
C/C++と何の関係もない件について
20 :
デフォルトの名無しさん :2008/02/20(水) 19:25:31
>>18 そうなんですか すいません
>>19 今やってるプログラムにそれを入れなきゃなんです
お前の都合は知らないけどさ、こういう分別は義務教育中に分かっておかないと将来困るよ
C++でダイアログからファイルを選択し、ファイルをバイナリで開きたいのですが CFileDialogから取得したパスをfopenのrbモードで開く、という認識であっているのでしょうか 使用しているエディタはVS2005です。よろしくお願いします。
24 :
デフォルトの名無しさん :2008/02/20(水) 19:34:12
>>21 出ました ありがとうございます
>>22 あなたに将来を気にして頂かなくても結構ですよ?
>>24 もっと適切な場所で聞けって言ってるんだろ
>>24 >>22 の
”おまえに切れられる筋合いは無い”
という心の叫が聞こえる。
>>23 CFileDialogってMFCか?
だったら同じMFCのCFileを使うのが筋なんじゃないかな
fopenでもいいけどさ
29 :
デフォルトの名無しさん :2008/02/20(水) 19:46:45
>>28 すみません、MFCアプリケーションでの作成です。
プログラム初めてなものでただただ関数調べたもので…
基本的な事がなってないのでもう少し自分で調べてみます
アドバイスありがとうございました。
初心者歓迎・環境依存OKとはあるが、 C/C++とは関係ない質問等には答えるなよ。 馬鹿が付け上がります。
>>31 俺は今度から、キモイのが来たら嘘を教えることにするよ。
34 :
デフォルトの名無しさん :2008/02/20(水) 21:33:17
変なタイミングで人をなだめる奴は 大抵自分が落ち着いてない罠
****ptrとかってものを使ってみたいんだけどどうすればいんでしょうか? (表現おかしいかもしれないです) int *ptr, *p1, *p2, *p3, val = 10; ptr = p1; *ptr = p2; **ptr = p3; ***ptr = &val; printf("%d", ****ptr); こんな具合のことなんですがこれじゃだめみたいですorz 意味はないんですが、試しにやってみたいというだけです
int val = 10; int *p1 = &x; int **p2 = &p1; int ***p3 = &p2; int ****ptr = &p3; printf("%d\n", ****ptr);
あ、そっか int*型やint**型はまた別のものなんですね、再確認させられました ありがとうございます
Vectorクラス{ float x,y }があるとして、 Vector a( 0,0 ); Vector b = Vector( 0,0 ); 今まで大差ないと思ってたんだけど、bの書き方って馬鹿にされるかな?
大差はないが、Vector のコピーコンストラクタが public でない場合、下はコンパイルエラーになる。 たとえ最適化でコピーコンストラクタの呼び出しが省略されるとしても。
試しにやってみたらたしかにエラーに。 不便すぎるな… ありがとう
noncopyable の時に困るね。 他では大した差は無いけど。
デコンストラクタを解放とは別のタイミングで実行したいのでnewしたものをfreeで解放してますが問題ないでしょうか
>>43 デストラクタなのかコンストラクタなのかそれが問題だwww
>>43 placement new/delete 使え
freeするならメモリ確保にはmalloc使えということだな。
デコンストラクタワロタw
デコンストラクタ の検索結果 約 1,390 件
"デコンストラクタ" の検索結果 約 788 件
>>46 newをオーバーロードしてmallocで実装ということでしょうか?
>>52 new/delete
new[]/delete[]
malloc/free
対応関係を間違えるな。
>>52 T* p = static_cast<T*>(::operator new(sizeof (T))); // 領域のみ確保
new (p) T(); // コンストラクタを呼ぶ(placement new)
p->~T(); // デストラクタを呼ぶ
::operator delete(p, p); // placement delete(省略可)
::operator delete(p); // 領域を解放
#include <new> #include <cstdlib> class c {}; void* p = std::malloc(sizeof (c)); c* obj = new(p) c; //... obj->~c(); //... std::free(obj); malloc/freeでなくても、operator new/delete関数とかでもいいだろうけどね。
>>52 違う。配置構文newだ。
newは大抵mallocをラッピングしてて効率は悪い。
57 :
sage :2008/02/21(木) 03:23:25
言語の使い方ではないのですが、一応処理系の一部ということで 質問させて頂きたいのですが、静的リンクされたELFバイナリにおいて、 リンクされているライブラリのバージョンを そのバイナリから知る方法はあるのでしょうか?
すみません・・sageを記入する欄を間違えました。
カレンダー作りたいんで、各月何日まであるか年によって違うのでその法則を 教えて欲しいんだけどスレ違い?
年によって日数が変わる月は2月だけだろ・・・。 最近の小学校は閏年も教えんのか?
ありがとう2月だけなのか。習ったけど忘れてた
1752年9月も変わってるな
どうやって生きてるのか不思議だな
カレンダー作るのに当時生きてるかはあまり関係ないかと。 unix系のOS使えるなら、 cal 9 1752 でカレンダー出るな。
1752年9月がイリーガルなのは一部の国だけだけどな。
66 :
デフォルトの名無しさん :2008/02/21(木) 13:11:47
class ttt { public: int i; int j; double k; }; int main() { ttt t = {1,2,3.001}; structやclassがこういう風に初期化できるのを最近知ったのですが、これって普通に 使う書き方でしょうか?結構C++長いこと使ってきたけど、知らなかったよ。
C/C++を勉強し始めて1年の俺的には、クラスならメンバ変数公開しないのでやらない。そこはコンストラクタで。 PODな構造体なら hoge h = {0}; とか、 Win32APIで構造体のサイズを入れる必要がある物は WNDCLASSEX wc = {sizeof(WNDCLASSEX)}; とかやるけど・・・ 俺も疑問なんだけど、 hoge h = {0}; って感じで初期化って普通にやるの? 俺より何年もCやってる先輩が言うには、「そんなんで0フィルされるのか?memset使えよ」って言われたんだが。
68 :
デフォルトの名無しさん :2008/02/21(木) 13:22:38
Cを昨日から勉強しましたが、今日でやめます。
>>67 「0フィル」が「全ビットを 0x00 で埋める」って意味なら memset() で正解。
ただし「全メンバを 0 で初期化する」なら memset() は間違いで {0} で初期化するのが正解。
この2つはメンバにポインタや浮動小数点数が混ざってると意味が違うので、動作が
異なる可能性がある。 C++ でメンバに POD 以外が混ざってる場合には、 memset() での
「0フィル」は未定義動作につながる。
>>67 ポインタや浮動小数点数などでは、
Cのソース上では0と表現される値でも、内部では0以外のビットパターンを持つことがある。
そんな場合にも対応できるので、変数初期化のほうが移植性が高いとされる。
#include <iostream> using namespace std; template <typename T> void printchar(T c){ cout << c << endl; } int main(void){ cout << "print int" << endl; printchar(10); cout << "print double" << endl; printchar(32e-2); cout << "print char" << endl; printchar('A'); cout << "print char*" << endl; printchar("test char"); cout << "print void" << endl; // printchar(); return 0; } コメントアウトした行でコンパイルエラーなのですが、 引数がvoidだと何もしないっていう処理はどう書けばいいのでしょうか。
void printchar(){ }
なるほど。 そういえば、Win32APIとかの解説ページを見ると、memsetで構造体を初期化してる人もいるよね(メンバにポインタがあるにもかかわらず Windowsでしか動かない移植性がないプログラムだから問題ないんか。
>73 やっぱりそうするしかないですか。 ありがとうございます。
素朴な疑問なんだけど、 #include <> なんかの"#"ってどんな意味があるんですが? cgiみたいに、特別な物でそうゆう仕様という認識で良いのでしょうか? 初めて触った時はコメントアウトじゃんと思ったりもしましたけど。
>>75 template<typename T>void printchar(T c = 0) {if (c) cout << c << endl;}
ではどう? 使うときにはprintchar<char>()のように型を指定する必要があるけど。
>>76 >cgiみたいに、特別な物でそうゆう仕様という
ややあたり、起源はいっしょ
C++のコンパイルの前に通すテキスト加工スクリプトの様なもの。
もはや意識している人いないれどね。
起源はそうでも、すでにC++の一部機能です。
printchar('A'); がマンドクセにみえた俺は病気
単純にテンプレートのprintcharとは別にinline void printchar() {}を多重定義するだけではだめなの?
>>81 すでに出てるし、そして当人は二つ書くことになにかご不満のご様子
C/C++でGUIを実装する方法にはどのようなものがあるのでしょうか? 代表的なものにWinAPIとMFCがあると調べてわかったのですが、どちらも難解そうな上 ニュアンス的なものですが、主流ではないような印象を受けました C/C++で作ったDLLをC#で使う?ような方法にも辿りついたのですが それだと使う側に.NETが必要になるようなので、それなら最初からC#を使った方が…と思います どういった方法がベターなのでしょうか?
普段は小物を作るのにVisual StudioのリソースエディタとATL/WTLをよく使っているけど、 C++はGUI作るツールに満足なものがないから、GUIに向いていない環境だと俺は思っている。 もっとましな状況になってほしい。 いろんなものが乱立していて決定打がないんだけど、 Windowsでは、Windows APIが最下層で、ほかがそのラッパーになっているので、 自然、Windows APIが共通語彙になっているという面はある。 だから、今何を使うにしても、いつかは素のWindows APIプログラミングに触れていてほしいなと思う。
86 :
デフォルトの名無しさん :2008/02/21(木) 15:46:41
整数を逆に並べて返す関数は以下でよいですか? 例) 12345→54321 12000→21 int reverseDigit(int input) { int a = input; int tmp[12]; int i = 0; while (a > 0) { tmp[i] = a % 10; a = a / 10; i++; } int res = 0; int n = 1; for (int j = i - 1; j >= 0; j--) { res = res + tmp[j] * n; n = n * 10; } return res; }
>>84-85 なるほど、見た感じWinAPIに一番無難な印象を受けてしまいました
Windowsがこの先消えうせることはなさそうですしとりあえずWinAPI触ってみます、ありがとうございました
>>86 試して問題ないならいいんじゃない?
負数で破綻するけど。
それと、一旦各桁に分割した結果を配列で保存するなら、
sprintf()で文字列にしてから逆順にして、atoi()で戻してもいいかも知れない。
int a = input;に意味がないね そのままinputを使えばいい 知っててわざとやってるなら別にいいが
c言語でhttpサーバを作っててわからなくなったので質問させてください。 サーバからクライアントへsendを使ってメッセージを送信した際、 メッセージの送信完了を伝えるには、ソケットをclose(あるいはshutdown) する以外に方法はないですか? つまり、ソケットを閉じずに、コネクションを維持したまま、 送信完了を伝えたいのですが、できませんか?
>>89 意味ある、というか引数いじらないのは鉄則だよ。
一時変数ケチってinputを加工するのは無駄なバグの元。
>>90 HTTPであれば、レスポンスにContent-Lengthを入れれば、クライアント
がそのサイズの受信でデータ終了だと思ってくれる。
93 :
90 :2008/02/21(木) 18:29:55
>>92 なるほど、そういう方法なんですね。
助かりました。ありがとうございます。
>>87 C#使った方がいいと思うってもう遅いけど
95 :
デフォルトの名無しさん :2008/02/21(木) 21:40:29
C++ならボーランドが最強 デルファイ言語の環境のまま、言語だけC++
正直決定打といえるほどのものじゃない
でもスタックにVCLのオブジェクト置けないんだよね
98 :
デフォルトの名無しさん :2008/02/21(木) 21:45:50
物理メモリの未使用量はどう調べられますか?
101 :
デフォルトの名無しさん :2008/02/21(木) 21:50:59
WindowsXPです
じゃあタスクマネージャだな
>>101 GlobalMemoryStatus で調べろ
105 :
デフォルトの名無しさん :2008/02/21(木) 21:57:57
サンクス
106 :
デフォルトの名無しさん :2008/02/21(木) 22:27:36
newやvectorで確保が失敗したかチェックするにはどうすればいいですか?
107 :
デフォルトの名無しさん :2008/02/21(木) 22:31:16
あとメモリが少なくて、確保に時間がかかる場合、途中で止めるか、かかる時間を予測できますか?
VC9なのですが、SHA-256の定番なライブラリってないでしょうか? JpegのIJGライブラリみたいなものがあると嬉しいのですが
>>106 長い思考の旅の後には、失敗しないからチェックは不要という結論になるよ。
>>106 bad_alloc 例外をつかまえる。
bad_alloc例外が必ず捕まえられる保障はないそうだよ。 by Sutter
set_new_handler
メモリ確保できなきゃ 大抵はそのまま異常終了するしかない事が多い。 ダウンするとマズいシステムの場合は そうも言ってられないが。
115 :
デフォルトの名無しさん :2008/02/21(木) 23:19:36
ビルドのエラーについて質問です。 timeGetTime関数を呼ぶだけの関数を作成したのですが、 ビルドで以下のエラーになりました。 LNK2019: 未解決の外部シンボル __imp__timeGetTime@0 が関数 "int __cdecl MainRoutine(void)" (?MainRoutine@@YAHXZ) で参照されました。 ソースは以下になります。 #include <windows.h> #include <mmsystem.h> int MainRoutine() { DWORD dwTime; dwTime = timeGetTime(); return 0; } VC2008 Express Editionを使用しています。 他に何か設定が必要なのでしょうか?
ライブラリのリンクが必要。
117 :
デフォルトの名無しさん :2008/02/21(木) 23:29:07
>115です。 すいません。記述漏れです。 以下の設定はすでにしていました。 「ツール」-「オプション」-「プロジェクトおよび〜」- 「VC++ディレクトリ」-「ライブラリリンク」にて、 C:\Program Files\Microsoft Platform SDK\Lib ほかのライブラリのリンクが必要なのですか? 必要な場合、どこのライブラリをリンクすればいいでしょうか?
それはライブラリを検索するディレクトリを指定しているだけで リンクするライブラリを選択するオプションではない。 何をリンクすればいいかはググれ。
119 :
デフォルトの名無しさん :2008/02/21(木) 23:38:58
>115です。 今は、ライブラリのリンクが出来てなかったと言うことなんで、 リンクの方法、リンクするライブラリについては、また調べてみます。 回答ありがとうございました。
ifやswitchってこんな風に書くのあり? if(i==(1||2||3||4||5)) switch(i){ case (1||2||3||4||5): break; }
おかしくね
>>120 C++ で operator をオーバーライドすれば可能かもしれませんね
>>120 switch(i){
case 1: case 2: case 3: case 4: case 5:
break;
}
d caseの方は間違ってるのね ifの方も駄目?
>>124 ああ、caseでbreak書かなかったらそのまま下までいくからそういう風に書いたらいいのか
C#では見事に禁止だな
>>125 文法的に間違いではないが、お前の期待する動作はしないと思う
(1||2||3||4||5)は常に真となり、それとiの値が等しいかどうか
だよ?これ
>>125 ifの方も意図しているであろう動作はしない。
ただしコンパイルは通る。警告くらい出してくれるかも知れんが・・・
ありがとうございます。自分でもためしてみたけど無理だった コンパイル通ってたから上手く動いてると思ってそのままつかってたよ…
>>127 C#も124みたいにcaseラベルを並べるのはありだと聞いた。
並べさせるくらいなら、コンマ区切りで書かせてくれてもいいのにね。
133 :
デフォルトの名無しさん :2008/02/22(金) 00:27:11
クラスの定義と代入を同時にやるにはどうやればいいですか? int a=10; のようにです
「代入」 は既に宣言されている変数に対して行う操作なので 同時に出来る訳が無い。 初期化なら別だが。
operator を使おう
136 :
デフォルトの名無しさん :2008/02/22(金) 00:30:52
事故解決しました
137 :
デフォルトの名無しさん :2008/02/22(金) 00:32:34
これでできました int main() { class Test{ int x; public: Test (int y) {x=y;} print(){ cout<<x<<endl; } }; Test a=10; a.print(); return 0; }
138 :
デフォルトの名無しさん :2008/02/22(金) 00:35:31
Test a=10; a.print(); a=20; a.print(); もできるんですね C++はすごいですね
往々にして望まない機能だけどな。 基本的に引数1つのコンストラクタには explicit つけとけ。
それよりも、構造体って感じの型でないクラスなのに コピーコンストラクタとoperator =をコンパイラ任せにしているのが嫌だね。
コンパイラ任せに出来る時は コンパイラ任せでいいよ。
142 :
デフォルトの名無しさん :2008/02/22(金) 00:48:46
138じゃないですが、
>>139 なんでですか?
(本当に理由を知りたいです。)
#include <iostream> #include <vector> class Vector { public: Vector(size_t size) : m_array(size) { } void output() const { for(std::vector<int>::const_iterator it = m_array.begin(); it != m_array.end(); ++it) { std::cout << *it << ' '; } std::cout << std::endl; } private: std::vector<int> m_array; }; void Foo(const Vector& v) { v.output(); } int main() { Foo(5); ←←←←←←← } これが直感的な挙動ではないことは分かってもらえると思う。 でも、コンパイル通るし、正常に動く。 explicit つけるとこういう時にコンパイルエラーにできる。 それでも Foo(Vector(5)); なら可だが、これは問題ないと感じてくれると思う。
>>91 どんなバグがでるのですか?
呼び出し側なにか影響でうるのですか?
input を変更した後に、 input が変更されていない事を前提とした処理を書いてしまうかもしれない。 あるいは、そういう処理があるにも関わらず、 それより前の地点で input を変更してしまうかもしれない。 そうなっていないか注意して探すよりは、 引数をいじらない方が良い。
みんな仮引数にconstって使わないんだよね。
一時期付けてみたけど、 あんま意味ないと思ってやめた。
>>145 なるほど
別にいじること自体がやばいわけじゃなくて
いじると間違い起こす原因となる可能性があるわけですね
ありがとうございました
だって関数の定義では付けてもいいけど、宣言では付けたくないので、 コピペじゃ済まなくなる。
>>131 fall throughは禁止じゃなかったっけ
何かキーワードがあったと思う
情報が古いかもしれんが
>>150 caseが連続する場合のみOK。その他は禁止。スレ違い。
152 :
デフォルトの名無しさん :2008/02/22(金) 01:19:25
>>143 ありがとうございます。
explicitは、暗黙の変換を抑制する機能なのですね。
しかしなんか上の例のコードは、すごくC++書き慣れた人な感じがしました。
154 :
133 :2008/02/22(金) 02:00:16
関数の引数にクラスを使いたいのですが、クラスの宣言と代入を同時にするにはどうやればいいですか intのようにコンストラクタではできませんでした test y = f( x ); のようにです fはクラスを返します intではないです
>>154 testというのがクラスなら、testにconst test&型の引数を1つ取るコピーコンストラクタを作るんだ。
156 :
デフォルトの名無しさん :2008/02/22(金) 02:14:25
サンクス
>>154 何度も言うが、それは代入じゃない。
初期化だ。
初期化の場合、= を使っていても
test y = f(x); は test y(f(x)); と同義。
まったくのプログラム初心者です。 はじめににインストールする言語?をどれにするかがわかりません。 どういう意味かというと ボーランド、とかマイクロソフトのvisual studioとかどれにすればいいのかです。 有料とか無料とかいろいろありますね。 できたら将来有料ソフトを販売可能なものがいいです。 今考えているのはマイクロソフトのVC++を考えているのですが、 C++とVC++は違うとか どっかで聞いたりもしたので 初心者にはちんぷんかんぷんでわかりません。 よろしくお願いします
C++ は言語名。 VC++ は C++ を使って開発を行うためのツールの名前。
161 :
デフォルトの名無しさん :2008/02/22(金) 11:08:37
VC++ はMSがWindows用ソフトを開発するために拡張した言語ともいえる VC++のコードはほかのものでは動かせないものが多い
ここはC/C++スレですが
システム構築売るならまだしもソフト売るのにJavaはないだろ。 VCにしとけ。
165 :
デフォルトの名無しさん :2008/02/22(金) 11:59:00
perl2exeみたいなやつでは? 実行環境を圧縮してexeに詰め込む 利点としてはランタイムとかの導入がいらないだけで
167 :
デフォルトの名無しさん :2008/02/22(金) 12:31:13
この直し方教えてください! IEBrowser->Document.charset="shift_jis"; error C2039: 'charset' : '_com_ptr_t<class _com_IIID<struct IDispatch,&struct __s_GUID _GUID_****> >' のメンバではありません。
168 :
167 :2008/02/22(金) 12:35:30
文字コードの変換をしたいのですが・・・ この様に定義してあります SHDocVw::IWebBrowser2Ptr IEBrowser; IEBrowser.CreateInstance( __uuidof( SHDocVw::InternetExplorer ) );
>>167 こうでは?
IEBrowser->Document->charset= L"shift_jis";
170 :
167 :2008/02/22(金) 12:55:40
>>169 error C2039: 'charset' : 'IDispatch' のメンバではありません。
になりました・・・
171 :
167 :2008/02/22(金) 13:05:44
文字コードの変更方法わかったら教えてもらいたいですけど そこだけVBAスクリプトを呼び出す事にします
>>170 じゃあこれはどう?
SHDocVw::IHTMLDocument2Ptr document = IEBrowser->Document;
docment->charset = L"shift_jis";
173 :
167 :2008/02/22(金) 13:13:13
だめでした
QueryInterface
適当に書いたらやっぱダメだったか、すまん。 #import <mshtml.tlb>した上で、MSHTML::IHTMLDocument2Ptrだ。
>>174 ナントカPtr(の実態_com_ptr_t<>)のコンストラクタや代入演算子の中でQueryIntefaceが行われている。
177 :
デフォルトの名無しさん :2008/02/22(金) 14:08:38
πの値は、自分で3.1415926535...とかって書くしかないでしょうか。 numeric_limits<int>::max()とか、そういう書き方はないですか?
#ifndef M_PI # define M_PI 3.1415926535 #endif
math.hをインクルードしたらM_PIとしてdefineされてる。 計算して出したいなら4*atan(1.0);
標準ではないのが玉に瑕。
181 :
デフォルトの名無しさん :2008/02/22(金) 15:02:49
>>178-180 ありがとうございます。
#include <cmath>
としてたのですが、M_PIでコンパイル通りました。
C初心者です。 実数→整数変換ですが、 double dval; char buf[80]; int ival; dval = -19.99; /* -19.99〜19.99 */ dval = dval * 100.0; sprintf(buf,"%.0f",dval); ival = atoi(buf); printf( "%f %d %d\n",dval,ival,(int)dval); /* printf( "%f %d %d\n",dval,ival,(int)ceil(dval)); */ ivalを求める場合、上記の方法が一番精度が良いのですが これ以外に方法はありますでしょうか? ceil() や floor() 使っても誤差が出てしまいます。
>sprintf(buf,"%.0f",dval); それ四捨五入してるだけだぞ そんなんでいいなら ival = floor(dval * 100 + 0.5) とでもやればいい 元々 -19.99 という値自体が誤差を持ってるから、これを無くすことは出来ない printf("%.20f\n", -19.99); とかやってみればわかる 本当に誤差が嫌なら、浮動小数点を使わない、という方法しかない
184 :
182 :2008/02/22(金) 16:12:26
>>183 早速のRESありがとう御座います。
>そんなんでいいなら ival = floor(dval * 100 + 0.5) とでもやればいい
了解です。これで行きたいと思います。
どうもありがとう御座いました。
185 :
デフォルトの名無しさん :2008/02/22(金) 16:53:31
char []型の要素を破棄して動的確保できませんか? 消せなくてもいいので別のアドレスに確保できませんか? f(char *ch){ delete ch; ch=new char[10]; strcpy(ch,"ssssssss"); } main(){ char *ce=new char[2]; f(ce); cout<<ce<<endl; char ch[]="test"; f(ch); cout<<ch<<endl; }
186 :
デフォルトの名無しさん :2008/02/22(金) 16:55:19
もしくは、char *型とchar []型を判別して、書き換えられないなら始めにエラーにするのでもいいです
>>185 ごめんfで何がしたいのか分からない。
まぁ俺の第六感で回答すると、ポインタのポインタ使えばいいんじゃね
188 :
デフォルトの名無しさん :2008/02/22(金) 17:05:10
char a[10]; をコード内で書き換えてたとえば100個まで使えるようにしたいんです はじめのaは破棄できなくてもいいので、a[50]とかにアクセスできるようになりませんか
Stringクラスの使い方でも覚えるとか
191 :
デフォルトの名無しさん :2008/02/22(金) 17:12:10
ポインタで文字列のアドレスが渡されたら、それが[]なのか*なのか渡された側にはわかりません どうしたらいいですか
配列サイズも渡す
閃いたw 初めから1000個くらい確保しとけばいいじゃん
194 :
デフォルトの名無しさん :2008/02/22(金) 17:21:28
無理か main(){ char ch[]="test"; char *ce=new char[20]; strcpy(ce,"ssss"); ch=ce; //ここでエラー cout<<ch<<endl; }
あほすぎ
>>194 こうすれば?
main(){
char chx[]="test";
char *ch = chx;
char *ce=new char[20];
strcpy(ce,"ssss");
ch=ce; //エラーなし
cout<<ch<<endl;
}
>>185 恐らく、引数でもらった文字列を元に新な文字列を返そうと考えてるんだろうけど、
そうしたいのなら、
char* func(const char* str)
{
char* s = new char[ほにゃらら];
ほげほげ
return s;
}
とした方が良い。
そもそも
char ch[] = "test";
の ch は配列の先頭のアドレスを返す「定数」なんだから、newで確保した領域を割り当てられるわけないよ。
199 :
デフォルトの名無しさん :2008/02/22(金) 19:05:33
レスありがとうございます 同じような質問なんですが、*chが確保されていてもいなくても、deleteするにはどうすればいいですか? 確保していないと実行時にエラーになります
言ってる事がよく分からんが、こういうこと? if( ch )delete ch;
201 :
デフォルトの名無しさん :2008/02/22(金) 19:15:06
まともに動くのはaだけなんです どれでも動くようになりますか? f(char *ch){ delete ch; ch=new char[10]; strcpy(ch,"ssssssss"); } main(){ char *a=new char[1]; f(a); cout<<a<<endl; char *b=NULL; f(b); cout<<b<<endl; // char *c; f(c); cout<<c<<endl; }
202 :
デフォルトの名無しさん :2008/02/22(金) 19:16:31
void f(char*& ch)
つーか、大人しく std::string 使え
>>201 fの中でchに代入してもmainの方はaもbもcも変わらないよ?
f(int x){
x = 2;
}
main() {
int a = 1;
f(a);
cout << a << endl; // 2ではなく1と表示される
}
↑これ解ってる?
206 :
デフォルトの名無しさん :2008/02/22(金) 19:19:04
>>203 それを組み込んだらbも動作しました! でもcが実行時にエラー出ます
>>200 も同時にやってもだめです
207 :
デフォルトの名無しさん :2008/02/22(金) 19:20:20
>>205 char* や配列は参照渡しだとききました
初期化してねえのに delete できるわけねえだろ
210 :
デフォルトの名無しさん :2008/02/22(金) 19:21:59
211 :
デフォルトの名無しさん :2008/02/22(金) 19:23:11
aは配列と見なされて参照渡しになってるんですね
用語の部分で思考停止してるな。 何が起こってるのか考えた事無いだろう。
>>210 初期化されてるポインタと、
初期化してないけど偶然たまたま同じ値が入ってるポインタを、
見分ける方法が物理的にあると思うか?
214 :
デフォルトの名無しさん :2008/02/22(金) 19:26:39
deleteした瞬間に落ちます tryも無理です f(char*& ch){ try{ delete ch; } catch(...){cerr << "例外を受け取りました。" << endl;} ch=new char[10]; strcpy(ch,"ssssssss"); } main(){ char *a=new char[1]; f(a); cout<<a<<endl; char *b=NULL; f(b); cout<<b<<endl; char *c; f(c); cout<<c<<endl; }
>>214 いい方法を教えてあげよう
関数 f の前にこれを書くんだ
/* この関数に初期化してないポインタを渡してはいけません */
基礎からやり直せよ
>>214 だーかーらーnewで確保したメモリを指してるポインタと、未初期化のポインタを見分け
る方法なんて存在しないんだってば。
ポインタ使うときは初期化しろって何で言われてるのか考えたことあるか?
#define HOGE int void f(HOGE x) { cout << '(' << x << ')' << endl; x = 42; } int main() { HOGE a = 10; f(a); cout << '(' << a << ')' << endl; HOGE b = 0; f(b); cout << '(' << b << ')' << endl; HOGE c; f(c); cout << '(' << c << ')' << endl; } これの挙動は分かるか? #define HOGE char* void f(HOGE x) { cout << '(' << x << ')' << endl; x = "f"; } int main() { HOGE a = "a"; f(a); cout << '(' << a << ')' << endl; HOGE b = NULL; f(b); cout << '(' << b << ')' << endl; HOGE c; f(c); cout << '(' << c << ')' << endl; } んで、これの挙動は分かるか?
219 :
デフォルトの名無しさん :2008/02/22(金) 20:17:15
質問ですが、stringの参照で値を受け取るとき memcpy(str, ch,10000); のようにできますか?
お願いだから str.assign(10000, ch); としてください。 頼みますから。
221 :
デフォルトの名無しさん :2008/02/22(金) 20:45:34
凄く無駄なレス消費してんなw
昔ならともかく惜しむもんではないが無駄感は否めないなwww
プログラムを1から始めようと思うのですが、まずは本でも買って読むべきですか? それともネットで調べるべきですか?
何をやりたいか目標を立てることから始めるべき。
文字列sに含まれる先頭のcの添字を表示させる関数を作れ cが無い場合は、-1を表示 という問題で詰まってます 文字列の中のcを認識させるにはどうすればよいのでしょうか
strchr
マルチで申し訳ないですが グローバルな共用体の変数に、関数からメンバーに代入したらセグメントエラーを吐いたのですが、これは許されないのでしょうか?
マルチしないでください^^;
火星人で申し訳ないのですが グローバルな共用体の変数に、関数からメンバーに代入してもセグメントエラーを吐かないのですが、 嫁は許してくれるでしょうか?
こんがらがっちゃったんで、聞きたいんですが・・・ 今こんなテンプレートクラスがあったとして template<typename T> class Array{ T *array; size_t length; public: Array(size_t n = 0){...} ~Array(){...} T& operator [](size_t n){...} } これを typedef Array<myclass> MyArray; //myclassは適当なクラスということで Array<MyArray> MyArray2(2); と使う時、MyArray2は与えた引数で初期化できますが MyArrayの方にコンストラクタの引数を与える場合はどうすればいいですか? ちなみにこれは、配列クラスなんでできれば、MyArray2が持つそれぞれのArray<myclass>に 別々の初期化パラメータを与えたいんですが・・・。
>>255 何ができるかを伝えてあげるべき。
ようこそプログラムの世界へ。
>>227 それは関数そのものではないでしょうか
わざわざ教えたいただいたのですが、伝達不足でした、すみません
int strch_idx(const char* s, char c);
という関数の雛形が与えられて、この中身を作るのに、cを認識する必要があると判断したのですが、間違っているでしょうか
>>231 今のC++では無理だね。だからSTLコンテナではreserveしてpush_backしたり、
組込の配列からコピー初期化したりする。
>>234 cを認識の意味がわかりません
s内からcを検索したいってこと?
>>235 もしやと思ったらやっぱりですか・・・
この場合大人しくループまわして作ることになるんでしょうね。
ありがとうございました。
>>236 例えば、sという文字列にcincoと入力すると、1を
sという文字列にiicicoと入力すると3を
sという文字列にnorioと入力すると-1をreturnで返却する
こういう関数を作ろうと思うと、sという文字列の中身について、
s[0]に格納されているのはcかどうか、s[1]に格納されてるのはcかどうか、s[2]に格納されているのは…
と、ひたすら繰り返して行く必要があると考えました
そのためには、s[n]について、cなのかどうか判定する必要があるのではないかと
この判定というのが、認識と同じ意味のつもりで使いました
strchrのソース読めよ。 検索すればいくらでも出るだろ
>>238 if (s[0] == 'c') return 1;
if (s[1] == 'c') return 2;
if (s[2] == 'c') return 3;
...and so on.
241 :
デフォルトの名無しさん :2008/02/22(金) 23:50:48
>>238 それ以外に方法はstrchrを使用するぐらいしか思いつかない
(strchrもおそらくは、中で同じようなことしてると思うけど)
なにが疑問なのかよくわからないので、とりえあず2通りソースを貼り付けときます
@
int i;
for(i=0; s[i] != '\0' && s[i] != c; i++);
return s[i] != '\0' ? i : -1;
A
char *p;
return (p=strchr(s, c)) != NULL ? (int)(p-s) : -1;
返ってくるのは配列の添え字ですのであしからず
全くコードの書き方が分からないので質問させて下さい。 C++ VS2005 略) printf("Got: %02x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); ※ buf[0]には01 buf[1]には06 buf[2]には17 buf[3]にはf3 buf[4]には34 が入る。 を文字列"0106171f34"に置き換えたい。 1.このbuf[]の中(16進数)を文字列に変換したい。 2.文字列に変換した後に、buf[0]〜buf[5]を繋げたい。 sprintとかを使えば良いみたいなのですが、どのようにやってよいか分からずに困っています。 どうかよろしくお願いします。
>>244 いや一応答えると
sprintじゃなくてsprintfだな
sprintfで連結もできます
247 :
244 :2008/02/23(土) 03:51:48
>>245-246 ありがとう。もうちょい試して無理だったら、宿題ではないんだけど、宿題スレで質問してみたいと思います。
sprintf のヘルプ見るだけで解決だろ
249 :
244 :2008/02/23(土) 08:58:16
>>248 なんとか解決しました。時間かかった>< やってみれば、なんと簡単なコードって感じですけど。
ヘルプのみかたってイマイチわからないんですけど、ヘルプの見方の解説サイトとかってありませんでしょうか?
>>249 manコマンドのことなら、man manでOK。
Cをずっとやってたのですが、 VC++6.0でデバッグしてると、関数に入るだけでESPが100バイトくらい進みます C++だとモジュール毎にスタックをこんなに食うものなのでしょうか? デバッグ情報か何かで食ってるのですか?
ローカル変数たくさん使ってるんじゃないの
>>251 ローカル変数が100バイトほどあるんじゃなくて?
254 :
251 :2008/02/23(土) 11:07:16
いやひとつもないのだが・・・ 家のPCでためしたけど、 関数にステップインするときはESPは4バイトしか進まないが、 そこから1step進めて、{から関数内の1行目に入るときに、 80バイトも食う char a[100];と宣言を入れると、これが180バイトになるから、やり方は間違ってないはず この80バイトが何なのかわからん
メンバ関数とかじゃなくて?
>>254 一時オブジェクトの置き場になってるとか?
関数の戻り値のオブジェクトを別の関数に直接渡してる場合とか・・・
アセンブラコード出させて見ても使われてなさげ?
まさかとは思うが、スタックオーバフローのチェックコードが入っているとか。 さもなければalloca()相当のコードが入っているとか。 あーそうそう、この場合のローカル変数は、Cのコード上現れるものに限らず コンパイラが必要とした一時変数も含めてってことね。 例えば、構造体を値渡ししていたりreturnで戻していると作られるかもね。
258 :
251 :2008/02/23(土) 11:32:53
void test() { char a[100]; printf ("test"); } int main(int argc, char* argv[]) { test(); return 0; } コードはこれだけなんだけど。C++じゃねーな。 混合モードで見ると、これが原因らしいが、何でこんなことしてるのかな。 アセンブラわからん。 sub esp,0A4h
>>249 VC++ なら sprintf とか入力して F1 推せば見れるだろ。
>>258 デバッグ用じゃなくてもそうなら、
例外用のコードなのかもしれないな。
>>258 手元の2005EEで試したが、リリースビルドの規定値では該当のコードは生成されない。
デバッグビルドだと生成されるが、「基本ランタイムチェック」を無効にしたら配列分だけになった。
つまり、>257の1行目だね。
262 :
デフォルトの名無しさん :2008/02/23(土) 13:23:22
C言語でポインタを値渡しするにはどうすればいいですか?
263 :
デフォルトの名無しさん :2008/02/23(土) 13:24:01
訂正 C言語でポインタを参照渡しするにはどうすればいいですか?
>>263 ポインタのポインタを使う
int **p;みたいなの
C言語には参照渡しの機能はありません。 ポインタを渡すことで参照渡し「っぽいこと」はできるので、 ポインタのポインタを渡せばポインタの参照渡し「っぽいこと」はできます。
参照渡しだって結局アドレス渡しの糖衣みたいなもんなんじゃねえの
文脈で「参照」の意味の違いを読み取れよ
268 :
デフォルトの名無しさん :2008/02/23(土) 13:32:28
サンクス
C++じゃなくてCならアドレス渡しと参照渡しは同義で通じるだろ
結局やってることは同じじゃねえの
271 :
243 :2008/02/23(土) 13:45:44
やっぱりうまくいきませんでした 何が間違っているのか、理解できません 添削をお願いしたいです c++、Borland C++5.5.1 for win32でやっています int strch_idx(const char* s, char c) { int i = 0; while(s[i]) { if(s[i] == 'c') goto end; else if(s[i] == 0) { i = -1; goto end; } i++; } end: return i; }
最近はソフトウェア工学も学ばないのか
>>271 >if(s[i] == 'c') goto end;
'c' じゃなくて c では?
あと、else if (s[i] == 0) の判定をする前に while の条件で抜けてしまうかと
>>274 俺はCでの話を言ってるんだぞ?
アドレス渡ししかないんだからないんだから、不正確もなにもねぇだろうが
Cには参照なんてないんだからそんな言葉つかうなよ。
え?マクロは参照じゃないの?
C言語は基本的にすべてコピーで渡す ポインタもコピー
参照渡しがアドレス渡しの糖衣ってのは正しい どっちかだけ知らずに語ると馬鹿なことになるけど、どっちもしっかり理解してるなら別に問題ないでしょう
static_castと(int)みたいなキャストってなにかなにか違うんですか?
>>281 static_castの方が用途が限定される
>>280 個人がそう理解するのはかまわんけど、初心者への説明としては不親切じゃね?
>>281 Cとの互換性を大事にしたいなら後者、意味をはっきりさせたいのなら前者を使うといいでしょう。
>>273 実際やってみると
cuで2が、gguで3が、ijcoで4が返ってきます
これは、s[i] == cと、s[i] == 0の判定が成されていないという事ですよね?
しかし、while関数自体は終わってるので、s[i]は判定されている
どういうことなんでしょうか?
また、ご指摘を受けて、whileをdo-whileに変更しました、ありがとうございます
なんでそんな単純な構造でgotoを使う必要があるのか解らん。
gotoは怖くて使えない・・・ てか絶対使わないようにしてるんだが、違うのか
>>280 単なる構文糖衣じゃない。
参照の参照というのは存在しないが、
ポインタのポインタというのは存在する。
これは大きな違いで、適当な教え方してると
>>207 みたいなやつが出てくる。
>>287 むしろ使った方が綺麗になる状況では使う。
でも、上のは break; 使えば解決できることで、
goto を使って解決すべきじゃない。
普通は C 風のキャストは使うべきじゃない。 せいぜいクラスのテンポラリオブジェクトを作るのに関数風のキャストを使うくらい。
>>292 それはキャストよりもコンストラクタ呼び出しのほうがしっくりくる
294 :
デフォルトの名無しさん :2008/02/23(土) 14:49:30
昨日質問したものですが、char * 型とchar []を判別する方法はありませんか?
ソースコードを読みましょう。
>>291 すいません
気にしろとだけ言われましてもなにに気を使えばいいのかわかりません
まずい点でもでてくるのか
だとかを教えていただけませんか
キャストには色々意味があって、C言語風キャストだとそれらをすべて内包してしまって意図が掴みにくい
298 :
デフォルトの名無しさん :2008/02/23(土) 14:58:20
メインウインドウにBUTTONを作成するときなどで使う、 CreateWindowとCreateControlWindowはどう違いますか?
>>296 C風のキャストはなんでもかんでもキャストできてしまうので、
プログラマの意図と違ってても警告が出ない
const void *p = 〜;
char *q = (char*)p; // charにキャスト・・・あれ? constも外しちゃったよ! でも警告は出ない
char *r = static_cast<char*>(p); // コンパイルエラー: static_castでconstは外せない
char *s = const_cast<char*>(static_cast<const char*>(p)); // constも外したい意図の場合はこう書く
>>286-287 gotoのほうが行き先が明確になるので、理解しやすかったので、用いていますが
なぜ怖いのでしょうか
それと、「これは、s[i] == cと、s[i] == 0の判定が成されていないという事ですよね?
しかし、while関数自体は終わってるので、s[i]は判定されている
どういうことなんでしょうか? 」
これにも答えていただけると非常にありがたいです
>>296 キャストというのは基本的にマズい処理。
アップキャストだけは例外的に安全だが、
それ以外は基本的にはあまりやるべきではない。
でも、実際にはどうしてもやる必要が出てくる事もある。
こればっかりは仕方が無い。
そういう時、C 風のキャストを使ってしまうと色々と問題が発生する。
・ 間違って危険なキャストをしてしまうかもしれない。
例えば、const を付けるべきところで const を付け忘れたり。
こういう時、static_cast なら危険な const の付け忘れがあるとコンパイルエラーになる。
C 風キャストだと問答無用でキャストされてしまう。
これが一番の問題。
・ キャストが原因っぽいバグが見つかった時、どこにキャストがあるのか探すのが面倒。
C++ のキャストだと検索でキャストを行っている箇所を簡単に見つけられる。
・ キャストがあまり目立たない。
危険な処理を行っている箇所が目立たないのは危険。
C++ のキャストは非常に目立つ。
・ 打鍵数が少ないので気軽にキャストをしてしまう。
C++ のキャストは打ち込むのが面倒で、キャストを本当に使うべきなのか
立ち止まって考えるよう思考を誘導してくれるかもしれない。
・ 今行おうとしているキャストはどういうものかをあまり意識しないかもしれない。
キャストという処理を軽く見ているのはよろしくない。
>>300 gotoが必要になるのは言語の構造化能力を超えた構造が必要になる場合であって、
この場合はそういう場合でない。
>>300 論理的に記述しようぜ。
「while を終了する」 と 「指定位置に移動する」 では
前者の方がより論理的だ。
論理的なコードは、一般に変更に強く、バグが出にくい。
まあ、break すらみだりに使うべきじゃないという人もいるけどね。
304 :
デフォルトの名無しさん :2008/02/23(土) 15:07:50
関数の引数で、char * 型とchar []型を判別する方法ありますか?
void foo(char* const& hoge); template <size_t N> void foo(char (&hoge)[N]); と区別できなくはない。
char[N]とchar[]は別物だと思うよ。
void foo(char* hoge, size_t size); template <size_t N> inline void foo(char (&hoge)[N]) { foo(hoge, N); } もちろん、こう実装するんだぜ。
そう言う意味での char [] 型なんてそもそも存在しないが。
>>285 >cuで2が、gguで3が、ijcoで4が返ってきます
その書き方はおかしい
strch_idxには引数が2つあるので、cuとかgguだけでは結果は決まらないはずだ
>>300 逆。
gotoの方がどこにでも飛ばせるせいで行き先が不明確になる。
自分の書いたコードを他人に読ませることを想像してごらん。
breakならどこに飛ぶのか一目瞭然だけど、gotoだといちいちラベルを検索しないといけない。
しかもbreakなら「ループの終了」という意図が一目瞭然だけど、
gotoだとどういう意図で飛ばしたのかを考えないといけない。
そういう理由でgotoは避けられるため、安易にgotoが入っているとさらに、
「gotoを使わなければいけないどんな理由があったのか?」と考えさせることになる。
int⇔floatの変換だけでも、毎回static_cast使う? あと、コンテナの最後の要素以外を処理する時、 std::vector<T> container; for (int n = 0; n < static_cast<int>(container.size()) - 1; ++n) container[n] = ...; ってやる?
>>312 俺はstatic_castを使う
コンテナの方は
for (size_t n = 0; 〜
って書けばいいのでは
本当は std::vector<T>::size_type の方が適切なのかもしれんが
>>312 >int⇔floatの変換
うん。
>最後の要素以外を処理
unsigned使う。
>int⇔floatの変換だけでも、毎回static_cast使う? 使う。 >コンテナの最後の・・・ for (std::vector<T>::size_type n = 0, size = container.size(); n + 1 < size; ++n) container[n] = ...; ってやると思う。 符号無しの値を符号付きにキャストするのは基本的に危険だと思う。
後者の場合、 if( !c.empty() ) for( size_t n=0; n<c.size()-1; ++n) で何か問題あるのか?
>>316 n + 1 < c.size() で判定すれば empty チェックは要らない。
typename 忘れてた。 まあ T をそういう意味で使ってるとは限らないが。
>>302 >>303 >>311 での説明とほぼ同じという理解でよろしいでしょうか
>>311 gotoよりbreakを使うべきというのは、よく理解でき、納得できました
しかし、怖いというのは一体
>>310 すみませんが、もうすこし噛み砕いて説明願えないでしょうか
const char* sには、任意の文字列が入って、char cで、検索する文字を固定という事ではないんですか?
そのconst char* sにcuですとか、gguですとかが入っているので、これで十分だと考えているのですが
>>319 goto はまず特定の状況でしか使われない。
それ以外で使われると混乱するし、
何のために使われているかすぐに分からないので不気味で怖い。
>>319 goto は意図が不明確。
goto のあるコードを変更することになった場合、
その意図が 100% 分からなければ、
手を加えて変なことになりかねないので怖い。
>>319 一番怖いのは、バグの温床になること。
コードの分かりにくさってのはバグに直結する。
>>315 イテレータ使うならこうだな。
前進イテレータでさえあれば、これでいけるはず。
if(! container.empty()) {
Iter it_next = container.begin();
++it_next;
for(Iter it = container.begin(), end = container.end(); it_next != end; ++it, ++it_next) *it = ...;
}
>>319 const char* s が cu でも c の方は
strch_idx("cu", 'c') とか
strch_idx("cu", 'u') とか
strch_idx("cu", 'x') とか色々指定できるわけで
>>320-322 なるほど、よく理解できました
ご親切にありがとうございます
1、意図が不明で不気味で怖い
2、バグを招きやすいから怖い
この二点ですね
そして、本筋のほうもできたら説明していただきたいのですが
326 :
デフォルトの名無しさん :2008/02/23(土) 15:53:54
STLつかうとコンパイルに時間かかりますけど、クラスも多少鈍くなるんですか?
そもそも while じゃなくて for 使おうぜ。
>>326 一般に、コンパイルに時間がかかる方が、
コンパイル時にある程度処理を行ってくれているため、速くなる。
ただ、コードがあまりにも肥大してくると、
キャッシュの効きが悪くなって遅くなる事もある。
>>325 いくつか修正したみたいだけど今はどうなってるの?
>>324 >>329 最初から全文現すべきでしたね、申し訳ありません
#include <iostream>
using namespace std;
int strch_idx(const char* s, char c)
{
int i = 0;
do {
if(s[i] == c) goto end;
else if(s[i] == 0)
{
i = -1;
break;
}
i++;
} while(s[i]);
return i;
}
int main()
{
cout << "文字列を入力:"; char p[] = ""; cin >> p;
char c = c; cout << strch_idx(p, c);
return 0;
}
>>327 forだと、終了させるための条件が思いつかなかったので、whileにしましたが、やはりforのほうが良い理由があるのでしょうか
>>330 >char c = c;
これはなによ
>>330 continue した時でもインデックスが増えてくれるのと、
インデックスをなめていく操作を行っているという意図が伝わりやすいのと。
終了条件は while の時と同じでいいじゃん?
>>330 goto end ってどこに飛んでるの?
>>330 goto endが一個消し忘れ。
×char c = c;
○char c = 'c';
-1を返したいのは文がヌル文字だけだった場合?それとも文字が見つからなかった場合?
前者ならループのたび判定するのは無駄だから最初に一回だけ判定させたらいい。
後者ならヌルが見つかった時点でループが終わってるから中のlese-if節は判定してくれない。
最初に文字列の長さを測って最後までループが回った場合に-1を返すようにしないと。
335 :
デフォルトの名無しさん :2008/02/23(土) 16:26:11
f(x)のあとでstrlen(ch)が1になることがあります もとのソースを簡略にしました 構造体を参照渡ししてもだめでした 下は期待通りの動作をします 何がいけないのかわかりません #include <string.h> #include <stdio.h> typedef struct STRDATA{ char *start; char *end;}strdata; f(strdata x){ delete x.start; x.start = new char [20]; strcpy(x.start,"++++++++++++++"); } main(){ char *ch=new char [10]; strcpy(ch,"uuuu"); strdata x; x.start=ch; x.end=ch+strlen(ch); f(x); printf("%s",ch);}
なんで do-while になってるんだろう。 もっと単純に考えようぜ。 まず、文字を1つずつ取得していくループを書く。 for(i = 0; /* 文字列が終了するまで */; i++) { /* s[i] で文字を先頭から順番に走査していける */ } んで次に、c が見つかったらインデックスを返すようにする。 for(i = 0; /* 文字列が終了するまで */; i++) { /* s[i] が c なら i を返す */ } そして、検索しても c が見つからなかった場合は -1 を返す。 for(i = 0; /* 文字列が終了するまで */; i++) { /* s[i] が c なら i を返す */ } /* -1 を返す */ これでおk。
>>304 Cならシーキビだろ
C++か?
template<typename T>
struct IsArray {
enum { value = 0 };
};
template<typename T, size_t N>
struct IsArray<T[N]> {
enum { value = 1 };
};
template<typename T>
bool test(const T&) {
return IsArray<T>::value;
}
template<typename T>
void f(const T& t) {
if(test(t)) cout << "配列だ" << endl;
else cout << "配列じゃない" << endl;
}
てか、C++ならブースト使えよか
>>335 f の呼び出し後、ch は既に delete された後のアドレスを保持することになるから
絶対にアクセスしちゃダメ。
そもそも生のポインタで確保されたメモリを扱ってるからそういう事が起きる。
コンテナ使え。
340 :
デフォルトの名無しさん :2008/02/23(土) 16:30:21
これだとエラーで止まります どうすればいいですか f(strdata *x){ delete x->start; x->start = new char [20]; strcpy(x->start,"++++++++++++++"); } main(){ char *ch=NULL; strdata x; x.start=ch; x.end=ch+strlen(ch); f(&x); printf("%s",ch);}
>>335 chに割り当てたnew char[10]はfの中でdeleteされてるから、
printf("%s",ch) は違法。
それからnew[]した配列はdeleteではなくdelete[]しないといけない。
>>340 char *ch=NULL;
x.end=ch+strlen(ch);
ヌルポインタに整数を足しても有効な値にはならない。
343 :
デフォルトの名無しさん :2008/02/23(土) 16:35:22
バイナリ文字列の始めと終わりを構造体で渡して、内容、サイズを書き換えるには
>>335 をどう変更すればできますか?
普通に先頭のポインタとstrlen使って適当に操作したらいいんちゃう?
バイナリ・・・文字列?? それはともかく、std::string 使え。 #include <string> void f(string& str) { str = "++++++++++++++"; } int main() { std::string str("++++"); printf("%s\n", str.c_str()); f(str); printf("%s\n", str.c_str()); }
346 :
デフォルトの名無しさん :2008/02/23(土) 16:38:32
このふたつは動きますが内容が変化しません なぜですか f(strdata x){ delete x.start; x.start = new char [20]; strcpy(x.start,"++++"); } main(){ char *ch=NULL; strdata x; x.start=ch; f(x); printf("%s",ch);} f(strdata *x){ delete x->start; x->start = new char [20]; strcpy(x->start,"++++"); } main(){ char *ch=NULL; strdata x; x.start=ch; f(&x); printf("%s",ch);}
1つ目、std:: 忘れた。
348 :
デフォルトの名無しさん :2008/02/23(土) 16:41:16
C言語だけで、0を含む文字列を変化させたいのですが、できないですか?
>>346 ポインタが参照渡しでどうのこうの言ってた奴だよな?
頼むからポインタとは何かを一から勉強し直してくれ。
>>346 関数に渡された数値は数値がコピーされただけの別物。
だから関数内でx.start = new char [20];とかやっても呼び出し元のxには変化は無い。
351 :
デフォルトの名無しさん :2008/02/23(土) 16:44:32
f(x)で、(バイナリ)文字列を書き換えられるやり方教えてください それみて勉強します
>>351 まともな本読め。
そこにいくらでもサンプルは書いてあるし、
詳細な解説も載ってる。
353 :
デフォルトの名無しさん :2008/02/23(土) 16:46:24
>>353 後者では x は書き換えられるが ch は書き換えられない。
>>353 アドレスの指す先の内容を書き換えると呼び出し元へ反映されるというだけのこと。
x->start = ch ってやっても、ch と x->start がリンクされるわけじゃない x->start の内容が変化しても、chには関係ない
357 :
デフォルトの名無しさん :2008/02/23(土) 16:52:12
これで正解でしょうか? #include <string.h> #include <stdio.h> typedef struct STRDATA{ char **start; char **end;}strdata; f(strdata x){ delete *(x.start); *(x.start) = new char [20]; strcpy(*(x.start),"++++++++++++++"); } main(){ char *ch=NULL; strdata x; x.start=&ch; f(x); printf("%s",ch);}
図を描こうぜ。図を。 ch, x, そして動的に確保されたメモリが 実際にメモリ上でどう置かれていてどう参照していて 何を実行するとどう変化するか。
>>357 それでとりあえずまともに動くね。
推奨されるコードかと言うとまたそれは別だが。
new 使ってるから C++ なんでしょ? コンテナ使えば楽だぜ。
横から質問で申し訳ないんだけど、 ・>357のfに渡す前に、xはいつnewされてるの? ・関数の一行目がdeleteって、ものすごく気持ち悪いんだけど、よくつかう手法なの?
>>360 deleteにNULLを渡しても何も起こらないことになっているから、
最初にnewされていないというのは大丈夫。エラーにはならない。
最初にdeleteというのは必要に応じて使えばいいと思うけど、
俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。
362 :
デフォルトの名無しさん :2008/02/23(土) 17:03:44
サンクス たびたびどうもありがとうございます
俺も横レスだけど、配列なのに delete [] にしてないのは問題ないのか?
だからコンテナを使おうぜと言ってるのに。
いろいろな意味で気持ち悪い。というか何をしたいのかよくわからない。
>361 >deleteにNULLを渡しても何も起こらないことになっているから、 >最初にnewされていないというのは大丈夫。エラーにはならない。 なるほど、どうもです。 >最初にdeleteというのは必要に応じて使えばいいと思うけど、 >俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。 なるほど。 よく考えたらC++になってからnewなんてほとんど使ったこと無かった気がします。 動的な配列が必要になったらだいたいvectorにつっこんでた。
clear はメモリが解放される訳じゃないんだよな。 std::vector<int>().swap(v); みたいにしないとメモリは解放できない。 解放した方がいいかどうかは状況次第だが。
>>364 大問題ってことで軽くググってみたら、
・配列に対して、delete [] としなかった場合、1個目の要素のみデストラクタが走り、残りの要素は走らない
・確保された領域(配列)は一応開放される(デストラクタで開放されるべき領域は除く)が、
要素数保持のための隠れた確保領域は開放されずに残る
ってな、感じかな
370 :
デフォルトの名無しさん :2008/02/23(土) 17:37:02
勘違いしてないか?タスクマネージャで確認してみ #include <stdio.h> main(){ char *ch=new char[200*1024*1024]; getchar(); printf("delete 実行\n"); delete ch; getchar();}
371 :
デフォルトの名無しさん :2008/02/23(土) 17:40:15
これでも解放するし #include <stdio.h> main(){ int n; char **ch=new char*[200]; for(n=0;n<200;n++)ch[n]=new char [1024*1024]; getchar(); printf("delete 実行\n"); for(n=0;n<200;n++)delete ch[n]; getchar();}
>>331 strch_idx関数に渡すためのcを、main関数のほうで作っておかないとだめかなと考えまして
>>332 あまり理解できませんが、なるべくforを使うようにします
>>333 消し忘れです
ご指摘ありがとうございます
>>334 理屈を丁寧に解説していただきありがとうございました
>>336 を参考にやってみて、できました
>>336 ご丁寧にありがとうございました
その指針でできました
最後にご丁寧に、教えるのもわずらわしいような初歩的な愚問に答えていただき、ありがとうございました
これが初心者歓迎スレの良心。
>>370 >>371 特に勘違いしてるところはないと思うが・・・
要素数を保持する領域はないってことを言いたいのか?
組み込み型にはないけど、クラスにはあるみたいなことが書いてあったんだが
375 :
デフォルトの名無しさん :2008/02/23(土) 17:49:37
これだと解放しないけど・・・ *xと定義されているなら、deleteを使うのでは? []は**xを解放する場合でしょ #include <stdio.h> main(){ char **ch=new char*[200]; for(int n=0;n<200;n++)ch[n]=new char [1024*1024]; getchar(); printf("delete 実行\n"); delete[] ch; // delete ch; getchar();}
>>369 そもそもnew[]したものをdeleteするとどうなるかは未定義。
そういう挙動になったという話は、たまたまその実装ではそうだったということでしかない。
377 :
231 :2008/02/23(土) 17:51:43
今更ですが
>>231 のようなことをした時に
MyArrayの方はデフォルトコンストラクタか引数を省略できるコンストラクタを
呼んでいるようなのですが、これのタイミングが分かりません。
コンストラクタを通過するそぶりもないし、一応初期化はされてるっぽいし・・・
特にデストラクタのタイミングも分からないのが心配です。
いつ開放されるんでしょうか?
>>377 どこかでnew[]やdelete[]しているだろ?そのときだ。
>>375 newで割り当てたものはdelete、new[]で割り当てたものはdelete[]で解放します。参照の深さは関係ありません。
380 :
デフォルトの名無しさん :2008/02/23(土) 18:12:04
終端をセットしたいのですがどうやったらいいですか? コンパイルが通りません main(){ char *ch=new char [50]; char **start, **end; start=&ch; //これは成功します end=&&ch[20]; // end=&(ch+20); }
381 :
デフォルトの名無しさん :2008/02/23(土) 18:24:57
ch と &ch[0]は同じアドレスを表しますよね 20個目のアドレスは、&ch[20]ですよね それを参照渡ししようとしたら&&ch[20]のはず・・・
char * chend = &ch[20]; end = &chend;
383 :
デフォルトの名無しさん :2008/02/23(土) 18:33:33
>>382 コンパイルはできましたが、startと動作が違うようです
main(){
char *ch=new char [50]; strcpy(ch,"abcdef");
char **start, **end;
start=&ch;
char * chend = &ch[20];
end = &chend;
printf("%c\n", ((*start+1)[2]) );
printf("%c\n", ((*end-5)[2]) );
}
384 :
デフォルトの名無しさん :2008/02/23(土) 18:34:48
間違えました 20個を定義していませんでした これだとうまくいきました サンクス char * chend = &ch[6]; end = &chend; printf("%c\n", ((*start+1)[2]) ); printf("%c\n", ((*end-5)[2]) );
なぜ「end = &&ch[20];」というか「end = &(&ch[20]);」ができないかは理解しておいてね。
386 :
デフォルトの名無しさん :2008/02/23(土) 18:41:41
再使用できるように動的確保したら複雑になってきました・・・ main(){ char *ch=new char [50]; strcpy(ch,"abcdef"); char **start, **end; start=&ch; char **chend =new char *; *chend=&ch[6]; end = &(*chend); printf("%c\n", ((*end-5)[2]) ); }
先ずお前はnewを使うのをやめろ。話はそれからだ。
これはひどい
何がしたのか全然わからない
何度基礎をやり直せと言ったことか
なぜ、再使用しようとすると動的確保することになるのかもわからない。 文章で理由を説明してほしい。
なるほど、stringが出来るわけだ
おまえらほんと我慢強いよな。感心するよ
俺は
>>386 と同レベルのコードを保守する羽目になって殺意を覚えた。
我慢強いというか、読んでない
395 :
デフォルトの名無しさん :2008/02/23(土) 21:02:02
C++の授業で先生が、 int main() { int i; cin>>i; double a[i]; ... というコードはC++では出来ない(やりたいならnewでやるべき)と言われたのですが、 g++とiccではできました。これってだめだけど、gccやiccの拡張機能によって できているのでしょうか?
>>395 現状のC++標準規格じゃ無理。C99は可能。
C99サポートしてるコンパイラなら期待してもいい。
newも使うべきではないよな。いやnew[]ではなくてstd::vector。
C99は正直あんまやらないでほしい
可変引数マクロはマジホシス
0xでおk
402 :
デフォルトの名無しさん :2008/02/23(土) 21:35:03
おしえてください 下から2行目を動かすとデータが壊れるのですが原因がわかりません #include <string.h> #include <stdio.h> #include <stdlib.h> typedef struct STRDATA{ char **st; char **end; }strdata; f(strdata x){ printf("%s",*(x.st)); } strconv(strdata *q, char **p){ char **chend =(char **)malloc(sizeof(char **)); q->st=p; *chend=&(*p)[strlen(*p)]; q->end = &(*chend);} strconstconv(strdata *q, char *p){ int n=strlen(p); char *ch=(char *) malloc(n+1); strcpy(ch,p); q->st=&ch; char **chen =(char **)malloc(sizeof(char **)); *chen=&(ch[n]); q->end = &(*chen);} main(){ strdata str; #define STR "abcdefgh" strconstconv(&str, STR); //ここをコメントアウトして一つ下を動かしても平気です //char *ch=new char [50]; strcpy(ch,STR); strconv(&str,&ch); //char *x=new char [1]; ここを動かすとおかしくなります f(str); }
もうお前いい加減諦めたら。 ローカル変数のアドレスを関数外に持ち出すな。
404 :
デフォルトの名無しさん :2008/02/23(土) 21:39:05
char *x=new char [1]; が、なぜstrdata strを書き換えられるんでしょうか?
なんかまぁ・・・・・・いろいろとおつかれさん
406 :
402 :2008/02/23(土) 21:45:20
おなじやつですが短くしました 下から2行目を動かすと壊れるのはなぜでしょうか #include <string.h> #include <stdio.h> #include <stdlib.h> typedef struct STRDATA{ char **st; char **end; }strdata; f(strdata zzz){ printf("%s",*(zzz.st)); } strconstconv(strdata *q, char *p){ int n=strlen(p); char *ch=(char *) malloc(n+1); char **chen =(char **)malloc(sizeof(char **)); strcpy(ch,p); q->st=&ch; *chen=&(ch[n]); q->end = &(*chen);} main(){ strdata str; strconstconv(&str, "abcdefgh"); // char *test=new char [1]; f(str); }
まず変数のスコープを勉強しよう
408 :
402 :2008/02/23(土) 21:48:09
なぜコメントアウトを外すとデータがこわれますか?
409 :
デフォルトの名無しさん :2008/02/23(土) 21:53:31
newやmallocの確保は、解放しない限り残るんですよね そのアドレスは参照で受け取っているので問題ないと思うのですが 参照渡しにしてもだめです f(strdata *zzz){ printf("%s",*(zzz->st)); } main(){ strdata str; strconstconv(&str, "abcdefgh"); f(&str); }
基礎からやりなおせよ
411 :
デフォルトの名無しさん :2008/02/23(土) 21:56:58
ヒントください
いいから基礎からやりなおせって。スタックとヒープの概念すら分かってないだろ。
>>409 トリップをつけてくれるとあぼーんしやすいのですがいかがでしょうか
スタックとかヒープとか、この際関係ないレベルじゃん
415 :
デフォルトの名無しさん :2008/02/23(土) 22:02:39
より短くしました これでも外すと壊れます なぜですか? #include <string.h> #include <stdio.h> #include <stdlib.h> typedef struct { char **st; char **end; }strdata; f(strdata *q){ char *ch=(char *) malloc(10); strcpy(ch,"abcdef"); q->st=&ch; } g(strdata *zzz){ printf("%s",*(zzz->st)); } main(){ strdata str; f(&str); //char *test=new char [1]; g(&str); }
416 :
デフォルトの名無しさん :2008/02/23(土) 22:03:36
>>409 多少手を入れて(int mainとするとか)こっちで動かしてみましたが、ちゃんとabcdefghと表示されました。
でも、newだけc++の機能をつかってるけど、あとは全部(結構年季が入った感じの)cだし、
c++のコンパイラなら、関数の戻り値を指定しないのはダメだと思うし、
mallocとnew は併用したらダメだってどこかで聞いたけどな。
いまいちやろうとしていることの意図がつかめません。
(mallocとnewを併用して、どういう状況でまずいのかしらべようとしているのか)
もしc++を勉強しようとしているなら、なにか適当な本とかで勉強するのを勧めます。
Cを上記くらいご存知なら、すぐにC++も使えるようになりますよ。
ヒントもなにも
>>403 がずばり回答してるんだが。
これでもわからないなら、なんでもいいからポインタの無い言語に行ってくれ。
そして帰ってくんな。
>>415 なんでお前は答えを貰っても全くレスポンスを返さずに、
そんなヘドロみたいなコードを貼り続けるんだ。
頭沸いてるのか
>>415 これなら動く。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *st;
char *end;
} strdata;
void f(strdata *q) {
char *ch=(char *)malloc(10);
strcpy(ch,"abcdef");
q->st = ch;
}
void g(strdata *zzz) {
printf("%s", zzz->st));
}
int main() {
strdata str;
f(&str);
g(&str);
return 0;
}
421 :
デフォルトの名無しさん :2008/02/23(土) 22:14:15
>>419 それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります
削ったのですがこれでも原因が不明です コンパイラはBCC5.5です
#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; }strdata;
f(strdata *q){
char *ch=(char *) malloc(10);
ch[0]='X';ch[1]='Y';ch[2]='Z';ch[3]=0;
q->st=&ch; }
main(){
strdata str; f(&str);
//char *test=(char *) malloc(1);
printf("%s",*(str.st));}
>それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります ( ゚д゚) ・・・ (つд⊂)ゴシゴシ (;゚д゚) ・・・ (つд⊂)ゴシゴシゴシ _, ._ (;゚ Д゚) …!?
419でどこの文字列がどう書き換えられないっていうんだ言ってみろ
424 :
デフォルトの名無しさん :2008/02/23(土) 22:20:55
VCCやGCCやDMCでも実行中にエラーになります #include <stdio.h> #include <stdlib.h> typedef struct { char **st; }strdata; void f(strdata *q){ char *ch=(char *) malloc(10); ch[0]='X';ch[1]='Y';ch[2]='Z';ch[3]=0; q->st=&ch; } int main(){ strdata str; char *test; f(&str); test=(char *)malloc(1); printf("%s",*(str.st)); getchar(); return 0;}
>>421 >それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります
wwwwwwwwwwwwwwwwwwwwwww
>>419 よ、これが現実だwwwwwアホは相手にするなwwwwww
ぶっちゃけポインタ全く理解してないだろ。
427 :
421 :2008/02/23(土) 22:26:27
誤解していましたすみません
さすがに・・・ 初心者を抜け出した程度の俺でも酷いと思うw
>>424 変数testの用途が不明だったので、削除させてもらった。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *st;
}strdata;
void f(strdata *q) {
char *ch = (char *)malloc(10);
ch[0] = 'X';
ch[1] = 'Y';
ch[2] = 'Z';
ch[3] = '\0'; //まあ0のままでもいいんだけど
q->st = ch;
}
int main() {
strdata str;
f(&str);
printf("%s", str.st);
getchar();
free(str.st);
return 0;
}
430 :
421 :2008/02/23(土) 22:28:56
すみません 誤解していませんでした 書き換えられません #include <string.h> #include <stdio.h> typedef struct { char *st; }strdata; f(strdata *x){ delete x->st; x->st = new char [9]; strcpy(x->st,"++++++"); } main(){ char *ch=NULL; strdata x; x.st=ch; f(&x); printf("%s",ch);}
>>430 お前が421や424で書いたコードは
>printf("%s",*(str.st));
だったのになぜ
>printf("%s",ch);
になってるんだ?納得のいく説明を聞こうか?
432 :
デフォルトの名無しさん :2008/02/23(土) 22:34:55
>>429 int main() {
strdata str;
f(&str); ←ここで初期化された文字列の内容、長さを変更したいんです あと変数testほ確保しても落ちないようにしたいんです
printf("%s", str.st);
みなさんは、
>>424 はまともに動きますか?
>>432 動かすまでもなく、まともに動かないのは分かる
434 :
430 :2008/02/23(土) 22:37:28
>>430 printf("%s",ch);をprintf("%s",x.st);とすればいい。
嫌か?
じゃあこれでどうだ。
#include <string.h>
#include <stdio.h>
typedef struct {
char *st;
} strdata;
void f(strdata *x) {
delete x->st;
x->st = new char[9];
strcpy(x->st,"++++++");
}
int main() {
char *ch = NULL;
strdata x;
x.st = ch;
f(&x);
ch = x.st;
printf("%s",ch);
delete[] ch;
return 0;
}
436 :
デフォルトの名無しさん :2008/02/23(土) 22:39:36
>>433 test=(char *)malloc(1);をはずすと上手くいきます なぜですか
>>436 それは上手く動いてるんじゃなくて、たまたま動いてるだけ
>>335 をチラ見しかしてないけどそれが動くことがとても不思議。
とりあえず期待する動作はなんなのかを日本語で書いてください。
439 :
デフォルトの名無しさん :2008/02/23(土) 22:42:06
>>435 それだと始めにchが巨大に確保されていたらメモリーリークになると思うのですが
>>436 偶然。
あのコードでは、すでになくなったローカル変数を読み取ろうとしている。
運良くメモリ上に残っていれば、一見正しく動いているように見える。
そのtestの行は、残っていた変数の値を破壊する決定打になったのだろう。
見る気もしない。 高速スクロールで華麗にスルー。 違うお題ないの?
443 :
デフォルトの名無しさん :2008/02/23(土) 22:46:11
Perlで言うところの
use LWP::Simple;
sub foo{ return get('
ttp://hoge.com/fuga.zip '); }
これをVC++で極力シンプルにやるにはどうすればいいでしょうか?
環境は以下のとおりです。
VisualC++.net2003 Standard
managedC++不使用 MFC不使用 ATL/WTL使用 STL/Boost使用
444 :
デフォルトの名無しさん :2008/02/23(土) 22:46:57
>>438 バイナリ文字列 (\0を含む) の初めと終わりを構造体で関数に渡して、バイナリ文字列の内容、長さを書き換えたいんです
445 :
444 :2008/02/23(土) 22:48:45
純粋なC言語だけでそれを実現したいんです
>>445 …
一般的に知られている C言語の定義とは違うものを扱ってらっしゃるのですね
447 :
デフォルトの名無しさん :2008/02/23(土) 22:50:53
最終的には、C言語のみにしますけど今は実験段階なので・・・
>>444 なんでchとかtestとか別の変数が出てくるの?
構造体のまま扱い続ければいいでしょ。
449 :
443 :2008/02/23(土) 22:54:26
>>443 単純にC++でネット上のものをダウンロードさせるには
どうすればいいですか?って聞くべきだった orz
450 :
デフォルトの名無しさん :2008/02/23(土) 22:55:14
chは現物の文字列です この初めと終わりのアドレスを構造体で渡して変化させるようにしたいんです
本でも読んで出直してこいよ 本格的に他人に頼りたいなら金でも払え
現物の文字列ってなんだよ ただのポインタだろ str.st と等価だ
453 :
デフォルトの名無しさん :2008/02/23(土) 23:01:55
たとえば、 char *ch=new char [100]; strcpy(ch, "---------"); という文字列に対して、その先頭と後方のアドレスを関数に渡して、関数側で書き換えられるようにしたいんです
何にそんなもんをつかうんかわからんが とりあえずそんなことを考える前に 入門書なりきちんと読め。 たのむから
455 :
デフォルトの名無しさん :2008/02/23(土) 23:09:26
初めの文字列が200M程度確保されていたとして作業領域も200M使うとします このとき初めの文字列を解放するか、上書きすれば最高でも400Mしかメモリを使いません しかし、それができずに返却すると最大 200M + 200M + 200M必要になります
>>449 ソケット使ってカリカリやるしか思いつかん
>>443 手軽さならWinInet
真剣にやるならWinsock
>>450 435みたいに、構造体で渡した後、元の変数に代入し直せばいい。
もはやポインタいらんがなw
460 :
デフォルトの名無しさん :2008/02/23(土) 23:19:19
文字列ではなく、1byte変数の配列を可変長で扱いたいと。 だったら、 typedef struct { char *baka; size_t length; } aho; とでもして、構造体をやり取りすればいいだろ。 C++だったら、vector<char>、deque<char>でも使えや。
461 :
443 :2008/02/23(土) 23:20:13
WinInetででググったらいっぱい出てきたんで調べてみる。 サンクス
463 :
デフォルトの名無しさん :2008/02/23(土) 23:26:44
>>458 なぜ直接書き換えられないのかわかりません
>>463 こっちからしてみたら、なんで構造体を使いたくないのかわからない。
466 :
デフォルトの名無しさん :2008/02/23(土) 23:40:17
もともと構造体は使っていますよ あとC言語のみで動かせるようにしたいんです 開始のアドレスと長さを渡しても上と同じだと思います
あぼーんしたいからトリップつけてくれ
たぶんトリのつけ方を知らない。 「名前欄にレス番つけること」すら今日知ったっぽい
釣りだろう
470 :
デフォルトの名無しさん :2008/02/23(土) 23:46:32
文字列を入力して、
表示するとき右から3文字ごとにコンマをつける方法ってどうすれば?
(例:入力
>>344 fru38fh4tgiur
出力
>>3 ,44f,ru3,8fh,4tg,iur)
この続きお願いします・・
#include <iostream.h>
main()
{
char a[50] ;
cout <<"aに文字を入力してください>>" ;
cin.getline(a, 50) ;
int a_count = 0 ;
while( a[a_count] != '\0'){
a_count++ ;
}
cout <<"aを表示します→" ;
for(int i=0 ; i<a_count ; i++){
cout << a[i] ;
}
}
471 :
デフォルトの名無しさん :2008/02/23(土) 23:48:55
これがたまたまうまく動いたりしますが、実際は間違っているから困っているんです #include <stdio.h> #include <string.h> typedef struct { char *start ; char *end; } bin; void f(bin *x) { delete x->start; x->start = new char [3]; strcpy(x->start,"aa"); } main() { char *ch = new char [2]; strcpy(ch,"a"); bin x; x.start=ch; x.end=ch+strlen(ch); f(&x); printf("%s",ch); }
473 :
デフォルトの名無しさん :2008/02/23(土) 23:53:13
x.start=ch; とした時点で、数値がコピーされるだけになり、文字列を書き換えられなくなります だから x.start=&ch;と参照渡しをするために 構造体を { char **start ; char **end; }に変更します そうすると上記のような現象が出ます
>>471 f(&x);
ch=x.start;
printf("%s",ch);
でいいだろ
って・・・釣られちまったよ〜〜〜〜ん
475 :
デフォルトの名無しさん :2008/02/23(土) 23:56:53
>>473 fを呼んだあとのchが指す先はfの中でdeleteされていることに気づいているか?
476 :
475 :2008/02/23(土) 23:57:42
477 :
デフォルトの名無しさん :2008/02/24(日) 00:03:07
>>475 >>471 ではdeleteやnewが効かない場合があるんです これはちゃんと表示されますか?
#include <stdio.h>
#include <string.h>
typedef struct { char *start ; char *end; } bin;
void f(bin *x) {
delete x->start;
x->start = new char [3];
strcpy(x->start,"aa"); }
main() {
char *ch = NULL;
bin x;
x.start=ch;
f(&x);
printf("%s",ch);}
478 :
デフォルトの名無しさん :2008/02/24(日) 00:06:58
Cで動くようにしたいとかホザいておきながら、new や deleteを使うバカ しかも、 baka = new aho[shine]; としたら delete []baka; とすることしら知らないバカ。 マニュアルでも読め
>>477 じゃあもういいから、こうしとけ
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void f(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"aa"); }
void g(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"bb"); }
main() {
char *ch = NULL;
bin x;
x.start=&ch;
f(&x);
printf("%s",ch);
g(&x);
printf("%s",ch);
}
これで終了、もう来るな
480 :
デフォルトの名無しさん :2008/02/24(日) 00:08:23
>>477 deleteもnewも効いているはずだよ?
・chが指す先をdeleteしようが、x->start=new・・・をしようが、chの中身は変わらない。
・deleteしても絶対に書き込めなくなるとは限らない。
これらは理解している?
481 :
not 477 :2008/02/24(日) 00:10:08
>>478 あ・・・そういえばdelete []baka;としないといけなかったんだ・・・・
C厨ですまん。
構造体はCでないというつもりか?
>>477 main関数内、chだけに注目すれば、
chはNULLで初期化された後、一切変更を受けないだろ。
printfにNULLを渡しているので、未定義。
484 :
デフォルトの名無しさん :2008/02/24(日) 00:18:48
>>479 それだと、 bin x;を初期化する関数と、適当な配列を入れるとバグるんです なんでうごかないんですか
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void f(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"aa"); }
void h(bin *x){
char *ch=new char [3];
ch[0]='X';ch[1]=0;
x->start=&ch; }
main() {
bin x;
h(&x);
f(&x);
char *test=new char [1];
printf("%s",*(x.start));
}
バグるじゃ分らんだろ。
>>484 h内のローカル変数chのアドレスをx->startに格納しているが、
chはhを抜けると無くなるので、x->startは存在しない場所を指している。
>>484 じゃあこれでいいだろう
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void f(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"aa"); }
char *ch;
void h(bin *x){
ch=new char [3];
ch[0]='X';ch[1]=0;
x->start=&ch; }
main() {
bin x;
h(&x);
f(&x);
char *test=new char [1];
printf("%s",*(x.start));
}
488 :
デフォルトの名無しさん :2008/02/24(日) 00:25:03
char *test=new char [1];をのぞくと、bcc5.5では動作します ほかのコンパイラでは、入れなくても実行時に落ちます 原因は何ですか?
いいように使われてるぞ、デバッグ隊w
491 :
デフォルトの名無しさん :2008/02/24(日) 00:27:09
>>488 OSが落ちろ!!って指令を下すからじゃないかな?
おまいらまだ付き合ってやってんのか こいつ分かってるけど、分からないフリしてるだけだろ
494 :
デフォルトの名無しさん :2008/02/24(日) 00:28:54
バカは放置汁。 最初の例から考えると、文字列定数や、文字配列をもdeleteしようとしてるんだから。
495 :
デフォルトの名無しさん :2008/02/24(日) 00:30:19
>>486 >>487 しかし、これはどのコンパイラでも正常に動きませんか? C++ですが
#include <stdio.h>
#include <string.h>
void h(char *&x){
char *ch=new char [11];
strcpy(ch,"ABCDEFGHIJ");
x=ch; }
main() {
char *x;
h(x); printf("%s",x); }
>>495 うん。それはローカル変数アドレスを取る(ポインタを取る、参照を取る)
ということをやっていないから問題ない。
>>495 そのhは、chの「値」をコピーしているので、
chが無くなっても値はxに格納されているから動く。
>>484 はchの「アドレス」を格納しているだけ。
>>488 プログラミングは諦めたほうがいい
1.簡単な事をややこしくして
2.バグを入れて
3.聞きまくることで他人の邪魔をする
別の仕事探せ
少なくともオレはそれを勉強熱心とはいえない
500 :
デフォルトの名無しさん :2008/02/24(日) 00:41:03
だから、バカは放置だって。 手段に固執して、何の目的でそのイミフな手段をとろうとしているのか自分でわかってない。
501 :
デフォルトの名無しさん :2008/02/24(日) 00:41:58
確認したいのですが、newは、deleteするかプログラムが終了するまで解放されないはずですよね? タスクマネージャで確認するとf()を抜けてもメモリはそのままです #include <stdio.h> f(){ char *x=new char [200*1024*1024]; } main() { f(); getchar(); }
>>495 ちなみに、それをポインタを使って書き直すとこうなる。
#include <stdio.h>
#include <string.h>
void h(char **x) {
char *ch = new char[11];
strcpy(ch, "ABCDEFGHIJ");
*x = ch;
}
int main() {
char *x;
h(&x);
printf("%s",x);
return 0;
}
503 :
デフォルトの名無しさん :2008/02/24(日) 00:43:28
だからローカルで定義された変数や配列でも、そのアドレスが判明していれば、main()などで操ったり解放できますよね
504 :
デフォルトの名無しさん :2008/02/24(日) 00:46:04
>>503 マニュアル嫁
ヒープの意味を理解してからnew や delete を使え。
変数の記憶クラスを理解しろ
ローカル定義は外に抜けたら、内容が残っている保証はない allocしたなら残っているけど
>>503 だからの前後が繋がってないぞ
newした領域がdeleteされるまで解放されなかったら
なぜローカルで定義された変数や配列をmainから操れることになるんだ
507 :
デフォルトの名無しさん :2008/02/24(日) 00:49:11
なぜですか? 間違っていないと思いますよ これはmain()側で解放してます #include <stdio.h> #include <string.h> void h(char **x) { char *ch = new char[200*1024*1024]; *x = ch; } main() { char *x; h(&x); getchar(); delete x; getchar();}
>>507 それはhのローカルで定義された変数chをmainから操ってるわけではないな
単にnewした領域へのポインタchをmainのxにコピーして渡してるだけだ
509 :
デフォルトの名無しさん :2008/02/24(日) 00:54:23
一度目のキー入力で、200M分メモリを解放しますよ タスクマネージャみてください
伸びがいいから何かと思ったら未だ相手にしてたのか。
>>507 newで確保したメモリへのポインタをmainに連れて行っているだけ。
newやmallocで確保したメモリはソース上のスコープに縛られずに使える。
一方、
>>484 では、x->start=&ch;というように、
ローカル変数へのポインタをmainへ持って行っている。
しかし、mainに戻ったときには既に変数chそのものが居なくなっているのでうまくいかない。
見事な無自覚の自己中心主義だな、早く治せよ
>>507 なにしてるかわかってるならいいけど、ポインタ一回お浚いしたら?
>>507 あんたはnewで確保した領域と、それを指すポインタ変数を、同一のものであると勘違いしてないか?
>>507 のコードでも、ポインタ変数chはhを抜ける時に消滅するのは分かるか?
まずchar *x の xは、int xや float xと同じで、ただのローカル変数であることを覚えとけ
515 :
デフォルトの名無しさん :2008/02/24(日) 01:04:18
しかしこれは動きません #include <stdio.h> #include <string.h> typedef struct { char **start ; char **end; } bin; void h(bin *x){ char *ch = new char[11]; strcpy(ch, "ABCDEFGHIJ"); *(x->start)=ch; } main() { bin x; h(&x); printf("%s",*(x.start)); }
516 :
デフォルトの名無しさん :2008/02/24(日) 01:04:59
>
517 :
デフォルトの名無しさん :2008/02/24(日) 01:05:04
free(p)ってやるとpがNULLになるとか思っちゃう人なのかな。
お前らバカの相手すんなって。つけあがるから。
>>515 x->startをまったく初期化しないまま、*(x->start)なんかに代入しているのが間違い。
>>513 に答えろ
俺結構ポインタの理解があやふやで、だからなるべくポインタのややこしい部分には触れないプログラム今までしてきたんだけど、 このスレ読んだらなんとなく理解できてきた気がする。 C言語でnewとdeleteを使い続けてる人ありがとう! あと、もちろん解説してくれてるみんなもありがとう! 明日からもstringばりばり使っていこうと思います。
>>515 そうだね、それは動かないね
だから?
何を聞きたいのか明確に
522 :
デフォルトの名無しさん :2008/02/24(日) 01:09:53
ポインタ変数が消滅するのはわかります 関数での、初期化と書き換えをする方法がわかりたいです
>>515 #include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void h(bin *x) {
char *ch = new char[11];
strcpy(ch, "ABCDEFGHIJ");
*(x->start)=ch; }
int main() {
bin x;
char *p;
x.start = &p;
h(&x);
printf("%s", p);
delete[] p;
}
524 :
デフォルトの名無しさん :2008/02/24(日) 01:10:30
new/deleteを使うということは当然C++だよな? じゃあ、なんでメモリ操作を隠蔽するクラスを作ろうとしないの? IQ低いから?
525 :
デフォルトの名無しさん :2008/02/24(日) 01:10:53
>>522 みんなが何回も例を出しているのに・・・(T_T)
>>524 上のほうで最終的にCで書くと言っていたはず。
俺にはなんで今はnew[]使ってC++にするのか理解できないけど。
>>522 おまいがポインタについて知っている知識をすべて述べよ
>>522 何度か出てる正しく動く例が気に入らない理由はなぜかね
仮に、彼へC言語ポインタ完全制覇を与えたとしても、 それでわかってくれるかどうか不安になる。
>>522 皆が何言ってるかほとんど分からないC++素人だけど
一日ぐらい気分変えて犬の散歩にでも行ったら?
まあ、犬のウンコの処理しながら考えたりさ
その後で、また一から作ってみる
以外とできるかもよ
531 :
デフォルトの名無しさん :2008/02/24(日) 01:21:40
>>523 それだとうごきました サンクス
x.start = &p;
h(&x);
printf("%s", *x.start);
初めにメモリ上にchar*型が確保されないと受け取れないって事か
>>530 犬のウンコの処理を考えたり に見えて
delete unko;とか脳内で実行しそうになった
533 :
デフォルトの名無しさん :2008/02/24(日) 01:28:09
>>523 pを確保しなくても、これでもいいはずですよね
int main() {
bin x;
x.start = new char *;
h(&x);
printf("%s", *x.start);
}
newしたらdeleteしとけよ
>>533 newしたものはdeleteしないといけないのが面倒だから、
使わずに済むなら避けるべき。
だから、newを捨てるところからはじめろって。
C及びC++を使いゲームを作成された方へ質問です。 再帰関数って便利ですか? もしよろしければ、メリットとデメリットを教えていただけないでしょうか? 自分の考えでは、 goto と同じ用に無理に使う必要はない機能だと思ってます。
再帰関数については色々思うところがあるのだが、ゲームを作っているわけではないからなぁ。
無理に使う必要は無いなぁ メリットデメリットという問題でもない気がする
>>537 ポリゴン(ボーン)の操作で便利
でも、無理して使わなくてもおk
ボーン操作ってことは、データの読み込み時に便利ってことでしょうか?
【環境】 MS WinXP/gcc 3.4.4 on cygwin
【ソース】
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/6079.txt 【用途】 IRCクライアント(bot)
【起動方法】 $ ./a irc.tokyo.wide.ad.jp 6664
【動作の現状】
1.コマンドラインからサーバ名とポートを受け取り、ソケット作成、コネクション確立
2.サーバからのコネクションメッセージ受け取り
3.USER/NICKコマンドの送信
4.ウェルカムメッセージ、MOTDの受け取り
5.半角英数のチャンネル名へのJOIN ←ここで停止する
【質問】
・Telnetで同じように接続すると問題なく接続→終了することができる(ISO-2022-JPだから文字化けするが正常)
・送受信周りがかなりいい加減なのでJOIN出来ないのはそこに問題があるのではないか?
イレギュラーなことをやってますが、IRC板orスレというよりCネットワークプログラミング自体の問題かと考え
こちらに質問させていただきました。よろしくお願いいたします。
>>541 typedef struct _D3DXFRAME {
LPSTR Name;
D3DXMATRIX TransformationMatrix;
LPD3DXMESHCONTAINER pMeshContainer;
struct _D3DXFRAME *pFrameSibling;
struct _D3DXFRAME *pFrameFirstChild;
} D3DXFRAME, *LPD3DXFRAME;
座標系の上に座標系があって、
さらにその座標系の上に座標系が…
と繰り返すので、スタックを自前で管理するより
再帰処理にしたほうが楽というだけ
(体-上腕-腕-手-指 のように繋がっていくので)
>>542 カンなので外してたら無視してくれ
>for(i=0;i<=strlen(p);i++){
\0も送信してるが、いいのか?
i<strlen(p) なんじゃない?
>>543 for分で体のパーツ数回してデータを読み取ってるんですが、
今は無理してそれを崩してまで使う機能ではないってことですね。
よく機能を理解して使えば楽になる物、ということですね。
答えてくれた方ありがとうございました。
>>542 メッセージの終わりを\n → \r\n に変えてみたらいけるかも
547 :
デフォルトの名無しさん :2008/02/24(日) 03:33:50
>>530 俺はオナニーして発射した後、ティッシュで拭いてる時にコードが閃くよ。
548 :
546 :2008/02/24(日) 03:56:01
あと、
>>544 と同じく\0の送信は不味いんでは?
\nでメッセージの終わりを判断してるとすると、サーバは次のメッセージの受信で
先頭に\0が入ってしまうんではないかと思う
(2回目のメッセージが、"\0JOIN #ircclidev\n"になるんじゃないかな)
>>544 ,
>>548 i<strlen(p)で解決しました。初歩的ミスもいいところだ・・・。
もう一つ質問があるのですが、(どちらかというとこちらが本題ですが)
ISO-2022-JP(いわゆるJISコード)とShiftJISを相互変換するライブラリorサンプルを探しています。
検索してもなかなかしっくり来るものがなく、nkf経由だと上手くISO-2022-JPの制御コード
(KI/KO=0x1B 0x24 0x42/0x1B 0x28 0x42)を取ることが出来ません。
RFCには、特にマルチバイト環境の規定は定められていませんが、日本語IRCサーバは
ISO-2022-JPを使っているところが主流のようです。
552 :
デフォルトの名無しさん :2008/02/24(日) 05:52:14
すんません。 VC++6.0からVisualStudio2008に移ったんですが、外観が変わりすぎててチンプンカンプン・・・ どこかVisualStudio2008 Exp の解説やってるページとかありませんか? dllすら読み込めぬ・・・。orz
Visual Studio2008スレにGO
554 :
デフォルトの名無しさん :2008/02/24(日) 10:24:08
自分でクラスを定義するときに、ポインタに対する演算は、定義しなくてもよいのでしょうか? つまり、ポインタでも、int*とか、char*とかの型がありますが、例えば myclass*==int* とかやるとコンパイルエラーになります。でも、myclass1*==myclass2*は、==演算子も 定義してないのに、コンパイルできるし、ちゃんと動きます。 これは、どういう理由でできるんですか?というか、ポインタの比較をする演算子って どこで定義してるんでしょうか? 変な質問ですいません。
継承関係があるんじゃない?
>554 規格上で「できる」と決められている処理ははコンパイラが勝手に処理してくれる、というだけ。 myclass1*==myclass2* は >555 の言うとおり myclass1 と myclass2 に継承関係があるんだろう。 この場合、暗黙の型変換が発生して同じ型になり比較できる、と決まっている。 で、規格で決められている以上のポインタに対する演算を、自前で定義する必要があるケースはまずない。
557 :
デフォルトの名無しさん :2008/02/24(日) 10:55:39
>>554 違う型のポインタの比較はダメ
int* a;
double* b;
a == b
をやってみれば意味がわかるんじゃないかな?
558 :
デフォルトの名無しさん :2008/02/24(日) 12:50:04
C++で配列を関数の引数にできますか?
配列の参照か、配列のポインタか、配列要素のポインタならできます 配列自体は無理
ポインタじゃダメなのか?
>>558 できる
template <size_t n>
void func((&a)[n]) のように
型がねえ
すまん忘れた
564 :
デフォルトの名無しさん :2008/02/24(日) 13:14:21
>>559-563 ありがとうございます。
たしかにできませんでした。でも、
template <class T, int N>
int func(T a[N])
{
...
}
こういう様に書いても(func()の引数に&を付けても付けなくても)、aは参照扱いになるようです。
aに対して変更を加えると、func()の呼び出し側の元配列にも変更が反映されました。
そりゃaはポインタなんだから。
>>564 aは参照でなくてdecayされるからポインタだろ
567 :
デフォルトの名無しさん :2008/02/24(日) 13:36:59
>>565-566 そうか。ポインタですよね。
ポインタをコピーして、その先まで複製してくれるのはありえないですよね。
ありがとうございました。
構造体かクラスでラップしとけばいい。 boost::array を使うとか。
C++で乱数を扱う為のクラスとか関数はありますか? rand/srand使うしかないですか? rand/srand使うとしたら、シードによく現在時刻使いますが 現在時刻を取得する方法はtimeしかないですか? ++らしい方法があれば教えてください。
MT法のインラインアセンブラ版がどっかにころがってたきがする
javascriptではalert("文字列"+123) という風に文字列と数字を一緒にメッセージ表示出来ましたが、 C++で文字列と数字を一緒にメッセージ表示させるにはどうしたらいいでしょうか? MessageBox(NULL, "文字列"+123, "test", NULL) というのは出来ませんでした。
>>573 JavaScript同様、文字列を連結してから表示すればいい。
>>574 char msg[20] = "文字列";
char tmp[10];
itoa(123, tmp, 10);
strcat(msg, tmp);
MessageBox(NULL, msg, "test", NULL);
こんな感じですか?
メッセージ毎にこのコードを書くのも面倒臭いのと、
いつも "文字列"+数字 の組み合わせと言うわけでもなく
数字+"文字列"+数字+"文字列" という事もあるため
自作関数でmsgbox(char*, int){}という決め撃ちではやく、
文字列や数字を混同で表示できる方法はないかと考えています。
お願いします。C言語初心者なんですが、 ソース内に日本語を入れるとエラーになるんですが、 どこをどうすればいいのでしょうか? 超初心者です。よろしくお願いします。
× ああああ ○ //ああああ
ソースから日本語を消す
579 :
576 :2008/02/24(日) 17:27:51
説明へたですいません。 /* hello02.c */ #include <stdio.h> int main() { printf("今日はよい天気です。\n"); printf("明日もよい天気でしょう。 \n"); return 0; } これなんですけど…
>>570-572 ありがとうございます、Boost 試してみます。
手元の mingw にはなさそうなので、まずはgooって
Boost 環境揃えてみますね。
>>576 ・ソースの文字コードを変えてみる
・処理系を変えてみる
582 :
576 :2008/02/24(日) 17:36:23
本当にすいません。 普通に表示されました。 なんか間違ったやりかたしてたみたいです… 申し訳ないです。
>575 そのためのsprintf、とだけいっておくけど。
>>583 sprintfだとメッセージウィンドウは生成されないですよね?
外見としてはMessageBoxの中身に数字や文字列を表示している様な方法がいいんです。
sprintfのsは何の意味か知っているか、とだけ言っておくけど。
>>584 ならsprintfしてMessageboxにいれる処理の関数つくればよくね?
要はフォーマット→MessageBox()と 二段構えになるのが嫌、というだけの話とエスパー vsprintf()使って自作ラッパー関数でも書くんだな
>>584 boost::lexical_cast
を使うと幸せになれると思う
>>585-588 失礼しました。printfと勘違いしてました。
sprintfだと文字列に格納できるんですね。
boostは自分にはまだ早そうなので(正規表現使えるのは魅力的ですが)、sprintfでやってみます。
ありがとうございました。
>>588 俺も最初それ思いついたけど、連結する数値がたくさんあると見苦しくなるから
std::stringstreamに流し込んで取り出す方がいいんじゃないかなあ。
592 :
デフォルトの名無しさん :2008/02/24(日) 18:45:34
DLLの読み込みで、コンパイラによって失敗します 序数で指定しても動きません どのような理由でしょうか? VC++だと動かないですが、BCCとDMCで動きます
593 :
デフォルトの名無しさん :2008/02/24(日) 18:47:43
HINSTANCE hd=LoadLibrary("*****.dll"); FN = (fnc) GetProcAddress(hd, (LPCSTR)4); //序数での指定 このような記述はWindowsXPなら万能ではないんでしょうか?
594 :
デフォルトの名無しさん :2008/02/24(日) 18:50:46
訂正 読み込みはしますが、実行時にエラーになります 序数がずれるのかも・・と思い全ての番号で試したのですがだめです
595 :
デフォルトの名無しさん :2008/02/24(日) 18:52:47
継承について教えてください CFooから派生したCFooEx0、CFooEx1、CFooEx2、CFooEx3があるとします。 そして、それぞれCJissou0、CJissou1、CJissou2、CJissou3に派生してるとします。 その上、CJissou0、CJissou1はIHoge0を、CJissou2、CJissou3はIHoge1を実装しているとします。 図にするとこんな感じ。 CFoo─CFooEx0┬CJissou0 IHoge0┘ CFoo─CFooEx1┬CJissou1 IHoge0┘ CFoo─CFooEx2┬CJissou2 IHoge1┘ CFoo─CFooEx3┬CJissou3 IHoge1┘ CFooとCFooEx〜は弄らないとして、IHoge〜のインターフェイス関数をCJissou〜に実装します。 で、マネージャー的な物例えば、std::vector<CFoo *> vecにそれぞれの実態を入れて、 CJissou〜の関数を呼びたいのですが呼ぶ際には、 dyanamic_cast<CJissou0 *>(vec[0])->Test();見たいな事をしないといけないと思います。 でもそういう呼び出しだとIHoge〜も意味が無くなってしまうし、数が多くなると厳しくなります。(IHoge〜は数個) だから、dyanamic_cast<IHoge0 *>(vec[0])->Test();//エラー 見たいな呼び方をしたいのですがどうすればいいのでしょうか?
>>595 そもそもそのような継承にしてる理由は?
>>595 CFoo のメンバ関数ならキャストは要らないはず。
IHoge〜 に意味が無くなると言うが、こっちからしたら CFoo や vec の使い方も
ひっくるめて最初からその継承関係の意味がわからん。
598 :
595 :2008/02/24(日) 19:06:57
えっと、まあ、CFooがMFCのCViewで、CFooEx〜がCTreeViewとかCListViewなのでどうした物かと質問しました・・・。
なんでvector<IFoo>とかにしないわけ? あるいは、virtual Test()をもつ何かインターフェースに。
CFooEx の状態で持てないのなら ダウンキャストすることになるだろうな。
602 :
592 :2008/02/24(日) 20:05:24
最適化オプション関係でした
boostが?
ごめん勘違い
文字コード?jisコード?って覚えるべきもの?
必要になったときに表を見れば十分
>>606 全てのJIS漢字のJISコードなんて、そうそう覚えられるもんじゃないと思うが。
class Piyo{ 〜 }; class Hoge{ public: void hoge(Piyo[][256]); }; void Hoge::hoge(Piyo[][256] piyo){ 〜 } こんな実装をした時に、Hoge::hogeのpiyoを書いておくと'Piyoは未定義のシンボル'と怒られてしまいます。 仮引数をPiyo[][256]だけにすればコンパイルは通りますが、どう使えというのか・・・といった感じです。 コンパイラはBCC5.5を使っています。クラスの2次元配列をできれば「参照」で渡したいのですが、 どうすればいいんでしょうか?
単に書き方がおかしいだけだ。 void Hoge::hoge(Piyo piyo[][256]) { しかもこれいわゆる参照渡しの挙動をするが、 正確にはポインタ渡しだし。
611 :
609 :2008/02/24(日) 21:29:18
うわ・・・。確かにおかしな書き方してた・・・。 自分でもドン引きです・・・。ありがとうございました
613 :
デフォルトの名無しさん :2008/02/24(日) 23:20:24
ReadFile(fp , &(buf[N]) , 1500 , &sz , NULL); でエラーで止まります bufは十分にとってあります なぜでしょうか
>>613 bufの宣言がどうなっているかにも拠るが、&(buf[N])をbufにしてみろ。
それで巧くいくなら、お前は馬鹿だ。
615 :
デフォルトの名無しさん :2008/02/24(日) 23:31:32
位置を変えてループして読もうとしてるんです bufにすると上手くいきますが前のデータが消えます 原因不明ですが、変数の位置変えたらエラーでなくなり一応うごくようになりました
たまたま動いてるだけくさいな。 単純にバッファオーバーフローしてるだけじゃないのか?
617 :
デフォルトの名無しさん :2008/02/24(日) 23:36:56
メモリ関係のエラーみたいです また止まりました 別のところから変更しないと直りそうにありません 設計やり直してきます
618 :
デフォルトの名無しさん :2008/02/24(日) 23:48:58
coutやnewの多重定義ってどうやるのかわかりません できますか
>>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]
cout の多重定義??
<<のオーバーロードに違いない
ostream& operator<<(ostream& ostr, const Hoge& hoge) { ostr << hoge.str(); } みたいなやつか。
623 :
デフォルトの名無しさん :2008/02/25(月) 00:07:21
stringは連続していますか? memcpyとかはできますか?
なんでstringにmemcpyしたがる人が多いんだろう。
stringにmemcpyはまずいんじゃね
626 :
デフォルトの名無しさん :2008/02/25(月) 00:10:45
string s="9999999999"; strcpy( &s[5], "000"); は正しいですか
詳しいことわすれたけど、s[i]で文字を取得できるならできるんじゃね? やった後、stringオブジェクトは壊れるとおもうけど
この日本語不自由そうなとこが同一人物くさい
>>627 あっ嘘、s[i]で取得できてもできないと思う
置き換えたいなら、replaceを使いなさい
>626 std::stringのことなら、正しくない。
632 :
デフォルトの名無しさん :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;}
633 :
デフォルトの名無しさん :2008/02/25(月) 00:25:35
stringの制御情報はどこへ格納されていますか? ユーザーは合法的でない方法を使ってもアクセスできませんか?
>632 必要のないポインタ操作はやめましょう。 動くか動かないかがプログラムの正しさの判定基準ではありません。
>>632 あるコンパイラのあるバージョンで動くとしても、規格で保証されていなければ、
他のコンパイラや同じコンパイラの別バージョンでは動かないかもしれない。
それでもいいなら、どうぞ?
今後ずっと同じコンパイラを使い続けて、決して変えないのなら、たぶん問題ないだろう
例外の使い方について エラーの通知にはエラーメッセージより例外を使う方がいいと聞いたのですが オリジナルな例外クラスを投げたり、charを投げまくる仕様にしていいのですか? 例外というと、これ以上の実行に支障が出るときに使うようなイメージがあるのですが実際の現場ではどうなのでしょうか?
例外処理を主要処理に書くと遅くなったりしませんか?
コンパイラによって例外処理用のコードが追加されるから パフォーマンスは落ちる。禁止オプションもあるくらいだからな。 特に組み込みでは。。。。。。
640 :
デフォルトの名無しさん :2008/02/25(月) 01:17:11
クラスメンバー変数は、自動で0やNULLで初期化されますか?
>>637 好きなように使え。
ただ、エラーメッセージと例外では通知する相手が違うぞ。
エラーメッセージはエンドユーザ、例外はプログラマに通知するもんだ。
ユーザがいきなり「0x00d2345でlogic_error例外が発生しました」とか見せられても訳わからんだろ。
charも投げられるが、標準との整合を考えて投げるのはオリジナルも含めてstd::exception派生のクラスにしとけ。
>>640 static領域に配置したオブジェクトのメンバなら、コンストラクタで何もしていなければ0になります。
それ以外は不定です。
643 :
デフォルトの名無しさん :2008/02/25(月) 01:29:37
static つけたらクラスが消滅しても値が残るんですか? クラスが消滅したらアクセスできなくなると思いますが つけなくても自動でstaticになりますか
>>641 なるほど・・・
戻り値でエラーを知らせたり、NULLを返したりという方法もあるのでどういう方法が主流なのかなと思ってまして
自分はたいていの場合
何が起こったのか確認して、何事もなかったかのように受け流してさいごにエラーログを確認する
位のデバッグライト的な使いか確かしてないのですが・・・
>>644 どれが主流というのは無い。場面によって適切な方法があるだけ。
ライブラリとか、設計思想によりエラーの返し方がある程度統一されてたりすることもあるけどね。
とにかく作ってみなさい。できたものを自分なりに分析して、ここはこうした方がよかったとか、省みることで成長するんだから。
>>643 残ります、というかクラスを複数生成しても全部同じstaticメンバ変数をさすんですよ?
三行目がいまいちなに言ってるのかわからんstaticつけないとstaticにはならないよ
まずインスタンスという言葉を覚えようや
>>643 >static つけたらクラスが消滅しても値が残るんですか?
(クラスではなくインスタンスのことを言いたいのだと思うが…)
staticで宣言した変数は、main関数の開始前から終了後まで存在する。
破棄されるのがmain関数終了後だから通常はそれへのアクセスが問題になることはないが、
staticの変数が異なるファイルで定義されて、一方のデストラクタからもう一方を参照するような
処理があるとまずい。
意味が分からないようなら気にしなくていい。
>つけなくても自動でstaticになりますか
ならない。
649 :
648 :2008/02/25(月) 02:14:21
ちょっと訂正 ×staticの変数が ○2つのstaticの変数が
質問があるのですが、 include " " include < > " ", < > の違いを教えて頂けませんか?
>>650 コンパイラのマニュアルか入門書を読みなさい。
>>632 std::string の内部バッファの連続性は次の規格で保証されるようになる。
おそらく現状全ての実装でそうなっていることが、その規格変更を実現したんだろう。
だから一応そう言うことをしても問題は無いはずだが、
メンバ関数でできることはメンバ関数でやった方がいい。
replace 使うといい。
例外ねぇ、何も考えずにint型のエラーコードを投げちゃうなぁ 返り値でエラーコード返しちゃうと返り値の型が拘束されちゃうしメンドクサ 結局こういう使い方だと例外のありがたみを半分も得ていない気がする
例外はstd::exceptionみたいな基本クラスを決めとかないと ありがたみが半減する。
656 :
デフォルトの名無しさん :2008/02/25(月) 11:44:36
ガベージコレクションは、標準のC++でつくれますか?ライブラリでは動作するのか不安です 自作したいです あと、整数変数は、初期化なしでアクセスしてもエラーは出ませんか?
素人が自作した方が不安だと思うんだが
658 :
デフォルトの名無しさん :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(); }
659 :
デフォルトの名無しさん :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(); }
>>656 整数変数を初期化しなくてもエラーは出ませんが、ローカルな場合に不定値なので初期化しましょう。
661 :
デフォルトの名無しさん :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(); }
662 :
デフォルトの名無しさん :2008/02/25(月) 12:42:21
値渡しされているかフラグを作って、されていれば解放する様にすればいいのですが、 初期化前にコンストラクタで代入されてしまうとフラグが確認できません
663 :
デフォルトの名無しさん :2008/02/25(月) 12:47:11
>>661 は間違えました 定数式が期待する方へ行っていませんでした それもどうやれば直りますか
>>661 やりたいことがよくわからん。せめて、コンパイルできるソース(の断片)を貼ってくれ。
665 :
デフォルトの名無しさん :2008/02/25(月) 13:00:43
まとめるとテンプレート関数で、 定数文字列" "と 固定文字列char [n]と 可変文字列char *を 区別して、上の二つならメモリを確保して値渡しにしたいんです 値を書き換えたいため
最近ずっとこいつ出没してるな
667 :
デフォルトの名無しさん :2008/02/25(月) 13:02:01
それと、新たにメモリを確保するときに、以前確保したメモリを解放してメモリリークしないようにしたいです
>>667 要は、const char *でコンストラクトするときはメモリを確保して、char *でコンストラクトするときは確保しなければ委員でね?
それと、書き換えのときはconst char *でもchar *でも以前の状態に応じて解放しないといけないんでね?
669 :
デフォルトの名無しさん :2008/02/25(月) 13:07:20
簡略化すると関数の引数で、" "型と、char[]型と、char*型を区別したいって事です
670 :
デフォルトの名無しさん :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();
}
すまん、そもそも char ch[] = "yyy"は固定長でも書き換え可能な配列なんだが それを定数として扱ってはいけない理由を教えてくれ。
あ、聞き方が変だ。 char ch[] = "yyy"は書き換え可能なんだから可変長と同一視すればいいし const char ch[] = "zzz"は書き換え不可能なんだから定数と同一視すればいいのでは?
673 :
デフォルトの名無しさん :2008/02/25(月) 13:22:41
可変長文字列と {定数文字列、固定長文字列} ( ← 一緒でいいです) を分類する方法教えてください あと、すでにメモリが確保してあればそれを解放する方法教えてください
674 :
デフォルトの名無しさん :2008/02/25(月) 13:23:36
長さも書き換えられないといけません
こいつ日本人なのかなぁ
>あと、すでにメモリが確保してあればそれを解放する方法教えてください これは簡単。コンストラクト時にメモリを確保したらフラグをセットしておいて、代入オペレータでそれをチェックすればいい。 勿論、代入オペレータも2種類用意して必要ならフラグをセットするのは当然として。 そのフラグはいずれにしてもデストラクト時に必要にナル死ね。
あー、ローカルな配列だとコンストラクト時にフラグが立ったら問題か。 ここは一つ、char配列は渡さないと言う運用でw
で、この馬鹿はなんで目的を説明できないんだろうなぁ。>675ってことなんだろうか。
679 :
デフォルトの名無しさん :2008/02/25(月) 13:43:23
目的は、参照渡しのできるstringを作りたいんです 現存するやつは値渡しです
いやだから、それを(態々)作る目的を聞いているのだが。
チャットじゃないんだから要旨をまとめてから書き込め。
682 :
デフォルトの名無しさん :2008/02/25(月) 13:46:53
>>676 クラスの確保と同時に代入されてしまうと、フラグが設定されていないので動作不明になりませんか?
683 :
デフォルトの名無しさん :2008/02/25(月) 13:50:39
>>681 可変長文字列は参照渡しにして、それ以外は値渡しにして、新たな文字列が渡されたら以前のを解放したいんです
伸びてると思ったら、また例の日本語が不自由なヤツが現れたのか
686 :
デフォルトの名無しさん :2008/02/25(月) 13:56:58
何をしたいかと言うと (バイナリ) 文字列 str , p , qに対して replace(str, p, q) strの全文でpをqに置換する という関数を作りたいんです
>>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);
}
//テスト int main() { f("abc"); char a[5]; f(a); char *p; f(p); }
689 :
デフォルトの名無しさん :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); }
>>689 そりゃコンパイラがだめなんだろうな。
g++ 4.2.3だとa b cになる。
>>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;
}
>>686 俺だったら、次のどっちかにする。だから、673のようなことをしたくなる理由が理解できない。
1. strは全く書き換えず、置換後の文字列は新しく確保したメモリに書き込んで戻り値に返す。
2. strは書き換えできるという前提でstrを書き換える。(書き換えできない
文字列をstrに渡したければ、書き換え可能な場所へコピーを作ってそれを渡す)
693 :
デフォルトの名無しさん :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", "(^_^)"); がしたいんです
694 :
デフォルトの名無しさん :2008/02/25(月) 14:29:10
巨大な配列を扱おうとすると、元のデータをコピーしたり、返却時に新規確保すると、
もとのデータと併せて領域が2倍必要になりますしコピー時間がかかります
>>691 バリナリデータも扱いたいです
>>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;
}
696 :
デフォルトの名無しさん :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; }
>>694 置換前より後の文字列のほうが長い場合、
単純にその場で書き換えていくと、1ヶ所置換が行われる度に
置換部分以降をずらしたり、時にメモリの伸張をしたりで時間がかかる。
最近のOSはメモリの扱いも上手になっているし、
そもそもPCのメモリ搭載量も大きくなっているから、
新しいメモリに書き込んでいくも選択肢として捨てたものではない。
>>689 VC++ 2008でしか試してない。オーバーロード解決は規格に従って
いるんだが。コンパイラがテンプレート規則に対応していないのかね。
699 :
デフォルトの名無しさん :2008/02/25(月) 14:48:28
>>695 >>697 stringにコピーするのが一番なんですかね?
関数で作業領域を確保しようとするので 初めの3倍必要になります
コピー無しなら2倍ですみます 300メガとかだと動作に支障出ないですかね・・
>>698 うちのコンパイラだと全滅しました MinGWの最新版 、DMC、VC++6.0、bcc5.5.1
700 :
デフォルトの名無しさん :2008/02/25(月) 14:51:46
>>692 2番の方向で行こうとしているところだったんです
定数なら書き換え可能な領域を確保しようとしたら、その判別がコンパイラでできないのでここで質問していたんです
>>699 new char[]せずに最初からstringの中にデータを作ればコピーを減らせる
int N=300*1024*1024;
string str2;
str2.resize(N);
for(int n=0;n<N;n++)str2[n]=n; //巨大なバイナリ配列
replace(str2, "geho", "(^_^)");
702 :
デフォルトの名無しさん :2008/02/25(月) 14:57:26
わかりました stringに直接挿入する方向で行こうと思います 巨大な入力があるのはファイルからなので、自作して直接stringに入れるようにします
>>699 >コピー無しなら2倍ですみます 300メガとかだと動作に支障出ないですかね・・
stringの操作云々よりも、その情報量をどう扱うかと言うアルゴリズムの方が問題になりそうな希ガス。
少なくとも、GiBオーダ未満のメモリくらい今時普通に扱えるよ。
>>696 どう、機能していないのさ。
ちゃんと目的を説明すれば、妥当な回答が手早く得られると言う好例だな。
705 :
692 :2008/02/25(月) 15:03:09
>>700 俺の場合、その判別は自分でやる。
必要なら自分でメモリ確保してmemcpyか何かでコピーしてから置換する関数へ渡すと言うこと。
メモリ確保その他をstringに任せているという点が違うけど、695案と同系統のアイデア。
>>696 関数突入を探すwhileの条件がcount != 1だから、関数突入後に中括弧を見つけるとcountが2になって脱出できなくなる罠。
>>696 >706に加えて、内側のwhileは両方ともifでいいだろよ。
つまり、最初のwhileは if (count == 0)で、次のwhileはif (count > 0)。
んで、fin >> bufferだと単語単位でしか入力できないから工夫が必要。
# 行単位入力すればいいのかな? 仕様がわからんからなんとも言えんが。
708 :
デフォルトの名無しさん :2008/02/25(月) 15:13:01
初めはC言語のみで、作成しようとして最後まで作ったのですが ポインタのポインタとかやっているうちに動かない場合があることに気づき修復不可能になりました そしてC++で参照や型判定して作ろうとしたらこれも上手くいきませんでした 簡明なプログラムが大事ですね
709 :
デフォルトの名無しさん :2008/02/25(月) 15:20:04
ここできいたのを参考に変換関数を作ってたのですが、そしたら全体がややこしくなり回復無理になりました #define strconv(q, p) _memconv(&q, &p, strlen(p)) #define memconv(q, p, n) _memconv(&q, &p, n) #define strconstconv(q, p) _strconstconv(&q, p) _memconv(strdata *q, char **p, int n){ char **chend =(char **)malloc(sizeof(char **)); q->start=p; *chend=&(*p)[n]; q->end = &(*chend);}
>>708 ,709
無理して難しく書いても、あとあとメンテナンスやデバッグのことを考えると、シンプルに書いた方がいい場合が多い
メモリを何MBか余計に使ったり、実行時間が何分か伸びたところで、なんだというんだ
ややこしいコードは書くのもデバッグも何日もかかる
それだけの価値があればやってもいいが、たいていは割に合わない
やさしいC++買って来た。 一日でマスターするのは無理なのかなぁ・・・
一週間くらいは覚悟しないといかんね
一年ぐらいは(ry とか言いたいけど最低10年とかいう意見もあるし やね某が何年か前に提唱した半年ぐらいで勘弁しておいてやろう
714 :
デフォルトの名無しさん :2008/02/25(月) 18:04:09
質問ですが、stringの+は、\0を特別視しませんよね? "aa\0aa" + "bbbbb"はどのコンパイラでも、 "aa\0aabbbbb"ですよね?
いつからCは+演算子で文字連結できるようになったんだ
stringと書いてあるだろうがアホ
そこは中身がそうなっているstringインスタンスだと解釈してやろうぜ。
質問者はそういう中身のstringを造ろうとしてそこでつまりそうだが
721 :
デフォルトの名無しさん :2008/02/25(月) 19:30:23
std::auto_ptrって、ブロックを出ると自動的に開放されるポインタですよね? これって、AUTO変数と比べてより便利な点ってあるのでしょうか?
×ブロックを出ると自動的に開放 ○std::auto_ptrが破棄されたときインスタンスも自動的に開放
>>721 ・スタックに置くには適さない巨大なデータも置ける
・最初はNULLにしておいて必要になってからnewできる
・ブロックを出るまで待たなくても好きなタイミングで削除できる
・releaseで手放せばブロックを出ても削除しないことも出来る
関数の戻り値にも使えるはず。
using namespace std; string func1() { string s = "Hello"; return s; } void func2(string s) { cout << s << endl; } int main() { func2(func1()); } この渡し方って解放されなかったり破壊されたりしますか? 処理系によりけりですか?
727 :
デフォルトの名無しさん :2008/02/25(月) 19:59:12
>>722-724 ありがとうです。
ところで、testは適当なクラスとして、
int main()
{
std::auto_ptr<test> tp(new test);
tp.release();
return 0;
}
とすると、メモリリークが検出されてしまうのですが、tp.release()をしないようにすると
大丈夫でした。これってrelease()の使い方が間違ってますか?
あと、最初にauto_ptr<test>だけ宣言しておいて、途中でnew testする方法もわかりません。
もうちょっとだけ教えてくださいな。
releaseは、以後、自分でメモリ管理するからauto_ptrはdeleteするなというもの。
729 :
デフォルトの名無しさん :2008/02/25(月) 20:14:08
>>728 最初は、
std::auto_ptr<test> tp(new test);
tp.release();
test* tp2 = tp.get();
delete tp2;
としていたのですが、以下のようにしなければならないということですね。
std::auto_ptr<test> tp(new test);
delete tp.release();
ありがとうございました。
resetはVC6のauto_ptrには無いとか言い出すぜきっと。
resetもしないでデストラクタに任せればいい場面にまで 729のようなことをしていないか不安。
設計について色々調べていると(デザインパターン等々)これ無駄じゃね?みたいな部分に多々遭遇します 例えばコンストラクタとデストラクタで確保&解放を行う為に全体をそれに合わせたり それの為にメソッドやクラスを用意したり等々 確かに見通しもよくなりますし、わかりやすくなるとは思うのですが、 それらを犠牲にすれば短く出来たりオーバーヘッドを減らせたり出来るんじゃないか?と考えてしまいます つまりコード全体の見易さ、転じてメンテナンスが容易になるなどのメリットと 速度を犠牲にするというデメリットがあると思います とはいえ後者は今時気にするほどでもなく、詳しくないのですがここを気にするのは組み込み系と呼ばれる分野くらいなのかなとも思います 実際はやはり見易さ等を気にした手法(なんていうんだろう?)を用いて設計を行うべきなんでしょうか? うまく表現できなく、長くなってしまってすみません
Visual Studioって 何処にヘッダファイル置けば
Visual Studioって 何処にヘッダファイル置けば フルパス指定しなくて読み込めるんですか? C:\Program Files\Microsoft Visual Studio 8\VC\include でOK?
>>735 ソースファイルと同じ場所なら
#include"hoge.h"
でおk
737 :
デフォルトの名無しさん :2008/02/25(月) 21:09:06
>>733 大丈夫
君よりコンパイラのほうが賢いから
速度犠牲とか偉そうに言うやつほど、ダメなプログラマ
普通の初心者質問には答えないんだなぁ
本当に遅くなることばかりじゃないしな。 std::sort が qsort より概して速くなる、というみたいに、 インライン化されると問題ないことも多い。
>>738 色んな分野があるって前提で考えてるんだろう?
お前は組み込み系とビジネスソフト開発が同じだと思っているのか?
それにプログラミングしてればみんなプログラマって思考が気持ち悪い
お前見たいのは答える側に回るな
742 :
デフォルトの名無しさん :2008/02/25(月) 21:14:59
プログラマではないです、ただいろんな分野があってそれに合ったプログラミングがあることくらいはわかっています でもやっぱり速度は気にしちゃいけないところですか、無駄だと思ってしまうところから直す必要がありそうですね コンパイラの最適化というのも知らない分野ですし、当分は見通しの良いプログラムを目指してみようと思います
まず動くプログラムを書く。 そして遅ければ改善する。 この順だな。
744 :
696 :2008/02/25(月) 21:19:34
これをちょっと弄って横長から縦長にしたいのですが、 いまいち組み方がわかりません。環境はLinuxでコンパイラはgccです。 #includeは省略 #define max 50 using namespace std; class hist{ private: string buffer; int count; int mat[max],i,j; public: int func(char *argv[]);}; int hist::func(char *argv[]){ ifstream fin(argv[1]); if(!fin)return 0; for(i=0;i<max;i++)mat[i]=0; while(fin>>buffer){ count=strlen(buffer.c_str()); for(i=1;i<max;i++){ if(i==count)mat[i]=mat[i]+1; } } for(i=1;i<max;i++){ cout<<i; for(j=0;j<mat[i];j++)cout<<"*"; cout<<'\n'; } return 0;} int main(int argc,char *argv[]){ hist hoge; hoge.func(argv); return 0; }
746 :
696 :2008/02/25(月) 21:28:43
すみません、あげるの忘れてました。 どなたか教えてください。
GNU global使えていう話じゃなくて?
748 :
744 :2008/02/25(月) 21:37:58
>>747 そんなソフトがあったんですかw
ありがとうございます。
しかしそれではコーディングトレーニングにならないので、
ソースコードでよろしくお願いいたします。
どう考えてもイメージがわかないもので質問した次第です。
はじめまして C++でプログラミングをしようと思っているのですが 開発環境等をどうしようか迷っています 将来的には ■ゲームを動かすプログラム(同人やエロゲのアプリ程度) ■補助ソフトやパッチ ■データを暗号化して格納するプログラム 等を作りたいと思っています 何かアドバイスがあればお願いします
VC++ でいいっしょ タダだし
751 :
744 :2008/02/25(月) 21:48:04
>>749 「C++の勉強したいんだがどの本買って勉強したらいいんですか?」
って聞いてるのと一緒だべ?
デザインパターン信者 私にもそんな時期がありました(マジで)
80:20の原則があるしな。経験つめばどこがホットスポットなのかが見当つくから、 プロファイルとってそこだけしぼって最適化すればいい。 最初から保守性犠牲にしてまでパフォーマンスチューニングが必要な分野って 限られてると思うよ。
>>749 今からC++勉強するよりもおまいは吉里吉里勉強したほうが幸せになれると思う
755 :
744 :2008/02/25(月) 22:06:01
マイヘッドがクラッシュしてしまいそうなんですが、 エニバディー、ティーチ ミーしてくれませんか?
トオルさん帰れよ
>>744 関係はないが、とりあえずバッファを buffer_size しか確保してないのに
fgets で filesize 読もうとしてるのはヤバい。
760 :
744 :2008/02/25(月) 22:29:05
>>758 bufferはstring型でいこうとおもったんですが、
fin>>buffer;でやると、単語読み込みで一行読み込みにはならないし、
fgets(buffer.c_str(),filesize,fin);はコンパイラに怒られるし、
どうしようもないんで駆け込み寺としてここにきました。
たぶんこれも慣れた人なら簡単に直せるんだとは思いますが、
いままでC言語ばっかりやってたもんで、変な癖ついてるんです。
getline を知らんのか?
762 :
744 :2008/02/25(月) 22:32:36
>744 よくわからんが、 一行よむなら、std::.getline( fin, buffer );だが。むろん、finはifstream辺りの必要はある。 初めて"{"が存在する行をみつけたとき、上のifでcount++になって、 下のifも成立してでcount++で2になるんだが、そういうものなのかね?
どこのK&Rだ、どこのw
>>750 あと必要な物はやる気と根気ですかね?
>>751 "だべ"ってどういう意味ですか?
マルチリンガーじゃないので日本語以外わからないんです、本当にごめんなさい。
767 :
744 :2008/02/25(月) 22:43:14
>>759 else ifですか。基本的なところ躓きました。
ありがとうございます。勉強になりました。
>>763 そんな関数があったんですか。
ちょっとgetlineの中をのぞいて使わせてもらいます。
>>764 Cアンサーブックのほうです。
バイブル本とか釣られてやってみたけど、
糞面白んないんで解くのやめました。
768 :
デフォルトの名無しさん :2008/02/25(月) 22:44:52
可変のchar *のバッファ用意したいとき string buf (n, '\0' ); &buf0]; ← これはchar*のところへ入れられる と使うと便利だ 自動で消滅するし
769 :
744 :2008/02/25(月) 23:06:24
>>768 下のほうhtmlのタグみたいですね。
奥の手っぽいんでどうしようもないときに使ってみます。
ありがとうございました。
>>744 さっき、恐らくは想定したと思われる仕様を完璧に満たすソースを書いたんだが、
反応がなかったから会社に置いてきちゃった。次に会社に出るのは3日後なんで、
後で寝ちゃわなければ軽く再現してみるよ。
>>770 >次に会社に出るのは3日後なんで
何でだ?
なんか、「それを記すにはあまりにも2chの投稿制限は厳しい」みたいに 続きそうな文章だなw
>>749 本体 > VC++
開発用ユーティリティ > TurboC++ Exploer (BCB)
でいいんでないの?
VC++はGUIアプリの構築はそれなりに手間かかるし、BCBは紙芝居の開発じゃ全然VCLの長所が生かせない。
>>771 単に、明日明後日は客先直行直帰だから。
>>744 手直ししながら、「クラスにする必要ないじゃん」とか
「変数は極力局在化しろよな」とか「マクロシンボルは大文字だろ」とか
「入力にfgets()を使うなら出力はfputs()じゃないか」なんて乗りで
修正してたらこうなった。
#include <cstdio> #include <cstring>
#define BUFFER_SIZE 1000
int func(char *argv[]) {
FILE * fin = fopen(argv[1],"r");
if (fin == NULL) return 1;
unsigned count = 0;
char buffer[BUFFER_SIZE];
while(fgets(buffer, sizeof(buffer), fin)!=NULL) {
if (count == 0) {
if (strchr(buffer,'{') != NULL) {
fputs(buffer, stdout);
count++;
}
} else if (count > 0) {
if (strchr(buffer,'{') != NULL) count++;
if (strchr(buffer,'}') != NULL) count--;
fputs(buffer, stdout);
}
}
fclose(fin);
return 0;
}
int main(int argc,char *argv[]) {
return func(argv);
}
775 :
744 :2008/02/26(火) 00:36:44
>>774 まぁ人には癖があるからね。
ありがとう。
人と自分のソースを比較するのが、
一番勉強になるよ。
>>775 >774は常套句の宝庫だと思うよ。fgets(buffer, sizeof(buffer), fin)とか。
>744のクラスは、変数をばら撒くだけでクラスとしては何もしない無意味な設計だったし。
後はあれだな、関数に渡すのはconst char *にしてmain()で予めargcのチェックと
argv[1]の抽出位しておくのが常套手段か。
777 :
744 :2008/02/26(火) 00:57:36
>>776 途中で配列にしたら楽だろうなぁとかは思ったが、
配列だと途中でサイズの変更が利かないから。
ポインタだと動的メモリの割り当てで適当なサイズに
割り当てできるし、と思っただけです。
別に機能さえあってればどのやりかたでもいいんだけど、
個人的には
stdoutの使い方がいまいちわかんなかったから、
そこが勉強になったのと、マクロの名前が大文字ね。
それ完全に忘れてたから勉強になった。
ありがとうってのは主にそこかなぁ・・・。
クラスは再利用に機能を発揮するから今の段階では必要としていないけど、
あとあと拡張していくにあたって必要になってくるから残しておきました。
確かにこの辺は言わんとわからんかったかもしれない。
突っ込まれたんで補足しておきました。
>726 ありがとう、ちょっと不安だったんだ。 名前も無いまま渡されるオブジェクトってどうなるんだろ、って。
ある関数に引数として構造体のポインタを渡し、そこにアドレスをセットして 返してもらうにはどう書けばよいのでしょう? BOOL hoge( HOGE *ptr ) { …略 ptr = address; return TRUE; } としても上手く動かないようです。
>>779 整数を受け取るには整数のポインタを渡す必要がある。
構造体を受け取るには構造体のポインタを渡す必要がある。
構造体のポインタを受け取るには構造体のポインタのポインタを渡す必要がある。
あ!なるほど。こんな感じでしょうか? BOOL hoge( HOGE **ptr ) ちなみにC++なのですが、参照渡しを使ってこれは良いのでしょうか? BOOL hoge( HOGE *&ptr ) 一応コンパイルは通るのですが…
OK
783 :
デフォルトの名無しさん :2008/02/26(火) 11:34:24
同じクラスなら、別のインスタンスのprivateなデータも参照出来ますよね。継承関係が ある場合には、親オブジェクトから子オブジェクトを通して親オブジェクトのprivateデータを 参照できたのですが、これってこういうもの? #include <iostream> using namespace std; class test2; class test { public: void func(const test2 &a); private: int p; }; class test2 : public test { public: void func2(const test2 &a); }; void test::func(const test2 &a) { cout << a.p << endl; } test2 T2; int main() { test t; t.func(T2); return 0; }
そういうもの。
>>783 というか出来ないとまずいだろ。
コピーコンストラクタとか代入演算子の定義が出来なくなってしまうよ。
protectedじゃなくてもアクセス出来ちゃうの?
protectedにすると、さらにtest2からも参照できるようになる
788 :
デフォルトの名無しさん :2008/02/26(火) 13:01:03
プログラムにZIPを解凍する機能を盛り込みたいのですが、そのような 機能のスタティックリンクできるライブラリをご存じないでしょうか? 環境はVisualC++.net2003です。
>>783 じゃないが試してみたけど
同じクラスのインスタンスへの参照やポインタを持つとアクセス権限ブッチぎれちゃうのか
なんかカプセル化とかそういう面で考えると気持ち悪いというかなんというか
仕様上出来ないと仕方ないと言うのも分かるのだが・・・
789d
C++のprivateはクラスプライベートであってインスタンスプライベートの意味ではない
>>782 すみません、寝てました。返答有難うございます。
ちなみに「ポインタ変数を参照で渡す」と言う意味ならむしろ
BOOL hoge( HOGE &*ptr )
のような気がするのですが、なんで*&ptrなのでしょう?
それが仕様と言われればそこまでですが。
>>793 typedef HOGE * HOGE_PTRしてみれば判る。
>>794 >>795 なるほど。正直きちんと理解できたかは自信ないですが、ちゃんと法則が
あってそうなっているのは分かりました。
どうも有難うございましたm(__)m
797 :
デフォルトの名無しさん :2008/02/26(火) 14:46:05
vc2008のコマンドラインコンパイラだけ手に入りますか vc6でコンパイルしたいです sp1で鈍いパソコンです
EEを入れてみたか?
>>797 コンパイラだけ手に入れるのは無理だが
コマンドラインでの利用はできるよ
800 :
デフォルトの名無しさん :2008/02/26(火) 14:56:40
sp1にインストールできますか
>>792 kwsk
according to standard
802 :
デフォルトの名無しさん :2008/02/26(火) 15:49:24
すみません DOSの実行ファイルで、標準出力へは書き出されないメッセージを取得する方法ありませんか? hoge.exe > log.txt として取得できないやつです 画面には出ます 標準出力、標準エラーの取り方はわかります
>>802 それのどこがC/C++に関係があるの?
805 :
デフォルトの名無しさん :2008/02/26(火) 16:34:10
>>803 標準出力はこれで受け取れますが、exeが返す実行結果がとれません
#include <windows.h>
main(){
HANDLE hFile = CreateFile("log.txt",GENERIC_WRITE,FILE_SHARE_WRITE, NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
SetStdHandle(STD_OUTPUT_HANDLE , hFile);
STARTUPINFO si; PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
si.hStdOutput =hFile ;
si.hStdError =hFile ;
si.wShowWindow = SW_HIDE;
CreateProcess(NULL, "HtoX32c.exe e:\\0.htm ", NULL, NULL, FALSE,0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hFile);
}
HtoX32とやらが標準エラー出力に出している可能性は無い? そもそも、まさかHtoX32はWindowを持っているアプリケーションなのか? だとしたら、メッセージフックなどの手段が必要になるよ。 つーか、HtoX32とやらが何ものかにも依るけど同等のプログラムを自分で書いた方が手っ取り早かったりしてね。
807 :
デフォルトの名無しさん :2008/02/26(火) 16:59:39
HTMLをテキストに変換するプログラムです ソースが公開されていたり定番のライブラリとかありませんか?
808 :
デフォルトの名無しさん :2008/02/26(火) 17:03:03
正規表現での消し方のサンプルみながら自分でやってみます
popenを使えたら楽だな あればだけど
>>805 そのコードだと、自プロセスの標準出力が hFile になるけど、子プロセ
スの HtoX32c.exe の標準出力はコンソールのままでは?
812 :
デフォルトの名無しさん :2008/02/26(火) 17:44:15
1つの関数に複数の構造体を渡すことって可能でしょうか? suruct typedef{ int x,y; }SAMPLE; SAMPLE sample; suruct typedef{ int x,y; }SAMPLE2; SAMPLE2 sample2; void AA(??? *s){ int a = s->x; int a = s->y; } void main(){ AA(&sample); AA(&sample2); } こんな処理をしたいのですが、???の所がわかりません。 良い方法を教えていただきたいです。 仮の構造体を1つ作って、その変数に代入→渡すってやり方だとできましたが 激しく面倒くさい。
関数オーバーロード、もしくはテンプレート関数でぐぐれ。
>>812 typedef SAMPLE SAMPLE2;
815 :
デフォルトの名無しさん :2008/02/26(火) 18:02:57
>>813 >>814 情報ありがとうございます。
テンプレート関数が一番やりたかった事を解決してくれそうでした。
ありがとうございました。
構造体のメンバを決め打ちするようなテンプレート関数は感心しないな。 テンプレートを使うということはC++で良いので、それならメンバ関数にしてしまった方が良い。
817 :
デフォルトの名無しさん :2008/02/26(火) 18:22:32
ifstream::readって実際に何バイト読めたか検出できないんですか? freadみたいにふつうに戻り値が来るのかと思いきや違うみたいですし…。
つ gcount
>>817 自己レス。failで少なくとも期待通りの
バイト数読めたかどうかは取得できるのね。
>>818 と思ったらそんなメソッドがあったか。サンクス
821 :
デフォルトの名無しさん :2008/02/26(火) 18:31:39
fstreamは重要なところでは使うべきではない APIのほうがよい
んなこたーない
823 :
デフォルトの名無しさん :2008/02/26(火) 19:18:08
fstreamは一社の開発ではないがAPIはMS一社 どのコンパイラでも同じ動作になる あと3000個とか開けない
if文って 文字列と文字列を比べることって出来ないですよね? 1 = あいうえお 2 = かきくけこ 3 = さしすせそ 4 = あいうえお if (a = 1){ } みたいなことをやりたいのですがどうしたら良いでしょうか?
825 :
デフォルトの名無しさん :2008/02/26(火) 19:19:44
stringはできる
> どのコンパイラでも同じ動作になる コンパイラで差はないかもしれないが・・・
>>823 んなばかな
APIがMS一社で規定されてるなんて初めて知った
MSはついに世界を征服したのか
828 :
デフォルトの名無しさん :2008/02/26(火) 19:23:04
Windowsのファイル入出力APIのことを指す
830 :
デフォルトの名無しさん :2008/02/26(火) 21:19:23
CreateProcessしたときに止まらなくなったら停止させたいんですけど どうやったらいいですか?
831 :
デフォルトの名無しさん :2008/02/26(火) 21:22:25
ググって解決しました
マルチスレッドで動かしてる関数って_endthread()書かなくてもreturn;書いてたら 問題ない?
VC6.0です。 __declspec(dllimport) int __stdcall hoge( LPWORD, LPWORD, LPWORD ); という形の関数のアドレスが入る関数ポインタhageを作りたいのですが、 うまく宣言できません。 __declspec(dllimport) int __stdcall (*hage)(LPWORD, LPWORD, LPWORD ); などとやるとコンパイルエラーになってしまいます。 どうすれば宣言できるのでしょうか?
declspecは関係ないだろ
関係あるよ
関数ポインタで悩んだら、typedef typedef __declspec(dllimport) int __stdcall hogetype( LPWORD, LPWORD, LPWORD ); hogetype hoge;
関数ポインタの便利さになれすぎてしまって 最近 if を見るたびにすぐ関数テーブル化してしまう。 間違い?
なるべくシンプルにかくのを推奨されますからね
840 :
デフォルトの名無しさん :2008/02/26(火) 22:43:09
関数テーブル間違いです 鈍いです
841 :
デフォルトの名無しさん :2008/02/26(火) 22:47:58
なんかCreateProcessすると不安定になる スレッドでsystemで実行してみる CreateProcessを短期間に20回以上使うと動かなくなるエラーってありますか? 実行する側のexeのせいかもしれないですが
テーブルだめなのか・・ if の中にさらに if があるともうその地点でうわ・・って思ってしまう。 ちょっとソース見直してみます
そこでBoost::functionとコールバックですよ。
>>842 無理して避けることもないよ。何事も程々が1番。
グローバル変数って絶対使わない方がいいんですかねえ 例えばゲームプログラムを作っていて、状態を管理するグローバル変数を使っているとする。 その変数には、ゲームの進行に合わせて、例えば 定数(TITLE=0, STAGE1, STAGE2, STAGE3, STAGE_CLEAR, GAME_OVER, ENDING)が入るとする。 処理は上の状態それぞれでモジュール化されているとすると、 どうしても状態管理変数はグローバル変数化してどの状態からでも 参照・設定できるようにせざるを得ないと思うのですが、何かいい手があるのでしょうか。 状態管理変数をファイル内static変数にしてセッターを使って書き換えるようにしたり、 状態管理変数とセッターをクラスにしてそのオブジェクトのスコープをグローバルにするもしくは状態管理変数とセッターを staticにしてどのクラスからでも書き換えられるようにするくらいなら最初から状態管理変数をグローバルにしといた方が シンプルだと思うのですがどうでしょうか。
847 :
デフォルトの名無しさん :2008/02/26(火) 23:03:57
数が多くなければOK、重要ならOK
>>846 静的なシングルトンもグローバル変数も似たようなもんだ
グローバル変数でいいんじゃね?
ただ、関数経由にしておけばデバッグするときに setter で引っ掛ければいいだけだから
ずいぶんと楽になる*かもしれない*
>>846 シングルタスクなら良いけど。
GUIでスレッド使って随時処理しながら入力待ちして、
入力はコールバックで処理、みたいのだと、
ゲッタやセッタ作った方が排他処理し易いかなぁ。
まぁケースバイケース?
ゲーム状態のインスタンスが1つだけなら、グローバル変数でいいと思う。 インスタンスが複数なら、 状態ごとの処理に、状態管理変数をクラス化したものを渡すとか、 もしくはstateパターンなんてのもいいかもしれない。
どうせグローバル変数的に使うとはいえ、 それゆえにどこから変更されてるかを追跡するためにも >関数経由にしておけばデバッグするときに setter で引っ掛ければいいだけだから というのは地味に大事
ゲーム状態も例えば、プレイヤキャラの他にAIキャラが裏で進行中なんてことになると、 グローバルだと破綻するよね。そんな場合はゲーム状態はキャラクタに依存する情報になるわけだけど。
シングルトンとグローバル変数は違う。
グローバル変数として使ってる間違ってる例が多いのが勘違いの原因かもしれない。
自分だったら
>>846 の場合、シーンマネージャクラスを作ってそいつに振る舞いを管理させる。
極力グローバル変数は使わない。
シングルトンは初期化のタイミングを選べるからグローバルとは大きく違う。
結局オブジェクト指向の導入でCにおけるグローバル変数使用の問題は解決できてないんじゃねえの Cを極めればオブジェクト指向言語を使わなくても良いコードが書けるんじゃねえの結局クラスとか オブジェクトとかデザインパターンとか複雑で分かりにくくするなだけじゃね
856 :
デフォルトの名無しさん :2008/02/27(水) 00:21:36
system は空白が改行のように扱われてしまいます パラメータは渡せませんか?
ファイルの読み込みについての質問です。 ---- 2008/02/20,01:00:00 2008/02/21,02:00:00 2008/02/26,03:00:00 … ---- と書かれたファイルを、 tmp[0] = 2008; tmp[1] = 2; tmp[2] = 20; tmp[3] = 01; といったように取り込みたいです。 スラッシュとカンマとコロンを区切りにしてうまく取り込む方法を教えてください。 もし、スラッシュしかなければstrtokとatoiでできたのですが、3種類あるので困っています。 よろしくお願いします。
見た感じフォーマットは固まってるだろうから 単純に先頭からパースするだけじゃね
861 :
デフォルトの名無しさん :2008/02/27(水) 00:29:09
string s; s.substr(0,4); s.substr(5,2); s.substr(7,2); とかでいいのでは?
>>858 fscanf(fp, "%d/%d/%d,%d:*[^\n]", &tmp[0], &tmp[1], &tmp[2], &tmp[3]);
863 :
デフォルトの名無しさん :2008/02/27(水) 00:31:50
>>859 自己解決しました 同名のexeがありそれが動いていたようです
862の訂正 *の前に% fscanf(fp, "%d/%d/%d,%d:%*[^\n]", &tmp[0], &tmp[1], &tmp[2], &tmp[3]);
>>855 >Cを極めればオブジェクト指向言語を使わなくても良いコードが書けるんじゃねえの
これは当たり前なんだが、(といってもオブジェクト指向を使わないって意味じゃない、
Cでもオブジェクト指向は昔から存在する)
>結局クラスとかオブジェクトとかデザインパターンとか複雑で分かりにくくするなだけじゃね
何が複雑なんだ?
デザインパターンなんか当たり前の設計パターンに名前付けただけじゃないか。
変数へのアクセスを制限することで単純になるんだけどなぁ。 無制限に変数にアクセスできたほうが複雑だって、わかんないかなぁ。
867 :
デフォルトの名無しさん :2008/02/27(水) 00:48:26
Perlの文法が糞なのは間違いない。
868 :
858 :2008/02/27(水) 01:12:38
>861 レスありがとうございます。 が、、私ではうまいこと使えませんでした。ごめんなさい。。 >860, 864 fscanfでできました。 どうもありがとうございました。
869 :
デフォルトの名無しさん :2008/02/27(水) 01:23:50
C++で配列のコピーってどうやりますか? for()文で代入を回す?
870 :
デフォルトの名無しさん :2008/02/27(水) 01:24:40
memcpyが最速では
>866 何を以て「単純」とするかに依るんだろうな。 多分 >855 は言語の構造として単純であること、習得の容易さなどを見て言っているんだろうが 大きなコードを、そのまま扱うと中身はかなり複雑化する。 クラスや名前空間などを使って、大きなコードを小さな部品の集合体として考えて それぞれの部品単位で扱うことで、ひとつひとつの部分は単純になる。
>>870 C++ で memcpy() は使わない。禿との約束だよ。
874 :
デフォルトの名無しさん :2008/02/27(水) 01:30:02
推奨されていなくても確保の仕方から vectorでもstringで有効でしょう memcpy
memcpyより自分でアセンブラ書いた方がはやかったんだけど、そんなもん?
877 :
デフォルトの名無しさん :2008/02/27(水) 01:39:54
memcpyより早いコードくれ
SSE使ったんだけどね
879 :
デフォルトの名無しさん :2008/02/27(水) 02:17:49
マイクロソフトのCHMファイルはなかなかいいんだけど SJISしかコンパイルできなくて、サイズが20Mとかになるとコンパイルに失敗する CHMをパクってWindowsの標準ヘルプ形式を作りたい 参加者募集中 圧縮接尾辞配列がいいと思う ブロックーソーティングしたデータはそのまま全文検索できるとおもうがどうか?
880 :
デフォルトの名無しさん :2008/02/27(水) 02:27:20
複数のテキスト文書を圧縮できてかつ高速に全文検索できて CHMのような普及率を目指したい デスクトップサーチとは目的が違う 元のファイルが復元できてまとめられる点が大事
tarでいいじゃない
882 :
デフォルトの名無しさん :2008/02/27(水) 02:33:30
tarは全文検索できるように設計されてるの?
tarは圧縮しないからね。
>>875 アラインメントに縛りを入れれば早くはできると思う
885 :
デフォルトの名無しさん :2008/02/27(水) 02:46:44
半分にはならないとだめだな chmは全文検索できて元の半分になるよ
>>880 専ブラのログをまとめるのに便利そうだ
あてにせず期待してるよ
887 :
デフォルトの名無しさん :2008/02/27(水) 03:29:32
badc$の巡回データは adc$b dc$ba c$bad $badc ソートすると $badc adc$b badc$ c$bad dc$ba ブロックソートではcb$daというデータのみが与えられる 復元しようとするとここまでは直ぐわかる $***c a***b b***$ c***d d***a c$、ba、、$b、dc、adと繋がっていることがわかる たとえばdcというデータは何番目に出現するか求めるとすると末尾のcから調べていけば良さそうだが
std::string のような STL クラスを前方宣言するにはどうしたらいいですか? それともこういうクラスって前方宣言しないでヘッダーに直接 include させても問題ないですか?
Visual C++ Express Edition を入手したので、簡単なプログラムを作ってみようと思ったのですが、 なぜかコンパイルできません。 コマンドラインで、 cl c:\source.cpp としても、 'cout' : 定義されていない識別子です。 'endl' : 定義されていない識別子です。 等とエラーが返ってきます。 ちなみに、ソースは以下のようなものです。 #include <iostream> int main(void) { cout << "Hellow, World!" << endl; return 0; } なぜエラーになるのか分かりません。お暇な方いましたら、どうかお知恵をお貸しください。
×cout << "Hellow, World!" << endl; ○std::cout << "Hello World!" << std::endl;
891 :
デフォルトの名無しさん :2008/02/27(水) 04:21:19
あんたが外国にいるんじゃなかったら、本を買って勉強しる。 とりあえず、 std::cout << "Hellow, World!" << std::endl; としてやってみ。 もしくは、 using namespace std: をinclude 文の下に書いておくとか。 まあがんばれ。
>>890 ありがとうございます。
using namespace std; を追加したらコンパイルできました・・・ ^ ^;
最初、#include <iostream.h> としていて、コンパイル時にそんなファイルは無いと言われ、
#include <iostream> に直したら今度は cout が定義されて無いと言われ・・・
完全に勉強不足ですね・・・・
>892 環境によっては #include <iostream.h> と書くと、using namespace std; を勝手にやってくれるんだわ。 多分、そういう環境を前提にしたコードだったんだろう。
ついでに勉強不足の俺に教えてください #include <string.h> #include <stdio.h> #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { string a = "0908a89"; printf("%s\n", a); getchar(); return 0; } aに0908a89が代入されて無いみたいなのですが、何処がまずいのでしょうか?
いろいろまずい。 というか、それVCならコンパイルとおるの?gcc 2.96だと少なくとも通らない。 ・string.hってCの奴じゃないかな。#include <string>と書くべし ・その場合aってのはstring型なので、printfに%sで受けるのはよろしくない。 書くならprintf("%s\n",a.c_str()); ・でも、せっかく#include <iostream>してるんだから cout << a << endl;でいいじゃん。 ・ところで最後のgetcharは何のために? 以上直すと、こっちでは代入されるよ。
>>895 ありがとー 出来ました。
コンパイルは出来てましたがNULLが表示されました。
getchar();しないと画面が速攻閉じてしまうので、画面確認用にです。
>>896 修正したソースを張ってみないと有効な回答は得られないと思うよ。
898 :
デフォルトの名無しさん :2008/02/27(水) 09:09:57
int* random_array(int n); shared_ptr<int> p(random_array(100)); というように書けないのですが、shared_ptrの作成時って、必ずnew[100]とかって やらないとだめなのですか?
>>898 arrayの共有にはshared_arrayな。
それとエラーメッセージ書かないとエスパーしか解答できない。
900 :
デフォルトの名無しさん :2008/02/27(水) 11:36:18
system("path %PATH%; C:\\hofe;"); が有効になりません・・・ なぜでしょう
>>900 環境変数はプロセスごとに別々だから
子プロセスを起動してPATHを設定させても自プロセスには影響しない
902 :
デフォルトの名無しさん :2008/02/27(水) 12:07:43
改行しても無理でした パスを直うちするか、そこへ移動するしかないですか? APIでPath設定できるか調べてみます system("path C:\\hofe; \n abc.exe");
903 :
デフォルトの名無しさん :2008/02/27(水) 12:20:15
pathを追加する方法教えてください わかりませんでした
SetEnvironmentVariable
905 :
デフォルトの名無しさん :2008/02/27(水) 12:30:25
サンクス 長い実行パスと、長いパラメータパスで困ってました これで解決しそうです
#include "stdafx.h" #include <string> #include <stdio.h> #include <iostream> using namespace std; 略) string x; sprintf(x, "%02x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); これで、buf[0], buf[1], buf[2], buf[3], buf[4]の値をstring型 でx代入したいんですけど xが定義されていないと怒られてしまいます。どうしたら良いのでしょうか?
907 :
デフォルトの名無しさん :2008/02/27(水) 13:39:20
string x(11,'\0'); sprintf(&x[0], "%02x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); これは無理?
まず間違いなく大丈夫ではあるものの一応標準外の仕様だと心にとどめておくといい
910 :
デフォルトの名無しさん :2008/02/27(水) 14:02:11
winsockを使うときエコーバックするのは普通ですか? それとも負荷を下げるためにしませんか? 少量ずつデータ受け取ればミスしにくくなると思うんですけど 少しずつ受け取って確認無しでいいですか
次の改訂で標準になるけど、コンパイラの対応が普及するまで合わせると、 問題ないと言えるのは何年も先かなぁ。
912 :
デフォルトの名無しさん :2008/02/27(水) 14:09:00
http先のファイルのサイズやcrcを取得する方法教えてください それみてデータが正常が判定したいです
>>912 サイズはレスポンスヘッダのContent-Length (ない場合もある)
CRC は無理かと
915 :
907 :2008/02/27(水) 14:46:39
もう一つ教えて下さい。 char str[100]; sprintf(str, "%02x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); char str0[100]; char str1[] = "01061719d0"; char str2[] = "0106171f34"; if (strcmp(str, str1) == 0){ printf("この番号は登録されています@\n番号%s\n",str); } else if (strcmp(str, str2) == 0){ printf("この番号は登録されていますA\n番号%s\n",str); } else { printf("この番号は登録されていません\n番号%s\n",str); } このようなif文にしたいのですが、登録したbuf[]を読み込んでも"この番号は登録されていません" と表示されてしまいます。なぜでしょうか?
std::vectorとCStringでは、empty() (とEmpty()) の意味違うのね〜 しばらく騙されてました。
917 :
デフォルトの名無しさん :2008/02/27(水) 14:54:36
stlのset使った方がいいんじゃない
919 :
デフォルトの名無しさん :2008/02/27(水) 15:06:37
>>914 GETでして送られてくるヘッダをみるんですよね?
2chのスレURLいれるとサイズ書いてないです
できる限りなんとか取得する方法無いですか?
920 :
デフォルトの名無しさん :2008/02/27(水) 15:08:28
921 :
デフォルトの名無しさん :2008/02/27(水) 15:12:53
動的に変化するから無理そうですね 通信切れで見られないHMLの取得を避けたいんですけどいい方法ありませんか
最後に </html> が無かったら途中で切れたと判断するとか
923 :
デフォルトの名無しさん :2008/02/27(水) 15:20:51
普通のテキストならどうしたらいいですか? もともと不完全なHTMLならどうしたらいいですか? サーバーのファイルと一致していてもエラーになります
924 :
915 :2008/02/27(水) 15:23:30
>>918 str は 0106719d0 になっているようです><
なんでうまくいかないんだろう。。
>>922 HTML4では </html> は省略可能なので万能じゃない
>>920 Connection: close
って書いてあるから接続断まで読めばそれで全部。
あと、なるべくHTTP/1.1使え
手元で確認した限り、HTTP/1.1でアクセスすると
chunked で送ってくるので末尾がちゃんと確認できる
926 :
920 :2008/02/27(水) 15:28:36
サンクス
>>924 sprinf で \n を付けているのに str1, str2 には付いていないぞ
HTMLパーサは↓程度はきちんと解析してくれないとねぇ‥‥
46 名前:デフォルトの名無しさん[sage] 投稿日:2008/01/27(日) 00:38:23
これだって正しいでっせ
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "
http://www.w3.org/TR/html4/strict.dtd ">
<title>テスト</>
<p><em/ほげほげ/
<p style=width:50px<strong>ふーばー</strong</p>
929 :
デフォルトの名無しさん :2008/02/27(水) 15:42:57
1.0から1.1にするとバットリクエストのエラーになります 書式が違うんでしょうか_ buf="GET " + path + " HTTP/1.1\r\n\r\n"; n=send(sock, buf.c_str(), buf.size(), 0);
1.1はHostヘッダの送信が必須
931 :
デフォルトの名無しさん :2008/02/27(水) 15:44:52
1.1だと、ユーザー情報も送信しないと無理になるんですか
932 :
デフォルトの名無しさん :2008/02/27(水) 15:54:08
なおらないです どうすればいいですか?
GET /test/read.cgi/livemarket2/1202634378/ HTTP/1.1
Accept: */*
Referer:
http://live27.2ch.net/ Accept-Language: ja
Host: live27.2ch.net
Connection: Keep-Alive
HTTP/1.1 400 Bad Request
ソース
buf="GET " + ko+ " HTTP/1.1\r\n\r\n";
cout<<buf; n=send(sock, buf.c_str(), buf.size(), 0);
buf="Accept: */*\r\n\r\n";
cout<<buf; n=send(sock, buf.c_str(), buf.size(), 0);
buf="Referer:
http:// "+sev+"/"+"\r\n\r\n";;
cout<<buf; n=send(sock, buf.c_str(), buf.size(), 0);
buf="Accept-Language: ja\r\n\r\n";
cout<<buf; n=send(sock, buf.c_str(), buf.size(), 0);
buf="Host: "+sev+"\r\n\r\n";
cout<<buf; n=send(sock, buf.c_str(), buf.size(), 0);
buf="Connection: Keep-Alive\r\n\r\n";
cout<<buf; n=send(sock, buf.c_str(), buf.size(), 0);
改行大杉
2回改行するのは最後だけ
935 :
915 :2008/02/27(水) 16:02:42
>>927 盲点でした。
やっと次の作業に進めそうです。本当にありがとうございます。
936 :
デフォルトの名無しさん :2008/02/27(水) 16:06:31
サンクス 改行削って上手くいきました あと受け取るバッファを多くすると返却値を間違えるようなんです どうやれば直りますか? n = recv(sock, &buf[0], 128000, 0); としてnまで表示するとデータ入ってないときがあります
めっちゃミジンコの質問させて下さい。 図書館で借りてきた本のページが抜けてて%cはどういう時に使うのか わかりません; %はぐぐれないみたいで困ってます。
939 :
937 :2008/02/27(水) 17:16:21
>>938 まだ始めたばかりなのでこのサイトはちょっと厳しいです・・・。
文字ということで本を読みすすめてみます。
有難うございました。
>>932 ,936
send も recv も、指定したサイズ未満しか送受信できないことがあるので、
その場合にも対応すること。
あと、エラー処理もちゃんと毎回やること。
941 :
デフォルトの名無しさん :2008/02/27(水) 20:53:29
HTTPで初めにサイズだけ取得したとして、読む位置をデータの始まりにシークできますか? 初期化からやり直した方がいいですか? データ位置を自前で判別して方がネットワークの負荷は少なくなりますが
942 :
デフォルトの名無しさん :2008/02/27(水) 20:55:33
自己解決しました いったん全部読み込んで、ヘッダとデータを分離してサイズが不一致なら再送にします
943 :
デフォルトの名無しさん :2008/02/27(水) 20:56:50
すいません。タイトルにふさわしく初歩的な質問ですが、 ポインタはメモリを格納しているアドレスの位置を指す と言いますが、ではそのポインタの情報はどこに格納 されるのでしょうか?
実行時なら、それを格納しているのがポインタ変数。 コンパイル時、&xという記述からどうやってxのアドレスを知るかと言うことなら、 それはコンパイラの仕事、コンパイラが決めること。
つまりint とか char とかと同じような感じでアドレスが入ってる変数があるってだけさ
ごめん語弊がありますねすいません (入ってるのアドレスだけじゃないですね)
普通はアドレスだけだと思うが。 メンバポインタとかは別だが。
948 :
デフォルトの名無しさん :2008/02/27(水) 21:12:50
string x, y="*****"; となっていたとして、 xとyのデータを一致するようにできますか コピーではなくて
949 :
デフォルトの名無しさん :2008/02/27(水) 21:14:24
int a,b=10; &a=&b;のような事はできないですよね?
string x = "*****", y = x; という話ではなくて?
string だと共用体が使えないから 参照にするしかないな。 string y = "*****", &x = y;
952 :
デフォルトの名無しさん :2008/02/27(水) 21:16:48
同一アドレスの同一データにしたいのですが 無理ですよね
x も xもポインタにして確保した同じとこさせばいいんじゃね?
>>949 アドレス演算子の結果は右辺値だと思った。
>>949 int *ap = &a;
int *bp = &b;
ap = bp;
957 :
デフォルトの名無しさん :2008/02/27(水) 21:36:28
すでに確保された変数のアドレスを書き換えるテクがあるかなと思った
アドレスはマシン語にそのまま組み込まれてるんだぜ?
変数は極端な話レジスタに載ってるかも知れないわけで。 string x,y="..."; #define x y
string y = "*****", &x = y; とした場合、最適化で x と y が同一視される可能性はあるんじゃないかな。
>>957 変数のアドレスは、変数が確保されたときに固定されるものだろ。
「すでに確保された変数のアドレスを書き換えるテク」を期待する目的がわからん。
論理アドレスくらいなら書き換えることは可能かもしれない。
class CSample2{}; class CSample { public: void get( CSample2 *obj_s2 ){obj_s2 = &m_obj_s2 private: CSample2 m_obj_s2; }; main{ CSample1 obj_s1; CSample2 *obj_s2 =NULL; obj_s1.get( obj_s2 ); } これでmain内のobj_s2がobj_s1.m_obj_s2と同じ物を指すようにしたかったのですが、NULLを指したままかわりません。 参照戻しではできたのですが、これで出来ない理由がわからず気持ち悪いです。 どなたか原因のご教授お願いします。
vectorに関数ポインタを格納するにはどうしたらいいでしょうか? vector<bool (*func)(int)> EroeroFunction; ↑<>の中のカッコが悪戯してうまくコンパイルが通らなくて困ってます。 構造体に関数ポインタを入れればなんとかなるんですが、メンバが1つしかないのでなんとも。
かなりのFAQ。引数経由でポインタを戻すなら、ポインタのポインタかポインタ参照か どっちかつかえ。 < void get( CSample2 *obj_s2 ){obj_s2 = &m_obj_s2 > void get( CSample2 *&obj_s2 ){obj_s2 = &m_obj_s2;} > void get( CSample2 **obj_s2 ){*obj_s2 = &m_obj_s2; }
>>963 get関数内でobj_s2を書き換えても、呼び出し側のobj_s2は書き換わらない。
関数に引数を渡す際の基本だろ?
ポインタを書き換えたいなら、ポインタをアドレス渡しでもすればいい。
void get( CSample2** ppobj_s2 ) { *ppobj_s2 = &m_obj_s2; }
obj_s1.get( &obj_s2 );
>>964 vector<bool (*)(int)> じゃないの?
968 :
デフォルトの名無しさん :2008/02/27(水) 22:33:46
vector<char>って後方に同じ型を連結できますか そういう関数ありますか
970 :
デフォルトの名無しさん :2008/02/27(水) 22:35:22
push_backでは一つしか増やせません 一度に増やすやつないですか
>>968 std::copyとstd::back_inserterを組み合わせるんじゃねーの?
>>968 こういうこと?
vector<char> v1, v2;
v1.insert(v1.end(), v2.begin(), v2.end()); // v1の末尾にv2の全要素を追加
973 :
デフォルトの名無しさん :2008/02/27(水) 22:37:22
vector<int> x,y; x={1,2,3} y={4,5,6} x.push_back(y)={1,2,3,4,5,6} こういうやつです
974 :
デフォルトの名無しさん :2008/02/27(水) 22:39:20
それでできますかサンクス
まんまinsertでいいんじゃね?
insertやね operator+=を外部に定義しておくと便利かも
要素の連結か、要素ごとの+=か曖昧なので、そんなのいらんかも
C言語なんですが 配列でポインタ表現を使ってアクセスしてインクリメントようと思って *(array+i)++としたら'++'には左辺値が必要です、とエラーが出てきました これは配列で宣言したからだと思うんですが ポインタで宣言した場合は値が飛び飛びになるので、*(array+i)みたいな表現できないでしょうし どうすればいいでしょう?
(*(array+i))++; ++*(array+i); 変なことになったらとりあえず優先順位を疑うのは基本。
*((array++)+i) // arrayを増やす場合 *(array+i++) // iを増やす場合
*(array+i) と array[i] は優先順位以外は等価。
>>979 できました。ありがとうございます。
優先順位って今まで全然気にしてませんでしたので
今後注意して行こうと思いますorz
>>979 と
>>980 のどちらを意図してるんだろうか。
それはともかく、array[i]++; と書けばいいのに
何でそうしないのか本気で理解できない。
984 :
デフォルトの名無しさん :2008/02/27(水) 23:27:31
i++[array]と書くのが漢
漢すぎるwwwwww
(*(array + i))++; ←等価→ array[i]++; ←等価→ i[array]++; array++[i]; ←等価→ *((array++)+i) ←等価→ i[array++]; i++[array]; ←等価→ array[i++]; ←等価→ *(array+i++);
はじめて見た。 誰だよこんな書き方見つけた奴……
*(E1+E2) と E1[E2] の挙動は等価だと規格に書いとるべ。 *(array+i) と *(i+array) が等価なのと同じく array[i] と i[array] も等価だべ。
array[i]を*(array+i)の糖衣構文とすることを発案した人が真っ先に見つけただろうな。 で、誰?
(i % 16)["0123456789ABCDEF"]
991 :
デフォルトの名無しさん :2008/02/27(水) 23:45:54
string x,y; N=0; x.resize(0); に対して x+=y; と memcpy(&x[N],&y[0], y.size()); N+=y.size; は同じのはず yがバイナリデータだと上が失敗することが多いです
994 :
デフォルトの名無しさん :2008/02/27(水) 23:50:05
メモリ確保はあらかじめしておいてください あと最後にNでresizeも
>>991 stringに文字列以外入れるなよ。
あと、x.capacity() >= y.size() でないとmemcpyがメモリ壊すぞ。
>>994 同じというなら、同じになるコードを書けよ。
変な入門書で配列のとこにすぐにその記法が説明してあったからできるのは知ってたけど、 できる理由は全然考えたことがなくて、今はじめて理解したw
998 :
デフォルトの名無しさん :2008/02/27(水) 23:53:19
zipファイルを少しずつyに入れてからxに足し込むんですけど memcpyの方は書き出して復元できますが、+=はまれに正常でほとんど壊れます 原因はなんでしょう
>>998 vectorを使わずstringを使ったから。
なんで文字列じゃないものをstringに入れるんだ。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。