【初心者歓迎】C/C++室 Ver.33【環境依存OK】
1 :
デフォルトの名無しさん :
2006/11/24(金) 22:51:27
3 :
デフォルトの名無しさん :2006/11/24(金) 23:48:46
早速質問させてください。環境は VC++2005 を使用しています。 汎用クラスから派生したクラスで継承元のクラス関数の呼び出しについて教えて ください。 下の child::Add() のコメントにあるように VC++2005 だと例1の記述でも問題無く 動作します。動作はするのですが出来れば C++的に正しい(移植性が高い)書き方を 知りたいのですが、どういう書き方が正しいのでしょうか? template <class T> class base{ T i,j; public: base(void){ i = 1; j = 2; }; ~base(void){ i = j = 0; }; virtual T Add(void){ return i+j; }; }; // class base class child : public base<int>{ int k; public: child(void){ k = 3; }; ~child(void){ k = 0; }; int Add(void){ return k + base::Add(); // 例1:gcc4.1ではErrorだがVC++2005だとOK //return k + base<int>::Add(); // 例2:両方ともOK }; }; // class child
>>3 両方通る奴で何が不満だ?
gcc のエラーメッセージはなんて言ってる?
5 :
デフォルトの名無しさん :2006/11/25(土) 00:03:47
>>4 "error: 'template<class T> class base' used without template parameters"
と言っています。確かに明示的に型指定したほうが安全でしょうし、両方通る方が
一般的と解釈していいんでしょうね。
>>3 規格書のどっかにあると思うが、VC2005で通る方のは文法違反だと思う
7 :
デフォルトの名無しさん :2006/11/25(土) 01:11:28
3次元配列の確保で質問です。 P =(double ***)calloc(ALL,sizeof(double **)); if(P ==NULL) exit(1); for(i=0 ; i < ALL ; i++){ P[i] = (double **)calloc(NN,sizeof(double *)); if (P[i]==NULL) exit(1); for (j=0 ; j < NN; j++){ P[i][j] = (double *)calloc(NN,sizeof(double)); if (P[i][j]==NULL) exit(1); } } ALL=8760,NN=99とします。この配列確保をP,P1,P2・・・と7回繰り返そうと思うのですが、4回目になると勝手に計算が終わってしまいます。 多分、ALL=8760が大きいためと思うのですが・・・。うまく配列を確保する方法ってありますか?よろしくお願いします。 環境はWinXP,VS2005でCです。
>>7 それを7回繰り返して、7つとも同時に使うの?
9 :
デフォルトの名無しさん :2006/11/25(土) 01:35:15
はい、ファイル出力する際同時に使います。
WinXP 64bit版でも使うしかないな。 32bit版は通常で2G、2003Serverでも3Gしか取れない
11 :
デフォルトの名無しさん :2006/11/25(土) 01:45:18
そうですか・・・。何かプログラム上で上手く回避できませんかね?
アホどもはどうしてなんでもかんでもメモリに展開したがるんだぜ?
14 :
デフォルトの名無しさん :2006/11/25(土) 01:55:18
>>12 わざわざ有り難う御座います!
質問でのP[ALL][NN][NN]はどれに対応しているのでしょうか?
マッピング機能がちょっと分からないので見当外れな質問でスイマセン。
>>14 >>12 を書いたのは俺じゃないんだが、P[][]とQ[][]が該当すると思う
でもよく考えてみたら、MapViewOfFile()はアドレス空間にファイルを マップするだけなので、どちらにしろ32bitじゃ足りなくないか? 結局はLPVOIDのサイズ幅に制限されるはず
最近勉強し始めたC++でswitch文を使ってプログラムを書いているのですが case 1: cout << "文字1"; cin >> a if (a <= 15) cout << "文字2\n"; else if (a >= 16) cout << "文字3\n"; else cout << "文字4\n"; break; この記述の仕方ではコンパイルできません。。。orz 1と入力されたら文字1を出力して更に入力させて15以下なら文字2を、 16以上なら文字3をそれ以外なら文字4を表示させたいのですが どうすれば記述できますでしょうか・・・ ちなみに他の文は問題ないようでした。 上記の部分を/*〜*/で囲ったら無事コンパイルできましたので。。。 どなたかご教授お願いします。
実際に
>>12 のソースを書き換えて実行してみたら、マップできる
個数は32bit WindowsXPで2個だけだな。3個マップしようとすると
エラーで止まる
>>18 aの型は何よ
症状が再現する最小のソースをうpしろ
21 :
デフォルトの名無しさん :2006/11/25(土) 02:22:43
>>20 int型です。
ソースうpします
#include <iostream.h>
int main()
{
int b, a;
cout << "文字0\n";
cin >> b;
switch(b){
case 1:
cout << "文字1";
cin >> a
if (a <= 15)
cout << "文字2\n";
else if (a >= 16)
cout << "文字3\n";
else
cout << "文字4\n";
break;
改行が多すぎると言われたのでひっつけました。。。
みにくくてすいませんorz
default:
cout << "文字5\n";
}
}
>cin >> a にセミコロンがないとか言う落ちか?
>>21 cin >> aの後にセミコロンが抜けてる
24 :
デフォルトの名無しさん :2006/11/25(土) 02:26:25
>>22-23 セミコロンつけたら無事コンパイルできましたorz
板汚しすいませんでした。
syntax errorを他人にデバッグさせるなと俺は言いたい
26 :
デフォルトの名無しさん :2006/11/25(土) 02:30:25
>>12 う〜ん、上手くいかないです・・・。
もうちょっと試してみますが成功する気配がしない・・・
>>26 配列風に扱うのは諦めて、fseek()、fread()、fwrite()で
原始的に書けよ。
>>26 全部一辺にマップしようとしてるのならお門違い。
元々全部はメモリにのらないので、その時々にアクセスする必要のある
最低限の所に限定してメモリを割り当てようというのが >12 だから。
家で実験したら最高2個しかマップできないので、うまく2個だけの マップで済むようにプログラムを書くしかないな。
2003Serverなら4個いけそう
31 :
デフォルトの名無しさん :2006/11/25(土) 02:48:16
色々やってたらパソコンの調子が悪くなってしまいました。
スワップファイルを置いてあるHDDの容量がぎりぎりなんじゃないか?
33 :
デフォルトの名無しさん :2006/11/25(土) 02:55:52
結局8760*99*99を大量にって無理ですね。 配列以外に良い方法ってありませんか?
どのように使うかを言わず良い方法といわれてもな プログラマーよりまずエスパー探してきたほうがいいんじゃないか?
>>33 どう考えてもファイル操作にするか64bitOSへの乗り換えるのがまともな方法。
>>33 本当にいっぺんに必要なのか?
そう思い込んでるだけでは?
何をやりたいのか具体的に書いてくれると、回答者としても代替案を出しやすいと思う
37 :
デフォルトの名無しさん :2006/11/25(土) 08:24:28
C machineで float x,y; scanf("%f",&x); scanf("%f",&y); としたときにxに2桁以上の数をいれると yに何もいれずにプログラムが進むという現象が起きたんですが どうしたらいいでしょう? 学校では、普通なんですが、家でやるとこうなります。
scanf()をつかうのをやめる。
つーか、C machineなんか使うからだな。
>>33 内部でディスク上に展開する配列もどきクラスでも書けば?
コードの見た目は配列みたいに扱えるが。
LargeArray.get(30,5,49);
な感じで。
41 :
デフォルトの名無しさん :2006/11/26(日) 00:31:41
アルゴリズムの質問なんですが、vectorで要素数で指定されてきた要素を 消したいんですが、いいやり方が思いつきません。 教えてもらえませんか?
42 :
デフォルトの名無しさん :2006/11/26(日) 00:42:04
ちょっと解りにくいと思ったので追加します。。。 いくつかの要素からなるベクター配列があって、 そのX番目の要素を消したいときって、どうやるんでしょうか。 Eraseだとイテレータが必要で、でもイテレータは最初か最後、他ちょっと くらいしか取り出せませんよね?? いま僕はX回インクリメントしてイテレータをその要素にさすようにしてますが、 もっといい方法はないでしょうか??
途中にある要素を削除しなきゃならんときにvectorを使うのが間違い
advance
>>42 vectorはRandom Access Iteratorだから、v.begin() + n で n + 1個目の
要素を指せる
46 :
デフォルトの名無しさん :2006/11/26(日) 01:21:23
>>45 おお。ほんとですか!ありがとうございます。
>>44 そういう関数があるんですか?あとで確認します。
>>43 ちょっと配列の勉強しなおそうかな・・・。
消したり出したりしたいんなら普通はリストにするんじゃないの
>>47 実行速度を最適にすることが普通とは限らない。
>>48 いや「普通」は実行速度を最適にする方だと思うよ
頻繁に途中の要素を消したり出したりするのにvectorを使うのは普通じゃない
>>49 それはオマエの「普通」。
まともな思慮のある技術者なら自分の主張の根拠に
「普通」などという主観的な根拠は使わない。
今回の場合、
「消したり出したりするなら list にしたほうが速い」
とは言える。でもそれでコンテナを切り替えるかどうかは
本人の選択。
____ / \ /\ キリッ . / (ー) (ー)\ / ⌒(__人__)⌒ \ それはオマエの「普通」。 | |r┬-| | \ `ー'´ / ノ \ /´ ヽ | l \ ヽ -一''''''"~~``'ー--、 -一'''''''ー-、. ヽ ____(⌒)(⌒)⌒) ) (⌒_(⌒)⌒)⌒)) ____ /_ノ ヽ、_\ ミ ミ ミ o゚((●)) ((●))゚o ミ ミ ミ /⌒)⌒)⌒. ::::::⌒(__人__)⌒:::\ /⌒)⌒)⌒) | / / / |r┬-| | (⌒)/ / / // だっておwww | :::::::::::(⌒) | | | / ゝ :::::::::::/ | ノ | | | \ / ) / ヽ / `ー'´ ヽ / / | | l||l 从人 l||l l||l 从人 l||l ヽ -一''''''"~~``'ー--、 -一'''''''ー-、 ヽ ____(⌒)(⌒)⌒) ) (⌒_(⌒)⌒)⌒))
>>50 >まともな思慮のある技術者なら自分の主張の根拠に
>「普通」などという主観的な根拠は使わない。
47の「普通」って頻度で言ってんじゃないの? 十分客観的だよ
選択は変えないでいいよ
>>52 「47の」って言った時点で主観確定だろ。アホか。
>>50 >「消したり出したりするなら list にしたほうが速い」
を認めておきながら47を48で返したり
49に50と返したり
「言葉の使い方が厳格な俺」っていう設定で遊んでるんだろう。 現実の姿は単なる屁理屈中学生だけど。
どこから「頻繁に要素を削除する場合」話が出てきたの?
普通は頻繁に要素を削除するんじゃないの
つまり普通はvector使っちゃ駄目ってことだな
普通はvector使うんじゃないの
配列をポインタ形式で使う。 心がければ高速になるし(ちりもつもれば何とやら、ね)これ最強
STLってスレッドフリーですか?
スレッドフリーってなぁに?
>>63 知らないんですか・・・ハア(呆)。もうちょっとレベルの高いところで聞き直す事にします。ありがとうございました。
>>64 スレッドフリーと言う言葉は存在しない。
スレッドセーフを書き間違えたのを遊ばれてるだけだろ。
free((void*)Thread);
質問です #define FILENAME "f.dat" typedef struct { int data[10]; int data2[10]; } HEAD; int main(void) { FILE* fp; HEAD head; if( (fp = fopen( FILENAME ,"r") ) == NULL ) { cout << "cannnot open." << endl; } fread(&head , sizeof(head) , 1 , fp); fclose(fp); } というコードをC++に書き直すと、どのようになるでしょうか。 ifstream file(FILENAME); file.read(処理略); 使ってもうまくコンパイルが通りません
ふつうに動くと思うが #include<fstream> #include<iostream> using namespace std; #define FILENAME "f.dat" struct HEAD { int data[10]; int data2[10]; }; int main(void) { std::ifstream file(FILENAME); HEAD head; if(!file){ cout << "cannnot open." << endl; } file.read(reinterpret_cast<char*>(&head),sizeof(head)); }
>>68 うまく動きました
けど、そのコードを初めコンパイルしたとき
コンパイルしています...
scan.cpp
scan.cpp(48) : warning C4551: 関数呼び出しに引数リストがありません。
scan.cpp(51) : error C2228: '.read' : 左側がクラス、構造体、共用体ではありません。
型は 'overloaded-function' です。
ビルド時間 0:01
となり、一回VC終了して起動し、コンパイルしたら何事も無かったかのように動きました。
なんでだろ・・・
俺には
>>68 のコードで51行以上になる理由が分らない。
どうせ晒さなかったコードに問題があるだけなんだろ。
2分も遅れてケコーンしちまったか
>>70-71 すみません。struct HEADの中身は、ほんとはもっと長いコードだったもので、、、
そこは置き換えてます。
74 :
68 :2006/11/26(日) 17:52:32
たびたびすみません。 こんどは f.dat のデータを読み出したいのですが、うまく読んでくれません。 f.dat の容量は50Mあります。 途中までは読んでくれるのですが、途中から値が全て0になってしまいます。 この場合どのようにしたらよいのでしょうか?
75 :
67 :2006/11/26(日) 17:56:04
>>74 ここにいるのはエスパーじゃない。問題の発生するソースを貼れ。
どうせ途中で fstream がエラー起こしてるんだろうけど。
77 :
67 :2006/11/26(日) 17:56:36
わかりました ちょっとまってください
78 :
67 :2006/11/26(日) 18:06:13
#include <string> #include <fstream> #include <windows.h> using namespace std; #define FILENAME "01.dat" typedef struct { struct SCAN_TIME { WORD Year; WORD Month; WORD Day; WORD Hour; WORD Minute; WORD Sec; }Time; BYTE Sp[1024-sizeof(struct SCAN_TIME)-sizeof(struct SCAN_ETC)]; } HEAD;
79 :
67 :2006/11/26(日) 18:07:17
void Print_Bit(short int data) { int j; int hoge; int piyo; char str_bit[17]; for(hoge=0,j=15;hoge<16;hoge++,data>>=1) { if(data & 0x01) str_bit[j--] = '1'; else str_bit[j--] = '0'; } for(piyo=0;piyo<=16;piyo++) { putchar(str_bit[piyo]); } return; }
80 :
67 :2006/11/26(日) 18:08:18
void Read_File(const char* filename , HEAD& head, short int* data) { ifstream file(filename); if( !file ) { cout << "cannot open." << endl; } file.read(reinterpret_cast<char*>(&head),sizeof(head)); for(int i=0 ; i <= 500000/* !file.eof()*/ ; ++i ) { file.read(reinterpret_cast<char*>(&data[i]) , sizeof( short int ) ); Print_Bit(data[i]); cout << endl; } cout << endl; cout << "SUCCESS" << endl; file.close(); } int main(void) { HEAD head; short int data[500000]; Read_File( FILENAME , head , data); return 0; }
81 :
67 :2006/11/26(日) 18:10:59
こんな感じです
>>78 コードの BYTE Spは気にしないで下さい
ちなみに50Mのデータにはちゃんとしたデータが入っていることが保障されています
バイナリモードで開いていないに1票
>>81 もしかして、ファイルサイズが 50M バイトなの?
sizeof(HEAD) + (50M * sizeof(short)) ないとおかしいんだけど、大丈夫?
3表
86 :
67 :2006/11/26(日) 18:39:53
>>83 ファイルサイズは50Mくらいで きっちり50Mではありません。
>>82 >>84 そのとおりでした。バイナリで開いたらちゃんとした値が出てきました。
すみません、最後に一つ質問です。
char buf2[4500000];
が動かないのですが、これだけ大きな配列は作れませんか?
50Mのデータが配列に入りきらなくて・・・
>>86 スタックサイズが足りないからその問題は発生している。
解決策は2種類あって、
配列をスタックに取らない or スタックを大きくする
前者の方法での解決方法としては
std::vector<char>buf2(4500000);
とか
static char buf2[4500000];
とかこんな感じ。
後者の方法を取るならやりかたはコンパイラ毎に異なるので適宜調べて
>>87-88 vector使ってやってみます。
どうもありがとうございました。
char* buf = new char[4500000] char* buf = (char*)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, sizeof(char) * 4500000);
>>90 vector が出てるのに、なんでそんなの勧めるの?
ただ別の手段を示してるだけのヤツになぜそんなにつっかかるの?
何か嫌な思い出でもあるんだろ、そっとしといてやれ
deleteし忘れたことがあるからトラウマになっちゃったんだな
そこでスマートポインタ使えばもうそんな心配は無用となるわけでBoostの出番です。 boost::scoped_array<char> buf(new char[450000]); #define BOOST_BIND_ENABLE_STDCALL #include <boost/bind.hpp> boost::shared_array<char> buf( static_cast<char*>(HeapAlloc(GetProcessHeap(), 0, 4500000)), boost::bind(HeapFree, GetProcessHeap(), 0 , _1)); 率直にstd::vector使えばこんなことをする必要も無いのだがな。
ベタな new / delete が使えないうちに、その辺をすすめるのもどうかと。
すごく初歩的な質問ですが 変数の再定義って可能なんでしょうか? int nNum; //なんか処理 char nNum;
>>97 スコープが変わらない限り無理。
逆に言えば、これはOK。
double foo = 1.5;
int main()
{
int foo = 5;
printf("%d\n", foo);
{
char foo = 'a';
printf("%c\n", foo);
}
return 0;
}
まぁなんつーか質問する前に、 int main() { int nNum = 0; nNum += 5; char nNum; return 0; } とか超簡単なもん書いて自分でコンパイルしてみりゃ解ろうものを
ダメな奴の3ない ・調べない ・試さない ・考えない
俺なんてテストプログラムが大量にあるがなぁ
俺なんてテストプログラム書いただけで終わった気になるがなぁ
やってみて出来なかったで、方法があるのか聞いただけのようなきがす。
C++が出来上がったのに、Cはなぜ未だ存在するのですか? Cで作らなきゃいけないメリットでもあるんですか?
あります
C++を実装できないプアな環境もあるんです。
既にC99で別の道を歩み始めています。
Embdded C++とは別に、現在Embedded Cまで作られているそうで。
C++は作者があんなくだらん言語作っちゃってごめんと公式で謝罪してるからなあw
113 :
デフォルトの名無しさん :2006/11/28(火) 14:50:59
質問させてださい。 文字列定数のポインタとmallocでヒープに確保した文字列ポインタが 混在した配列を解放したいのですが、配列に格納されているポインタが ヒープポインタかどうかを判断する方法はないでしょうか? できれば標準のCランタイムでできる方法がよいのですが、無ければ 別の方法でも構いません。よろしくお願いします。 環境は、VisualStudio2005(C++)を使っています。
>>113 まぁ、環境依存しない方法では手っ取り早い方法はないな。
やるとすれば、どれかの文字列定数のポインタとの差が大きいか小さいかだけど確実性はないし。
地道にmalloc()するごとにそのアドレス範囲を保存しておいてそれと比較するとかじゃないかね。
115 :
デフォルトの名無しさん :2006/11/28(火) 17:12:55
質問です。 int型やString型やその他自作オブジェクトを、 使われなくなった時点でそれらのデストラクタなりdeleteなりを よんで片付けてくれるようなクラスを創りたいんです。 参照カウント方式で削除のタイミングをはかるようなやつです。 どんな風に実装したらいいでしょう。 どんな型の変数でも代入できるような変数を クラス内に持って、そこにintやらstringやらなんやらを入れて、 参照カウントをチェックして、使われなくなったら削除処理を呼び出すような 入れ物みたいなクラスをイメージしてるんですけれど、 どんな型の変数でも代入できるような変数って、そんなのできますか
Boostを使ってよければ、参照カウントのスマートポインタは既にある。 boost::shared_ptr<T>とboost::shared_array<T>。 それぞれT型(及びT型へ変換できる型)でnewしたもの、T型でnew []したもの用。 特にboost::shared_ptr<void>には、newしたものなら何でも入る。 それどころか削除子(削除処理する関数オブジェクト)さえ指定すれば実質的に何でも入れられる。
117 :
デフォルトの名無しさん :2006/11/28(火) 18:46:30
>>116 Boostをいれられない環境で動かしたいんだけど、
同じようなものを造るのはむずかしいでしょうか
Boost入れられる環境で作って入れられない環境で動かせば問題ない
119 :
デフォルトの名無しさん :2006/11/28(火) 19:16:49
大学生です これからC言語を勉強していきたいんですが コンパイラ等のソフトをダウンロードできるサイトを教えて頂けませんか?
ググれ
121 :
デフォルトの名無しさん :2006/11/28(火) 20:19:34
C言語で配列をグローバル変数に使うのですが その配列の要素数を、関数内で開いたファイルの値を元に指定したいんです。 グローバル変数は最初に指定する為、後から開くファイルの中身を どのように反映させたら良いか困っています。 こうしたら良いと言うのがあればお願いします。
一例 int *pBuf (中略) { unsigned int uCount; (ファイルから値取得) pBuf = (int*)malloc(sizeof(int) * uCount); }
やっべ、 int main() が抜けてたわい
124 :
デフォルトの名無しさん :2006/11/28(火) 20:44:16
すみません、数学的な質問なのですが、 数値の2乗を返す数式で、その答えに元の数値の符号がつくような数式を 場合分けなしで出来ましたでしょうか? すなわち 10を渡したときには100を、-10を渡したときには-100が返るような数式です。
125 :
デフォルトの名無しさん :2006/11/28(火) 20:47:59
>>122 レスありがとうございます。
mallocを使う方法でやってみます。
グローバル関数をmallocを使って動的にメモリ領域を確保すれば良いのですね。
ただ今回使う物は
float vertex[xxxx][3] ;//xxxxの部分が可変なのですが
vertex = (int*)malloc(sizeof(int) * uCount)
みたいな感じでしょうか?
それともpBufをポインタにしたのには何か意味があるんでしょうか?
そんなレベルでグローバルに可変配列なんて5年早いんじゃね?
ポインタにしたのには何の意味がって、mallocがどういうものなのか解ってるか?
>>127 今調べてて多少は理解しました。
上の運用は根本的におかしいですね。
構造体でも使って代用します。
130 :
122 :2006/11/28(火) 20:58:39
float型の多元配列か vertex[x][y]のyが固定なのなら float *vertex; int main() { unsigned int uCount; (取得) vertex = (float*)malloc(sizeof(float) * y * uCount); //yは固定 } でやればいい 配列への実際のアクセスは普通にvertex[x][y]でいける あと、要らなくなったらちゃんとfree(vertex)するように
>>130 ありがとうございます。
見つけたサイトの説明の関係で、yが固定なのでxとyの場所を入れ換えようか
などいろいろ考えていたのでとても助かりました。
mallocをもう少し理解してこの実装の方法で詰めていきたいと思います。
132 :
デフォルトの名無しさん :2006/11/28(火) 21:07:59
133 :
デフォルトの名無しさん :2006/11/28(火) 21:17:12
フリーのCコンパイラをWinXPに入れようかと思っているのですが、 日本語のソフトで何かいいものはありませんでしょうか?
ググって出てくるやつを全部入れろ
135 :
デフォルトの名無しさん :2006/11/28(火) 22:42:32
1を入力すれば"1を選択"、2を入力すれば"2を選択"と表示するようにしたいのですが どの数字を入れても"1、2、3のどれか選択してください"と表示されてしまい困ってます。 どの辺を修正するなりすればいいのでしょうか? #include <stdio.h> int main() { char aa[256]; char bb = aa; printf("1をえらぶ\n2をえらぶ\n3をえらぶ\n"); scanf("%s", aa); switch(bb){ case 1: printf("1を選択\n"); break; case 2: printf("2を選択\n"); break; case 3: printf("3を選択\n"); break; default: printf("1、2、3のどれか選択してください\n"); break; } return 0; }
136 :
デフォルトの名無しさん :2006/11/28(火) 22:44:38
問題点が山積みだな。 int = aa; printf("1をえらぶ\n2をえらぶ\n3をえらぶ\n"); scanf("%d", &aa); switch(aa)
137 :
135 :2006/11/28(火) 22:59:24
>>136 うまく表示されました、ありがとうございます。
138 :
デフォルトの名無しさん :2006/11/29(水) 00:06:58
boostのスマートポインタって、 スコープを抜けたかどうかをみて参照カウントをデクリメントしてるんですよね?? でも、スコープを抜けてるかどうかを、どうやって監視してるんでしょうか。 一行読むごとに、スコープが閉じられたかどうかを常時監視してるわけでもないんでしょ? よくわからない・・・どういう仕組みなのか教えてください
ヒント: デストラクタ
140 :
デフォルトの名無しさん :2006/11/29(水) 16:51:49
大学生です。 家庭のノートPCでC言語を勉強したくて 坂下夕里 著 の「10日で覚えるC言語入門教室」 という参考書を買って、本に従って「Borland C++ Compiler 5.5」を ダウンロードしてインストールしました。 bccフォルダの中にあるreadme.txtファイルに従って まず、マイコンピュータのプロパティの環境変数のシステム環境変数 に;c:\Borland\Bcc55\binというPATHを加えて 次に、メモ帳を使って -I"c:\Borland\Bcc55\include" -L"c:\Borland\Bcc55\lib" という内容のファイルをbinの中にbcc32.cfgという名前で すべてのファイルを選択して保存 次に、またメモ帳を使って -L"c:\Borland\Bcc55\lib" という内容のファイルをbinの中にilink32.cfgという名前で すべてのファイルを選択して保存 最後にコマンドプロンプトを使ってbcc32と入力しましたが 参考書のようにヘルプと呼ばれる説明は出てこないで 「エラー E2266: ファイル名が指定されていない」 と出てくるのです。 自分ではどこが間違っているのか分かりません。 自分のPCはwindows XPです。 もし分かる方がいたら解決方法を教えていただけないでしょうか
142 :
デフォルトの名無しさん :2006/11/29(水) 17:01:10
140です。 どこで聞けばいいのでしょうか?
暗号: 51-16-98-29-40-114-85-43-29-103-98-118-55 解けますかな?
>>140 気にせず先へ進め。
そんなエラーメッセージが出てくるということは、正しく導入できたと思ってよい。
(コマンドが見つからないというようなエラーメッセージだったら良くなかった)
>>140 > Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
> Try `bcc32 -h' for more information, or `bcc32 -h <OPT>' for specific help.
> エラー E2266: ファイル名が指定されていない
メッセージの2行目に書いてあるように bcc32-h と入れればいい。
でも5.5.1は引数無しだとコマンドラインオプション出たような‥‥/ ,' 3 `ヽーっ
ひそかにBCB2006の5.8にでもバージョンアップされたのかな‥‥
C++で整数、文字列両方に対応している変数ってありますか?
こんなところか。 積極的に勧めたくない選択肢は括弧で囲んだ。 //標準規格内 (union {int x; char *p;}) (std::stringstream) (void*) // boost boost::variant<int, std::string> boost::any (boost::shared_ptr<void>) // OLE VARIANT // (.NET) System::Object
そもそも文字列というデータ型が無いわけだが charもwchar_tも内部的にはただの数値で、整数として扱うこともできるがな だから、x == 'A'とかできるわけだが
>>146 Discriminated Unions by Andrei Alexandrescu
150 :
「 p2165-ipbf205kyoto.kyoto.ocn.ne.jprlo」 :2006/11/29(水) 22:36:55
「SummerKitchen2004」「otzoi」
151 :
p2165-ipbf205kyoto.kyoto.ocn.ne.jprlo :2006/11/29(水) 22:37:43
SummerKitchen2004otzoi
152 :
p2165-ipbf205kyoto.kyoto.ocn.ne.jprlo :2006/11/29(水) 22:38:57
SummerKitchen2006otzoi
153 :
デフォルトの名無しさん :2006/11/30(木) 03:43:57
うむ。
お前の肉棒をおごらせてくれ
記述に関して質問です。 VS2005を使用してます。 構造体などでポインタを使う時 (*p_hoge).xxx = 1; を p_hoge->xxx = 1; とも書きますが、オブジェクトのポインタと関数のポインタがある場合 int型の引数と戻り値がある関数実行 int ans = (*p_obj.*p_func)(1); を同じように->で記述できますか?
>>156 (p_obj->*p_func)(1)
158 :
156 :2006/11/30(木) 13:54:47
>>157 ありがとうございます。
無事動作しました。
(*p_Hoge).xxxをp_Hoge->xxxとも書きますがって言うが (*p_Hoge).xxxなんて常用するやつぁそうは居らん
オーバーロードしている場合はまあそういうこともあるだろう。
だったら->も多重定義しておけと。
162 :
デフォルトの名無しさん :2006/11/30(木) 20:52:48
C言語でなのですが、時間差で文字が表示されていくように下の方法で作ったのですが これ以外にも方法がありましたらお願いします。 #include<stdio.h> int main() { int i; for(i=0; i<600000001; i++){ switch(i){ case 1: printf("3・・・"); break; case 200000000: printf("2・・"); break; case 400000000: printf("1・"); break; case 600000000: printf("0!\n"); break; default: break; } } return 0; }
すごく、非現実的です
165 :
162 :2006/11/30(木) 21:53:04
すみません、APIはまだ勉強していないので 使用しない方法では無いでしょうか?
>>165 何がやりたいんだ?
最初のforの中にprintf書けば?
windowsなら printf("3・・・"); Sleep(1000); printf("2・・"); Sleep(1000); printf("1・"); Sleep(1000); printf("0!\n");
API使いたくないならforでひたすら時間取得しまるとか・・・ 詳しく調べたことないからよくわからんがsignal関数とかでタイマーとか使えなかったっけ?
>>165 time.h の time() と difftime() を使えばなんとかなるんじゃない?
ぐるぐるまわすことになるから CPU に優しくないけど。
170 :
デフォルトの名無しさん :2006/11/30(木) 22:35:39
すみません、プログラミング超初心者なのですが、 メモ帳に作成したソースコードを コンパイルするにはどうしたら良いでしょうか? ちなみに言語は、Cです。
>>170 ソースコードを保存して
コンパイラを手に入れて
マニュアル等に従ってコンパイル
>>170 コンパイラによりますが、一般的にはファイルに保存して、
ファイル名をコンパイラに伝えればよいはずです。
173 :
162 :2006/11/30(木) 22:52:42
>>173 >>167-169 表示したい文字列は配列にでも入れて
for(i=0; i<270000001; i++){
if(i%30000000 == 0)
printf(str[i/30000000]);
}
176 :
デフォルトの名無しさん :2006/11/30(木) 23:51:44
ダメすぎるな
>>173 だからSleep(Unixならsleep)使えと。
マルチタスクOSでfor使ったウェイトは御法度
クラスのメンバに定数を入れたいのですが(const int XX=100とか) コンパイルエラーになります、どうすればいいですか?
>>179 外部で定義する
class X {
const double d;
................
};
double X::d = 1.234;
あ、しまったこれはstaticの時だけね。 staticでない定数はコンストラクタの初期化リストに入れる
>>181 ありがとうございます。staticにして外部で定義してみます。
>>182 static const intだけは例外的にクラス内で定義できるはず
>>184 古いコンパイラとサブセットはだめぽかもわからんね
>>184 そういうときにはenumで代用すればよい。
enumで代用かな。 その辺自動でやってくれるのが BOOST_STATIC_CONSTANT
188 :
デフォルトの名無しさん :2006/12/01(金) 16:40:18
プログラミング初心者なのですが、 コマンドプロンプトの使い方でわからないことがあります。 コマンドで日本語のファイル名を入力したいときどうしたら良いでしょうか? 半角/全角キーを押しても日本語入力できない! 日本語に変換する方法があるのでしょうか? どなたか教えてください。
190 :
デフォルトの名無しさん :2006/12/01(金) 16:49:21
>>190 コマンドプロンプトの使い方と言語がCであることにどういう関連があるのだ?
>>188 Alt押しながら半角/全角キー押してるのか?
>コマンドプロンプトの使い方でわからないことがあります。 この段階で鼬害ということが判らないわけはないと考えられるので、 釣りか、さもなくば教えて君なのだろう。
Windows板行け屑
196 :
162 :2006/12/02(土) 00:18:49
おくれながら色々アドバイスありがとうございます。
くだらな〜いしつもんですが、 void hoge (void){ unko; return; } と言う関数の戻り値って何なのですか? void型ですか? そもそもvoidって何なんですか?
つ英和辞書
ということにしたいのですね
>>198 いや、もちろんvoidの日本語訳は分かりますよ。
ただ、EAXレジスタに何が代入されるのかぁと思って。
入っている値が永遠に使われないとしても レジスタに何が入っているかが重要だと思ってるわけ?
なに語気を荒げて 質問に質問を返してるんだろう。
おっと ここで会話が成り立たないアホが一人登場〜 質問に質問で返すとテスト0点になるの知ってたか? マヌケ
質問に質問で返されたら、最初の質問者が困るだけでしょ。 テストって何だろう? 「設問」と「質問」は全く別のものなのだけど。 これだから週末は面白いね。
0じゃなくて0なのが なぜか全てを物語ってる気がするね。
0だっていいじゃない 無能なんだから みつを
>>200 んなもん、自分でコンパイラが生成したasmソース見ろよ。
gccなら-S
VC++のclなら/FA
大抵のコンパイラにはそれに類するオプションがあるはずだ。
あんまり「アセンブラならどう」という理解の仕方に偏るのは
感心せんがな。
ま、結論から言うと、何も代入しない。
voidという英語の日本語訳はわかってても、「戻り値void」の意味が解って無いんだから仕方ないわな いくらネットで色んな情報が入手できると言っても プログラムやるなら本の1冊2冊くらい買って勉強しれ
現在ほどほど学んだのがC言語のみなのですが、 画面の判定を行いたいと考えております。 任意の座標(ドット?)がどうなっているか、色という情報になるのでしょうか? どういった手順で進めていけば、その情報を得られるでしょうか?
210 :
209 :2006/12/02(土) 10:35:30
質問が下手だったと思いますので訂正させていただきます; 画面上の色を取得するにはどういった手順を踏めば得られるのですか? よろしくお願いしますorz
ひょっとしてスレ違いだったって奴ですか・・・orz お邪魔しました、すんませんすんません
> 質問者は必ず、環境を書きましょう。
そして、十中八九WinAPIスレ行きになりそうな予感
WinAMPスレに見えた。
216 :
197 :2006/12/02(土) 14:17:53
すいません。 回答有り難うございます。 copyの戻り型はvoidになっている。 これは返される値がないことを明示するためである。 つまりvoid型というものが存在するのでしょうか?
存在しなきゃコンパイルエラーになってるだろうね
テキストエディタで入力できるような普通の日本語全角文字ってのは 必ずchar2つ分で表現されるんでしょうか? あと、それ以外でもchar3つ分の文字(国内外問わず)ありうるんでしょうか?
日本語ならとりあえず、「shift_jisで」って前提を置いたほうがいいのかな あいまいですみません('A`)
utf8とかは3Byte以上になったはず
中東の言語が確か3バイト 現状、一般的な日本語OSなら2バイトと思って差し支えない
ありがとうございます wcharとかcharとかutfとかeucとかいまひとつわかんないよママン…
EUC-JPなら補助漢字は3バイトになる。
SJIS、EUC-JP、JIS → 1〜2バイト UTF-16、WinのWCHAR → 2バイト UTF-8 → 1〜4バイト(日本語は3バイト) EUC-JP(拡張版) → 1〜3バイト UTF-32、Linuxのw_char → 4バイト
可変長文字コードはもういやだー
>>225 生半可な知識で適当なこと書くなよな
UTF-8は6byteまでだし。
>>227 UCS2でいいんなら、それが一番楽
cp932の範囲で使ってる分には特に困らないし
多くのコードで if (!変数) ではなく if (NULL == 変数) を目にするんですが、どうしてでしょうか? !変数と比べて可視性が高い事だけが理由ですか? よろしくお願いします。
>>231 勉強になりました、ありがとうございました。
例えばその変数が関数の戻り値を取る場合 エラーが必ず0とは限らないということもある(特にWindows)
>>231 >NULL�==�hogeはくだらない書き方。
リンク先も同様の主張でワラタ。
それにしても、どうして左側に定数を持ってくることにそんなに抵抗があるんだろう?
単に自分の好みじゃないって言うだけならまだ理解できるんだが、なんでそこまで否定的なんだ?
否定的なのは、感覚的に「NULLが(is)hogeなら」っていう不可解な読みになっちゃうからじゃないかな?
そうだな。コードが十分に分かりやすいかどうかを知るためには 電話テスト(電話の相手に音読してみせる)が有効だと カーニハン先生も言ってるしな。
>>235-236 他人にまでスタイルを押し付ける理由としては根拠が不十分だとは
思うけど、せめてそれぐらいの理屈捏ねてればまだいいのに
>>231 のリンク先みたいに逆のスタイルの利点だけあげておいて
それを否定しているのを見ると頭がおかしいようにしか見えない。
math.h をインクルードして M_PI 使おうとしたけど出ません M_PI = π では無いのですか? WinXPのVisualStudio2005 使ってます
239 :
238 :2006/12/05(火) 23:05:28
ごめんなさい、調べたら、 VisualStudioはM_PIを定義されて無いみたいですね orz 自己解決しました #define _USE_MATH_DEFINES #include <math.h> 使います
>>234 リンク先に書いてあるとおり変数同士の比較では意味がないから。
それにどうせ今時のコンパイラなら警告を出してくれる。
>>237 特定の人間を「頭がおかしい」とまで言うにしては
根拠が不十分にもほどがあると思うよ、それ。
>>240 それだとどっちでもいい理由にしか過ぎなくて、否定する理由にはなってないよ。
Boostでも読め 最高のプログラマが実にいろんなスタイルで書いている 定数==も存在する。 コードを読むこととは他人のスタイルを楽しむことだ なんちて
>>237 ,241
俺も if (NULL == x) 式のスタイルは嫌いだが、
CFAQのそこんとこの記述はちと偏りがあるかな、と思うね。
ま、頭おかしいとまでは思わんが。
>>243 この程度で十分と思ってしまうのは頭おかしいとしか思えない。
247 :
デフォルトの名無しさん :2006/12/06(水) 03:30:04
if(定数 == x)という書き方もありとは思うがな... 理由が先に来てた方がコードが読みやすい場合もあるし まあ、NULLを先頭に持っていく意味はわかんないが... if(ALLOC_ERROR == x) とかだと、読みやすくて良いと思う
>>247 その形が複数並んでれば見やすいと思う。
でもふつうはあまり目にしない書き方だから
見にくい場合がほとんど
実際、たまに目にするけどわかりにくい
249 :
デフォルトの名無しさん :2006/12/06(水) 05:00:02
MS Excelに色んな関数が山のように入ってますけど、あれのプログラムを見る方法はないでしょうか?
>>248 そういうのをフツーは慣れの問題って言うんじゃないの?
俺は「定数==変数」の書き方大好きだけどな。 条件判定において、その変数が何物なのかよりも、 そこで何が判定されてるかが先に目に飛び込んでくる方が 読みやすいっていう俺理論。 NULLとの比較はそもそもやらないが。 つーかNULL書かない。
>>249 逆アセンブルなりすれば見られるんだろうが…
根気と能力と刑務所に入る勇気と無謀さが必要。それぐらいだったら
自分で一から書いた方がいいとは思わないか?
>>251 俺は「変数==定数」の書き方。
「何の状態」によってこの処理はされるのかを明確にしたいから
比較対象を先に書く、っていう俺理論。
俺は関数の戻り値と定数を比較することが多いから「定数==変数(関数)」派。 関数の引数が沢山あるとその結果がどうっだったら条件成立なのかがそうほうが 断然わかりやすい。逆のスタイルだと最悪、定数がスクロールしなきゃ見えん かったり、改行された位置に来たりして分かりづらい。 俺がif文を見る時の瞬間的なビジョンは↓こんな感じ。 if (定数 == 関数(ほげ, ひげ, まげ, はげ, ぬるぽ, ぬるぽ,... if (関数(ほげ, ひげ, まげ, はげ, ぬるぽ, ぬるぽ, ぬるぽ... 前者だと俺の脳内CPUは1Clockでそのif分の大体の意味をつかめるが 後者だと同程度の理解をするのに数Clockを要する。とかそんな感じ。
つまんねーネタほど人が群がる傾向は年々強まっていくな。
256 :
デフォルトの名無しさん :2006/12/06(水) 14:28:52
WinでCのCUIアプリでビープ音出したいんですけど printf("%c",0x07); で出ませんでしたっけ?
>>256 それで出るはずだと思うがな。stdoutがリダイレクトされてなければ。
258 :
デフォルトの名無しさん :2006/12/06(水) 15:43:55
なんか使ってるパソのせいみたいでした。 別のでは鳴ったので。どうもおさわがせいたしました。
>>255 タイトルにも【初心者歓迎】ってなってるスレでなに言ってんだ、お前?
初心者≠馬鹿
>>259 「群がっ」ってるレスは明らかに初心者のものではなくて
非初心者による宗教論争にも行かない自分語りなのに
なに言ってんだ、お前?
今時のPCは内蔵スピーカが省略されてて'\a'でも音が出ない奴が ちらほらあるからなぁ・・・・ 圧電スピーカーはパーツ屋に行けば売ってるんだが
コンパイルしてD&Dで、 『てすと.dat』という名前のファイルを開こうとしたら エラーになります。 (半角で)『test』という名前のファイルの場合は、 正常に開けます。 『てすと.dat』の場合に開けないのは、何か問題があるのでしょうか? #include <fstream> #include <iostream> using namespace std; int main(int argc, char *argv[]) { ifstream fin; fin.open(argv[1], ios::in); if (!fin){ cout << "以下のファイルを開けません!\n" << "ファイル名 : " << argv[1] << '\n'; }; } 【環境】Visual C++ 2005 Express Edition コンソールアプリケーション
>>263 こっちでは同環境(与えられた情報の範囲内では)開けるがなぁ…
>>264 確認、ありがとうございます。
どうしてでしょう。何か私の環境に問題があるのでしょうか?
どうしても、if文の中に入ってしまいます。
266 :
デフォルトの名無しさん :2006/12/06(水) 18:49:56
全角、半角交じりだと、入力してるファイル名がそもそも間違ってないか確認した方がいいのでは?
>>266 if文の中に入って、↓のように表示されるのは確認しました。
以下のファイルを開けません!
ファイル名 : D:\てすと.dat
入力されているファイル名は正しいと思います。これじゃ甘いですかね?
俺(EE)も以前それでつまづいたことがあるんだけど、wchar_tにして渡さないとだめみたいだった fin.open(L"D:\\てすと.dat", ios::in);
std::locale::global(std::locale("japanese"));
>>268 >俺(EE)も以前それでつまづいたことがあるんだけど、wchar_tにして渡さないとだめみたいだった
>fin.open(L"D:\\てすと.dat", ios::in);
おー、開けました。
↑のL"D:\\てすと.dat"のLと\\がポイントですか?
Lと、\×2をしてopenの括弧に入れないといけないってことは、
argvから入力しても、そのまま
fin.open(argv[1], ios::in);
なんてことは無理ってことですよね?
(だとすれば、openじゃなくてfopenの方が使いやすい気がする...)
271 :
268 :2006/12/06(水) 19:32:32
>>270 >>269 だな。
setlocale(LC_ALL, "");
とかって書こうとして開いたらすでにつっこまれてた
>>270 ソース上は\\だけど、実際には\だぞ。
std::locale::global(std::locale("japanese") ↑これを設定しないといけないのは、Visual C++ 2005 EEの場合で、 他の環境では、不要の場合もあるんでしょうか?
275 :
264 :2006/12/06(水) 20:10:51
同じ環境で開けてしまった俺の立場はいったいどうなるんだ?
>>273 そのLはそれに続く文字or文字列がワイド文字であると知らせるためのもの
Large の L じゃなかったっけ? でっかい数値リテラルにもつけるやつと同じ意味だよね?
いや、意味チャウやろ。 ていうか、数値リテラルのLはLongやろ…
ついでに言うと数値リテラルのは数値の後に書く
>>274 俺の環境はVS2003.NET(VC7.1)だが、別にいらん。
VS2005(VC8.0)では #define UNICODE がデフォのようだし、
デフォルト動作としてパスを勝手にUnicode変換して
CreateFileW()でファイル開こうとするのかもな。
そんなら、確かにlocale設定してエンコード指定しとく必要があるだろう。
なんか、VC8.0て、ワイド文字/locale周りの品質が聞くだに
怪しいな……
wcoutにwchar_tがちゃんと出力できないとかいう話もあったし……
SPか何かで直るのかねえ。
CランタイムのDLL自体がダメってことだと、SPで開発環境は直せても
他環境は古いままでバグってる可能性あるしキツいよな。
std::locale::global() でも症状は改善するけど、数値の出力にカンマが入るようになったり、 副作用が大きい。問題が発生するのは、 fstream の open() の中で勝手に mbstowcs() を使って変換するせいなので、 setlocale(LC_CTYPE, "") とすれば 十分だったはず。
正直locale指定は死んでくれて良い。 つーか誰かアカデミック・バカどもの手から、C++を取り上げてしまってはくれまいか。 奴らはなんかもっとこうメタメタなメタ言語でも与えて延々思考ゲームで遊んでるべきで、 高度な最適化を施された生バイナリをOOPで組めるというシンプルなC++の存在意義を 脅かす以外に何一つC++に貢献してくれてくれてない気がするんだが、その辺どーですか。
>>282 「あまり賢くない人は自分が理解出来ないことについては何でもけなす」 - ラ・ロシュフコー
借り物の言葉なんかでなくって、あなた自信の言葉が聞きたいです。 ママ的には。
こんだけシンプルな格言は、オリジナルでも細かい口調しか変えようがないな。 で、「そりゃお前があんま賢くないから、価値もわかんねーで貶してるだけだろ」 に変わった途端納得するのも変な話。
std::locale::global(std::locale("japanese")); ↑設定すると、以降で↓のような全角の出力をしようとすると 難しくなります。なぜ?これって回避する方法はありますか? cout << "表示テスト" << '\n';
なんか、↓を追記すると、std::locale::global(std::locale("japanese"));は解除されるみたいです。(解決できたかも) std::locale::global( std::locale("C") );
cout.imbueしろよ
STLportのように、locale対応すると重くなるからとばっさり切り捨てて "C"だけ実装してあるライブラリを使えば気が楽になるよ^^
>>288 >cout.imbueしろよ
imbueってどうやって使うんですか?WEBで検索してもよく分からないです。
(というか何をやるものか、わかりません。)
こんな(↓)風にすればいいんですかね?
cout.imbue(std::locale::global(std::locale("japanese")));
>>289 @でもAでも、記述した箇所移行で、coutが日本語を
出力しなくなります。(VS EEでは、設定しないと日本語名のファイルを
オープンできなくなる...)
std::locale::global(std::locale("japanese")); ----- @
setlocale(LC_CTYPE, ""); -------------------------- A
最小限に絞った setlocale(LC_CTYPE, "") でも結局副作用が許容範囲外だな。 fstream の open() する前に切り替えて、後で戻せばいいのか? MS 死ねって感じ。
setlocale()は挙動がglobalだからなぁ。 もともとmain()の最初に一発 setlocale(LC_CTYPE, "") して安直にI18N/L14Nする、 という使いかた以外あんま考慮されてない気がするし。 実行時にglobalなCロケール切り替えるなんて、マルチスレッドなプログラムなら 論外だべや。 つか、このVC8.0の挙動って何なの?一応規格どおりのlocale対応だったり するわけ?
>>293 if文の中に記号をごちゃごちゃ入れられると見づらいので
よっぽどな事が無い限りは、適当な変数に値を入れ
それで比較してくれると可読性が良いので助かる。
また変なコピペ厨が
>>293 しばしばそれで文句が出てるのを見かける。
俺は諦めて最初からUNIでいくかマルチでいくかしか考えてないや('A`)
なんかC++ localeって小難しいんだな。 俺は手持ちにVC8.0の環境が無いので確認できんのだが、 ↓みたいな方法でどうだ? loc1はクラシックロケール(Cロケール)をベースにcodecvt<>だけを 日本語ロケールのものに置き換えてるんで、 setlocale(LC_CTYPE, "japanese") に相当すると思う。 #include <iostream> #include <locale> main() { std::locale loc1(std::locale::classic(), "japanese", std::locale::ctype); std::locale loc2("japanese"); std::cout.imbue(loc1); std::cout << "日本語 " <<10000 << "円" << std::endl; std::cout.imbue(loc2); std::cout << "日本語 " <<10000 << "円" << std::endl; }
結局 ・locale設定しないとfstream::open()で日本語ファイル名のファイル開けない ・locale設定すると(w)coutが腐る ってこと? 終わってるなVC2005
重複組み合わせを出力していくプログラムを作っているのですが、 3H4=15としてa,b,cから4つ選ぶ場合、aaaa,aaab,aaac,aabb,aabc・・・となるのを 例えばaaaaについてaはP[0].co[0]=4、bはP[0].co[1]=0、cはP[0].co[2]=0 というように順々に格納していきたいです。 よろしくお願いします。
int na, nb, nc, i; i=0; for (na = 4; na >= 0; na --) { for (nb = 4 - na; nb >= 0; nb --) { nc = 4 - na - nb; P[i].co[0] = na; P[i].co[1] = nb; P[i].co[2] = nc; i++; } }
これだと重複組み合わせじゃなくてただの組み合わせじゃね?
んなこたぁねぇよ?
305 :
301 :2006/12/08(金) 00:21:11
すいません、ABCの3種類だけではなくN種類とするとどうすれば良いでしょうか? よろしくお願いします。
>>305 まずは自分で書けよ。困ったら、困ってる箇所を相談してもいいからさ。
>>306 どのように書いていけばいいのでしょうか?
>>307 まずはメモ帳でも開け。あとは、わかるな?
309 :
301 :2006/12/08(金) 00:49:58
読み込みを4から40ぐらいに増やすと固まってしまいます。 年間で365日でやってみたいので3種類とすると3H365=67161ですよね? これってintが足引っ張ってるんでしょうか?
エスパーが必要だな。
なんだこりゃ。 おまえさんのPCのスペックが悪いせいじゃないのか。 4ってのはna=4のこと?
67161パターンも格納するからフリーズするんだよ。そんな量使うんだったら格納するな
なんだかわからねーが、とりあえずPは何個用意してあるんだ。
関数や変数なんかの名前で付けるべきでないとされるのって アンダースコアで始まる、アンダースコアが2つ連続する、 ぐらいでしたっけ?
(メンバ関数でなくて) 普通の関数で、戻り値がstringクラスのものって宣言できますか? ↓こうすると、 string func ( char *ucAAA ); error C2146: 構文エラー : ';' が、識別子 'func' の前に必要です。 "戻り値がstringの関数の宣言"でなく、stringクラスのオブジェクトを 生成していると解釈されてしまったようです。 戻り値が、stringクラスの関数は、宣言できないのでしょうか?
std::string or using namespace std;
320 :
デフォルトの名無しさん :2006/12/08(金) 23:39:11
すいませんが、教えてください。 VS2005stdで、C/C++等を勉強してるんですが クイックソートについて質問さしてください。 クイックソートは再帰使って、文字通り早いのはわかるんですが 再帰呼び出しが多すぎるとスタックオーバーフローすると思うんです。 で、自分の環境下で、何回再帰呼び出ししたらスタックオーバーフローするのか 確かめるにはどうしたら良いんでしょうか。 配列が長くても、配列内の数値次第でソートのための再帰呼び出し回数が 変わってくるとおもうので、意味が無いと思いますし・・・ 申し訳ありませんが教えてください。
>>320 クイックソートは別に再帰を使わなくても実装できる。
再帰を使った方がシンプルに書けるが、繰り返しで実装することも可能だ。
>>320 再帰は自前でスタックを用意すれば楽に移行できる
>>320 リンカの設定あたりでスタックサイズ増やしてしまえ
>>320 分割したうち短いほうを通常の再帰、長いほうを末尾再帰で書けばスタックはあふれないよ。
Excel VBAで数値計算してmasu 実際計算してるのはC++で書いたdllで エクセルがいろいろパラメータを変えてそいつを呼び出してます それで、今性能評価をしているのですが、 特定のdllの特定の関数が呼びだされた前後でフックして 処理時間を計測することは可能でしょうか? VBAにロジックを入れてもいいのですが、 多数のdllをいろんな場所で呼び出してるので大変です。 お願い島耕作
なにこれ
327 :
325 :2006/12/09(土) 02:12:25
酔っ払っていたもので、失礼な書き方をして 申し訳ありませんでした
普通にVBAで計測したら? 酔って下らないこと書く暇があったらそのくらいできるでしょ。
>>328 あほか。それができないって書いてあんだろ
何が「できるでしょ?」だ。お前は学校の先生か。死ね!!
330 :
デフォルトの名無しさん :2006/12/09(土) 10:13:14
>>328 >>329 は私ではありません
でもハゲドウイ
わからないんだったらいちいちうざいレスしないでください
331 :
301 :2006/12/09(土) 11:36:18
>>301 なのですが、C始めたばかりなので1日考えても分かりませんでした・・・。
最初の質問では重複組合せだったのですが、今回は重複順列で
for(a0=0;a0<4;a0++)for(a1=0;a1<4;a1++)for(a2=0;a2<4;a2++)for(a3=0;a3<4;a3++)for(a4=0;a4<4;a4++)for(a5=0;a5<4;a5++)printf("%d %d %d %d %d %d\n",a0,a1,a2,a3,a4,a5);
のようにforをひたすら列挙する以外の書き方はありますでしょうか?
よろしくお願いします。
一晩寝ても酔いがさめてないのかよ。 知ってはいるがお前の態度が(ry
333 :
デフォルトの名無しさん :2006/12/09(土) 11:47:16
質問です if文って普通は if(条件式){ 処理 }; と書くと思うんですが、 本を読んでいたら条件式のところに変数だけのプログラムが出てきました これって、どういう判断をしているのでしょうか? ど素人な質問ですいません
C/C++でが0が偽、0以外が真になる。
335 :
301 :2006/12/09(土) 11:52:25
for(j=0;j<na;j++)for(k=0;k<6;k++)for(a[k]=0;a[k]<2;a[k]++)printf("%d %d %d %d %d %d\n",a[0],a[1],a[2],a[3],a[4],a[5]); こんな感じに書いてみたんですけどさっぱりで・・・。
336 :
335 :2006/12/09(土) 11:54:38
>>334 なるほど、つまりif文の中で書かれた変数がtrueかfalseかってことですね
ありがとうございました
337 :
333 :2006/12/09(土) 11:55:35
ごめんなさい 335は333でした
必死すぎて笑える
笑いのツボが変だねキミ
そもそも酔っぱらってて性能評価ができるのかね? プログラムがまともに動いても、エンジニアが 壊れてるんじゃ・・・ねぇ
342 :
デフォルトの名無しさん :2006/12/10(日) 21:55:10
質問さしていただきます。 Cでmalloc()を使ってヒープからメモリ借りて realloc()でサイズを増やしたりできますが C++では一度newしたあと、どうやって増やすんでしょうか 普通のintなりdoubleなりの配列ならstd::vectorを使って pushbackやremoveやclearなどで増やして削除する要素を移動さし要素削除 で出来るのはわかるんですが、Cにあたるreallocはあるんでしょうか すいませんが教えてください。お願いします。
ない。 だからstd::vectorとそのメンバresizeを使え。
>>342 C++にrealloc()に相当する演算子がないのは、コンストラクタや
デストラクタの絡みです。
自分で新たにnewしてコピーして面倒を見るか、コンテナを
使いましょう。
>>342 reallocはない。
だからstd::vector等のresizeで代用
禿本にもそうしろと書いてある
重婚にも程がある
347 :
342 :2006/12/10(日) 22:08:21
わかりました。 ありがとうございました。
私のまったくの勘違いかもしれないのですが、BSD等なら特にヘッダーをincludeしなくても writeやreadのシステムコールがC言語内で呼べますよね? Windowsの場合、標準ライブラリなんかで最終的にシステムコールが出来るような 関数ってあるんでしょうか?とりあえずreadとかwriteは呼べなかったんですが・・・
>>348 Windowsではシステムコール+OS提供ライブラリルーチン集に相当するものが
Windows APIと呼ばれている。
read(), write()といったAPIはWindowsには存在しない。
ReadFile(), WriteFile()ってのが、それ相当。
ただし、VC++のような開発環境は、Unixライクなread(), write()を
ライブラリレベルのエミュレーション層として提供している。
なお、「特にヘッダーをincludeしなくとも」というやり方は全く薦められん。
ANSI C以前ならあまり意味の無いこともあったかも知れんが、
今後はプロトタイプ宣言による型チェック機能を利用するためにも、
ちゃんとincludeしる。
Unixなら<unistd.h>などだ。
>>349 なるほど、わかりやすい説明ありがとうございます。
ということはstdio.hなんかは内部でReadFile等の関数定義、並びにkernel32.dllなんかの
system32フォルダにあるDLLを動的(?)にリンクしてReadFile等の関数をImportしてる感じなんですかね?
ヘッダーに関しては普段はincludeしてたんですけど、少し実験したら動いちゃったもので。
気になって調べてました。
>>350 Cコンパイラはヘッダの情報を見て型チェックなりを行うが、C言語において
プロトタイプ宣言は必須じゃないのよ。だから、仮にヘッダを取り込んで
いなくとも、コンパイラはコンパイルを通してしまう。
そして、リンカはシンボルの名前しか見ないから、適切なライブラリと
ちゃんとリンクされていれば、通してしまう。
この場合、コンパイラによるプロトタイプ宣言を利用した型チェックが一切
行われないし、例えば sqrt(1) みたいな呼び出し(本当はdoubleの引数が
要求されているのにintを渡している)も素通しだ。
プロトタイプ宣言があれば、int→doubleの型変換はコンパイラによって自動的に
なされる。
352 :
351 :2006/12/10(日) 23:48:31
あー。一応補足しとくが、 >そして、リンカはシンボルの名前しか見ないから、適切なライブラリと >ちゃんとリンクされていれば、通してしまう。 普通リンクライブラリはリンカに対して明示的に指定してやらないといけないが、 処理系がデフォルトでリンクするライブラリも存在する。 何にも指定してないつもりでもread()やwrite()が使えたり printf()が使えたりってのは、そのせいだ。 要するに、デフォルトでリンクされるライブラリの関数を、その本来の宣言と 無矛盾な形で利用している限りは、何もせずとも一応動作することは動作する。 ただし、それは良いやり方ではないから、今後はちゃんとヘッダを取り込むことだ。
>>350 stdio.hほか殆どのヘッダが参照しているのは、
libcに当たるもの(VC++ではCRT、Cランタイムライブラリなどと呼んでいるが)。
そいつらがWindowsではWindows API、Unix/LinuxではPosix API(システムコール)を基に
Cの標準ライブラリの関数やその他独自の関数を実装している。
>>350 ちょっと勘違いしてる部分もあるみたいなので補足すると。
>ということはstdio.hなんかは内部でReadFile等の関数定義、並びにkernel32.dllなんかの
>system32フォルダにあるDLLを動的(?)にリンクしてReadFile等の関数をImportしてる感じなんですかね?
ヘッダファイルは関数のプロトタイプ宣言などは書いてあるが、
ライブラリのリンクはまた別の話だ。
#includeでヘッダファイルをインクルードするとライブラリのリンクまでやってくれるというわけではない。
stdio.hが普通にテキストファイルとして存在するから中を覗いてみたら?
>>354 >stdio.hが普通にテキストファイルとして存在するから中を覗いてみたら?
解説ヨロ^^;
>>351 なるほど。暗黙のうちにライブラリがリンクされてしまう処理系もあるんですね。
知りませんでした・・・。丁寧にありがとうございます。
>>353 なるほど、libcなんていうライブラリがあるんですね。どこからOSのシステムコールに
入るのかずっと不思議だったのですが、解決しました。ありがとうございます。
>>354 stdio.hとか更にその中でimportされてるヘッダーを色々見てみたんですが、
VCはオープンソースじゃないせい(?)かその実装まではよくわからなかったんですよね。
まだよくリンクというものがわかってないので勉強したいと思います。
ありがとうございました。
357 :
356 :2006/12/11(月) 00:20:53
実装というか定義ですね。まあ
>>355 でいわれてるように宣言だけでも私には難解で
解説お願いしたいぐらいです・・・
359 :
デフォルトの名無しさん :2006/12/11(月) 00:27:21
質問なんですが、gccで、 動的ライブラリのSOファイルにiostreamをインクルードすると、実行時に、 undefined symbol: __dso_handle ってエラーがでるんですけど、なんか対処法ないですか? $ g++ -Wall -g3 -c test.cc $ g++ -shared -nostartfiles -o test.so test.o こんな感じでコンパイルしてます。
>>356 libcってのは、printf()のようなC言語標準関数群を含むライブラリの
伝統的な呼称。無論実際の名前は処理系によって違う。
ただし、<math.h>で宣言される数学関数等が含まれて居なかったりするが。
>>354 が説明しているように、JavaやC#のような現代的な言語とCは違って、
ヘッダとリンクは明確に意味が違うものだ。importに相当する概念は
存在しない。
あくまでC言語としての宣言を取り込むのがヘッダの#include。
コンパイル後の、マシン語のレベルで実際にライブラリに実装されている
関数と結合するのがリンク。これを実行時に動的に行う仕掛けがいわゆる
DLLだ。
ちなみにVC++のように、#pragmaを利用して、ヘッダを#includeするだけで
自動的に必要なライブラリをリンクさせる実装もある。
>>356 >VCはオープンソースじゃないせい(?)か
VCは標準ライブラリのソース付属してるよ。
ライブラリはソースがついてこないとやってられないからな
>>361 Expressだと付いていない。
上の付いているエディションでも、改変したソースを人に配れるようなライセンスではないと思う。
stdlibインクルードせずにmalloc使ってて「返り値intなのにポインタに格納しようとしてんな馬鹿!」 とか言われるなんてしょっちゅうですよ、ええ。
>>364 Platform SDKに付いてるよ。最新のかどうかしらないけど。
367 :
デフォルトの名無しさん :2006/12/11(月) 15:36:59
linux上でプロセス情報を取得するプログラムを作成したいと思っています。 検索して調べたところ task_structという構造体にプロセス情報が格納されているということは分かったのですが、 検索したサイト先であげられているヘッダファイル "include/linux/sched.h" 内に task_structに関する記述が無いのです。 上記構造体を利用するためには、 何か別の手段をとらないといけないのでしょうか? OSはred hat linuxです。 分かる方いましたらよろしくお願いします。
ストリームを引数にしたいときって、どういう型にすればいいんでしょうか 例えば、何かを表示する関数something_dumpがあって std::ofstream a; //aのファイルを開く処理 something_dump(a); あるいは something_dump(std::cout); みたいな使い方をしたいとき、something_dumpの型宣言はどうしたらいいんでしょうか
371 :
369 :2006/12/12(火) 03:07:41
372 :
367 :2006/12/12(火) 12:14:02
>>368 スレ違いすいませんでした。
該当スレを見つけたのでそちらに逝ってきます
373 :
デフォルトの名無しさん :2006/12/12(火) 13:12:54
struct name { unsigned name_1 : 1; unsigned name_2 : 1; }; こういう構文の : 1; ってどういうときに使うもんなんでしょうか? さっき初めて見かけて、あてずっぽうでこの構造体にsizeofしたら4ってなったのですが まったく意図というか用途がわかりません ちなみにVC2005で試してます
>>374 びっくりするほど基本構文です
ほんとうにありがとうございました
>>375 めったに使われないからね。
言葉すらひさびさに聞いた。
まぁビットフィールドは色々問題多いから、自分で明示的にビット操作やる ことのが多いかな
VC++を使っています。 市販のプログラムでフォーカスを失うとアニメーションを停止するアプリがあるのですが バックグラウンドに押しやった状態でもアニメーションを続けてもらいたいのです。 そこで、ON_WM_KILLFOCUSメッセージを渡さなければいいのではないかと思ったのですが、 このように、他のアプリケーションのイベントを阻止するようなプログラムを作るには どのようにすればいいでしょうか?
アプリケーションの名前は?
>>378 アプローチの仕方が違う。
別スレッドで描画を回すか、別スレッドからWM_PAINTを投げるとかするのが常道。
他のプロセスの動作に干渉しようとしたり、処理を奪おうとするのは基本禁じ手。
一人和を乱す奴がいたおかげで全体が迷惑するのはよくある話。
避けるべき。
382 :
デフォルトの名無しさん :2006/12/13(水) 19:26:10
場違いかもしれませんが、質問する場所が分からなかったのでここで質問させていただきます。 当方BCC Developer 1.2.21を使ってC言語の開発を始めたばかりの者ですが 例えばTest1.bdpというプロジェクトをつくってその下にsample1.c sample2.c sample3.c といったファイルを作ったとします(ソースの中身はなんでもいい) それで私が困っているのは、sample1.cをまず最初につくってメイクしてコンパイルして実行すればちゃんと実行できるのですが sample2とsample3もメイク→コンパイル→実行といった順番で行うと 一番最後にコンパイルしたものしか実行できなくなります (画面左のsample1や2を選択してメイク、コンパイル、再構築等を実行してから実行のコマンドを押してもSample3が実行される) スレ違いかもしれませんが、解決法を教えてください。
>>382 基本的にプロジェクト一つにつき実行ファイル一つだよ
(よってmain関数を持つファイルも一つだけ)
プロジェクトに複数のファイルを登録するのは分割コンパイルをするためにある
384 :
382 :2006/12/13(水) 22:06:34
へぇ、そうなんですか。 ありがとうございました。
VC2003を使っています。 あるファイルが使用中かどうかを判断するにはどういったAPIを使えばいいでしょうか? 具体的には、監視しているWavファイルが使用されたら、 指定の動作(メールを送るとかLAN経由でファイルを実行するとか) をするというものを作りたいのですが。
#include<stdio.h> int main(void) { int no; scanf("%d",&no); do{ if(no % 2 == 0){ 1/2*no=no; } else{ 1+3*no=no; } printf("%d\n",no); }while(no != 1); return 0; } 左辺値が必要ってなんだよ うんこやろー('A`)
>>386 もしかしたら、noにnoの半分の値を代入したいのか?
それなら、no = no / 2;だ。
そのエラーメッセージの意味は、「=の左側は代入できるものじゃないとダメ」と言う意味だね。
>>387 おまい天才
ありんがちょーーーーーーー
随分と安い天才だなあ。俺も欲しいぜ。
390 :
デフォルトの名無しさん :2006/12/14(木) 08:32:43
C++ Win32APIです。 リソーススクリプトで作成したダイアログに、複数のエディットボックスがあります。 Tabボタンを押すと、他のエディットボックスにカーソルを持っていくようにしたいのですがどうすればいいのでしょう。
メッセージループで IsDialogMessage を処理する
393 :
デフォルトの名無しさん :2006/12/14(木) 20:17:56
map<double, vector<string>> m; が駄目なのはどうしてでしょうか? どのように宣言すればいいのでしょうか?
×map<double, vector<string>> m; ○map<double, vector<string> > m;
395 :
デフォルトの名無しさん :2006/12/14(木) 20:23:17
>>394 即レスありがとうございます。
できました、ありがとうございました。
>>395 そいつができるようになるにはもう少し時間がかかるぞ〜
コンソールでアプリ作ってるんだけど、 printf("\x1b[1;1H"); とやってカーソル移動したり表示色変えたいんだけど、エスケープシーケンスが うまくできない。どうやればいいかご教授ください・・・・環境はVC++2005EE、WinXPです。
32bitコンソールアプリではエスケープシーケンスは使えない。 16bit DOSアプリならansi.sysを組み込めば使えるがVC++2005EEでは16bitアプリは作れない。
代わりにWindows APIでカーソル移動や文字色変更の関数が用意されている。
400 :
397 :2006/12/14(木) 22:18:01
>>398 ,399
ありがと。ANSIもいいがWinAPIもやってみるよ。
WinAPIがANSIじゃないというのか
CってANSIで規格されてるでしょ? でもWinAPIは環境依存だから違う・・と思ってたんだが。 WinAPIもANSIで規格されてるってこと?
どこから突っ込んだものやら
>>401-402 ↑で言ってるANSIってのは端末制御の規格の話で、C言語の規格とは
全然別の話だよ。
↓のソースコードみたいにyやnを入力してループを終了するのではなく、 画面に continue finish のようなのを用意しておき、方向キーの「←」「→」で、 選択した方されたほうを、括弧([ ])で continue [finish] のように表示させて、enterキーを押すと 決定される(上の場合はループを抜ける)ようにしたいのですが、 どうしたらいいのでしょうか? #include <iostream> using namespace std; void main() { char cInput = 'n'; do { cout << "終了する場合は y を入力\n"; cin >> cInput; } while ( cInput != 'y' ); return 0; }
Visual C++ 2005 express (コンソールアプリケーションで)を使っています。
>>405 Cならこれでいける
#include<stdio.h>
#include<conio.h>
#define KEYCODE_ENTER 0x0D
#define KEYCODE_EXTEND 0xE0
#define KEYCODE_RIGHT 'M'
#define KEYCODE_LEFT 'K'
void print_menu(int menu_item){
if(!menu_item) printf("\r[continue] finish ");
else printf("\r continue [finish]");
}
int main(void){
int menu_item=0;
int keycode;
while(1){
print_menu(menu_item);
keycode=getch();
if(keycode==KEYCODE_ENTER) break;
if(keycode==KEYCODE_EXTEND){
keycode=getch();
switch(keycode){
case KEYCODE_RIGHT: menu_item=1; break;
case KEYCODE_LEFT: menu_item=0; break;
}
}
}
printf("Your choice is %d\n", menu_item);
return 0;
}
>>407 非常に助かります。
ありがとうございました。
横からすまないが、誰か
>>407 を解説してくれないか。
一度目のkeycode=getch(); でキーボードから何か受け取りエンターキーなら
breakするよね。方向キーならmainの中の二度目のifに入れるところまでは
わかるがその下のkeycode=getch(); はMかKを受け取っているの?
方向キーって文字コードどうなってんだ?
>>409 方向キーは一回押すと二つのコードがキーボードバッファに入れられます。
普通のキーとは扱いが違うので注意が必要です
>>410 二つのコードだったのか!右がM、左がKみたいだけど
上下の方向キーはどうなんです?
>>411 自分で試してみればいい
printf("%02X [%c]\n", keycode, (keycode<0x20 || keycode>=0x80)?'.':keycode);
これからC++を学ぼうと考えています。 (プログラム自体が)初心者向けの書籍やサイトは多くありますが、 他のプログラム経験者がC++を学ぶための書籍やサイトってありませんか? 当方javaをメインでやっているので、 「"自動車"オブジェクトは"タイヤ"オブジェクトと"ハンドル"オブジェクトが云々」みたいのを すっ飛ばした感じのがあればうれしいです。
414 :
デフォルトの名無しさん :2006/12/16(土) 13:06:55
Javaやってるなら新要素はポインタくらいじゃね?
java・・・w
Javaで初心者じゃないなら初心者向けC/C++書籍・サイトでもいいんじゃ? 明らかに簡単なところは飛ばして読めば良いわけだし。
>>414 templateを忘れるな。JavaのGenericとは異質だと思うぞ。
ようこそメタプログラミングの世界へ。
質問です。 クラスのメソッドでvectorやmapなどのクラステンプレートをオーバーロードすると error C2084: 関数 'void testDat::getUserParam(std::vector<_Ty> &)' は既に本体を持っています。 というエラーが発生します。サポートを見てみたのですがよく分かりませんでした。 どなたか初心者にも分かるように説明していただけませんか? よろしくお願いします。
>>418 それだけじゃなんとも言えないけど、クラステンプレートどうこうは関係なさそう。
testDatクラスの定義の仕方がおかしいんじゃない?
testDatクラス定義とgetUserParam関数の実装のソースを晒せば分かるかも。
(大きかったら全部載せないで、エラーが再現する必要最小限の部分にしてほしいが。)
420 :
418 :2006/12/16(土) 14:38:41
すみません、自己解決しました(^^;) 二回実装してしまっていました。 次回からもっとよくソース確認します。(´Д⊂グスン
解答ありがとうございます。
>>414 ポインタは知識としては理解してます。
それよりも、不必要になったオブジェクトが確保したメモリは、
明示的に解放しなきゃならない(NULLを入れればいいの?)という噂を
耳にしたんですが…。GCは!?
それが本当なら恐ろしい話ですね…。
>>416 「ここは知ってるから飛ばそう」なんてうちに、重要な部分を見逃してしまう可能性があるので。
「java開発者のためのC#入門」みたいなサイトがあるんですが、そういうのがC++にもあればと。
もしなければ、初心者向けの本でも買って読もうと思います。
でもそれって中国語を学ぶために「中国の小学校に入学する」感じなんですよね…。
>>417 java1.4で開発してて、ジェネリックプログラムを知りませんでした。
java1.5のジェネリックは便利そうですね。
…でもjavaのそれとは異質なんですか('A`)
>>415 javaで悪かったなw
422 :
413 :2006/12/16(土) 15:41:40
失礼。↑は413です。
>>421 GCは無い。が、C++的にはスマートポインタがあればそんなもの不要。
コンストラクタで初期化し、デストラクタで始末するのが全ての基本。
424 :
871 :2006/12/16(土) 17:00:44
>>421 そもそもnewしないと使えないJavaにはGCが必要だが、
必ずしもnewする必要がないCにGCがないのは蓋し当然。
newしたものをdeleteするのが嫌ならvectorでも使いんしゃい。
>>424 綺麗かどうか以前に、論外でダメすぎで阿呆。
427 :
424 :2006/12/16(土) 17:23:27
えーw 結構自信作なんですけど
とりあえず文字列操作がうんこ。 \tがみつからない時の処理がない。 さらに後置インクリメントを始めて覚えた小学生のように無駄に使いすぎ strcspn,strpbrkとかつかえば自前でループまわす必要ない。 グローバル変数死ね。 runのプロトタイプ定義しろボケ 結論を言えばゴミ
この程度のプログラムで無駄に外部変数を使っている時点で論外。 与えるテキストファイルによっては誤動作の原因になりそうでダメすぎ。 標準関数でできることをわざわざ自分で実装している辺りは阿呆。 まぁ、いかにも初心者らしいコードで微笑ましくはあったよ。 指摘した辺りを自力で修正できたら、かなり力になると思うよ。 #これよりもっと酷いコードを書くプロがいるのも事実だけどね。
これならどう? while (fgets(buf, sizeof(buf), in)) { scanf_ret=sscanf(buf, "%*[\t]%[^\t]%*[\t]%[^\t\n]", filename_src, filename_dest); if(scanf_ret!=2) continue; rename(filename_src, filename_dest); printf("\"%s\" -> \"%s\"\n", filename_src, filename_dest); }
return run(); この辺ががんばりを感じた
>>431 私は逆に、main()のみがコマンドインタプリタとのI/Fという考えからrun()がEXIT_*を返すのは反対。
つまり私なら、run()は処理の成否のみを返すことにして、main()でそれをどう扱うか決める。
どうせUsage表示するのもmain()だしね。
>>430 sscanf()を使う辺りは私好みw
>>433 激しく同意。
>>424 sizeofの後は括弧でくくれ。
ライブラリを使え(strchr)
sizeofの対象を括弧で括らないのは別にいいと俺は思うけどな。
>>437 オレが思うには
すべて256にすれば
↓
すべて255にすれば
だな
>>437 in.txt はテキストエディタで編集できる?できない?
出来上がりのビットマップのファイルサイズはいくら?
ビットマップのbppは32bitじゃダメ?
教えてgooとおマルチ
okwaveとマルチだな。
被ったorz
マルチポストチェッカーが欲しいな
同じだったのか。知らなかった。 というより 教えてgoo と okwave を今知ったthx
>>446 他にも、日経bpとかなんだとか、およそ20社くらいがOKのライセンスで同じことをやっている。
448 :
424 :2006/12/16(土) 21:06:57
ありがとう勉強する
自分Visual C++ 2005EEでプログラムしてるんですが
>>407 のgetch()はGCCでも使えるんでしょうか?
MinGWならそのまま使えると思うが、Linuxとかなら、conioの代わりにcursesを使うことになるかも。
451 :
デフォルトの名無しさん :2006/12/17(日) 21:47:10
ある数値を渡されると、その数値の 2 乗を求め、 その値を return する関数 pow を作る。 main 関数において、1 から 10 までの数値の 2 乗を pow 関数を呼び出して求め、それぞれの値とその合計を表示する。 この二つのソースコードをおしえてください。
コンソール画面を表示した時に、
[alt] + [半角/全角]キーを直接たたくのでなく、
上の
>>407 のような方向キーの入力で、全角 ⇔ 半角の変換を
行いたいんですが、
[alt] と [半角/全角] の文字コードが分かりません。
これは元々文字コードはないのでしょうか?
とりあえずSendInputしてみたら?
質問なんですけど 全角数字1と半角数字1を_wtoi()関数で数値に変換すると 両方とも1が返ってきます。全角か半角かチェックする場合 方法ってありますか?合ったら教えてください。
ちょいと言葉がおかしかったです。すみません。 正しくは >全角か半角かチェックする場合方法ってありますか? ではなく >全角と半角の数字を識別する方法ってありますか? です。よろしくお願いします。
文字列をぐるぐるまわして L'0'<=ch&&ch<=L'9'と L'0'<=ch&&ch<=L'9'をifで判定する話か?
460 :
458 :2006/12/18(月) 22:58:42
>>459 レスどうもです。
教えていただいた方法で判定できました。
ありがとうございますm(_ _)m
test
Cではexternの使い方としては ======file1.c====== int g_foo; とし、 これを他のfile2.cファイルから参照する場合、 ======file2.c====== extern int g_foo; としますよね? C++の場合、 ======file1.cpp====== extern int g_foo; とし、 ======file2.cpp====== extern int g_foo; としてもインスタンスは一個だけ作成されるのですか? もともとc言語でも両方にexternをつけてもインスタンスは一個だけ生成されるんでしたっけ? (VC++で試すとcファイルでも両方にexternをつけてもOKだけど、VCは拡張されているかもしれないから良くわからない。。)
>>462 > ======file1.cpp======
> extern int g_foo;
> とし、
> ======file2.cpp======
> extern int g_foo;
C でもC++ でもリンクエラーが発生するはずだが。
>>462 普通は
======fil1e.h======
extern int g_foo;
=====file1.cpp=====
int g_foo;
======file2.h======
extern int g_foo;
にする
>>464 宣言は一つでいいだろ。なんで2つのヘッダに置くの?
見えないからでは?
いや、寝ぼけてただけ/ 。゚ 3 `ヽーっ
というか、 #ifdef HOGE #define EXTERN #else #define EXTERN extern #endif みたいな仕掛けを用意しておいて、 file.h : EXTERN gHoge; file1.c : #include "file.h" file2.c: #define HOGE #include "file.h" みたいにしない?
>>468 小手先の技巧に走ってもメリットがないので、弊社コーディング規約では不許可。
寧ろ、グローバル変数や外部変数はコスト意識を持たせる為に長い名前をつけることを規定している。
すみませんが、質問です。 以下のプログラムが、RedHatだと動くのですが、Debianだと動きません。 コンパイルは通るのですが、コンソールに何も表示されないのです。 アドバイスをお願いします。 #include <iostream> #include <locale> int main(void) { std::locale::global(std::locale("ja_JP.eucjp"));//RedHatはUTF-8 std::wstring ws = L"これはw_char型のリテラル"; std::wcout << ws << std::endl; return 0; }
471 :
470 :2006/12/20(水) 00:14:48
ちなみに、charなら問題なく出力されます。 std::wstring ws = L"これはw_char型のリテラル"; std::wcout << ws << std::endl; std::string s = "これはchar型のリテラル"; std::cout << s << std::endl; -- 出力結果 -- これはchar型のリテラル w_charだけうまく行かないのです。
gccのバージョンは?
>>470 gccの-finput-charset, -foutput-charsetオプションをちゃんと
指定してないんじゃない?
無指定だとデフォはUTF-8らしいから、たまたまそれでUTF-8環境のRedHadで
ワイド文字リテラルが上手くエンコードされただけ、に見えるよ。
後は、wcout.imbue()は呼んでおいたほうがいいかもな。
規格上はどうだかしらんが、locale::global()だけでは、既に作成されてる
ストリームオブジェクトのロケールが変わらない実装もある。
474 :
473 :2006/12/20(水) 01:59:20
すまん。 × -foutput-charset ○ -fexec-charset な。
475 :
470 :2006/12/20(水) 02:15:38
ありがとうございます。今は環境がないので、明日試してみます。
>469 その、「寧ろ」がどう繋がってるのか解らない。 468は、広域変数の宣言と定義を単一ファイルですますことで 漏れをなくす目的で、変数名の長さとは直交した概念だとおもうが。
#define EXTERN派がしばしばコード量(≒タイプ量?)を問題にするからじゃないかな。
>>468 しないなぁ。
公開したくないグローバル変数もあるので、公開用のヘッダと非公開用のヘッダを
分けて作って、externは公開用だけに書く。
グローバル変数の定義はヘッダには書かない。
共通してる物を入れ子にすることはあるけど、非公開ヘッダは他のソースには
インクルードさせないし、公開ヘッダは自ソースではインクルードしない。
479 :
470 :2006/12/20(水) 14:19:08
ありがとうございます。Debian Sergeのg++は3.3だったので、新たにg++-3.4 を導入しました。 g++-3.4 -finput-charset=eucjp -fexec-charset=eucjp ソース 実行ファイル これでw_charが出力されるようになりました。 しかし今度は、char が出力されなくなってしまったのです。 std::locale::global(std::locale("ja_JP.eucjp")); std::wstring ws = L"これはw_char型のリテラル"; std::wcout << ws << std::endl; std::string s = "これはchar型のリテラル"; std::cout << s << std::endl; -- 実行結果 -- これはw_char型のリテラル charをw_charの前にすると、今度はw_charが文字化けします。 std::locale::global(std::locale("ja_JP.eucjp")); std::string s = "これはchar型のリテラル"; std::cout << s << std::endl; std::wstring ws = L"これはw_char型のリテラル"; std::wcout << ws << std::endl; -- 実行結果 -- これはchar型のリテラル S\214ow_char\213n蠧蜍 これは一体なぜでしょう?どうやったら解決できるのでしょうか? どなたかアドバイスをお願いいたします。
480 :
470 :2006/12/20(水) 14:21:15
補足です。 この現象は、RedHat上でもDebianと同様に起こっています。
>>479 RedHadではlocale, charsetオプションはutf-8なんだよね?
基本的な前提として
Debian環境ではLC_CTYPEはja_JP.eucjpでソースのエンコーディングもそうなってる
catで文字化けせずにソースを表示できる
RedHad環境ではUTF-8であることを除き、上と同じ
と思っていいかい?
482 :
470 :2006/12/20(水) 16:18:31
>>482 それで何で動かないかは、俺にはぶっちゃけわからんなぁ。ごめん。
とりあえずstringの中身を愚直に16進でダンプしてみては?
-fexec-charset
で指定された通りにエンコーディングされてるはずではあるのだが。
後は、cout.imbue()してみるとか、ベタにstdio使って
printf()での出力をしてみるとか。
484 :
470 :2006/12/20(水) 19:48:35
cout.imbue()はやってみましたが、ダメでした。 いろいろ試行錯誤してみます。ありがとうございました。
>>484 Linux板で聞いた方がいいかもわからんね
コンパイラ: Linux -> gcc Windows -> Visual C++ 6.0 質問: 1. Linuxでディレクトリの存在を確認する関数を知りたい。 2. Windowsでフォルダの存在を確認する関数を知りたい。 質問は以上の2つです。 よろしくお願いしますm(_ _)m
1.stat 2.FindFirstFile,FindNextFile,FindClose
>>487 WindowsはGetFileAttributesでおk
Winなら専用関数としてPathIsDirectoryってのもある 直感的だけど要IE
490 :
デフォルトの名無しさん :2006/12/20(水) 23:16:11
CまたはC++です。 開発環境はWin2000+VS.NET2003ですが、標準関数等の出来るだけ汎用的なものを希望。 うまく説明できないのですが、プログラムの実行時オプション、要はmain関数の引数を取得したいのです。 この辺の定番作業をやってくれる関数等はありませんか? あるとしたら、その使い勝手も添えていただければ幸いです。 別にwhileなりforなりで読み込めば済む話ですし、実際に自前で作ったものを使い回してるんですけどね。
>>490 NT専用でよければCommnaLineToArgvWがある
>>490 Unix系の定番はgetopt()だな。
Cランタイム(libc)の一部として提供されてることが多いが、GNUやBSDの
実装はそこらに転がってて手に入るはずだ(getopt.c, getopt1.c, getopt.h
といったファイル)。ただしライセンスには注意。
単に *.c みたいなワイルドカード展開したいという場合は、
単にsetarg.objとリンクしる。
argc, argvを展開後の形でセットされている。
493 :
490 :2006/12/20(水) 23:58:30
ありがとうございます。 色々と調べてみようと思います。
>>490 main関数の引数でいいだろ。
別にmainから始まるプログラムでもコンソール無しにできる。
495 :
490 :2006/12/21(木) 00:39:18
-a とか -b とかオプションがあって、かつ -abとかもOKとかにすると実装するの面倒じゃん(ぼそ
すまん、argc/argv程度のものを欲しているのかと思った。 Boost.Program_optionsなんてどうだろう?
497 :
490 :2006/12/21(木) 01:00:56
重ね重ね感謝デス。 getoptとBoost.Program_optionsあたりで少し遊んでみることにしますね。 納期まで時間あるし。
うぇw program_options構文きもいw
499 :
486 :2006/12/21(木) 17:47:49
>>487-489 ありがとうございます。
おかげで、丸一日かけて調べていたことが解決しました。
ところで、このスレは、ソースをアップして評価してもらうとかできますか?
できます。 そういうのが好きな奴等です。
テンプレートとマクロを使った変態的なコードなら、 喜んで読む奴等がたくさんいます。 あと複雑な型の宣言を人間コンパイラよろしく読む人もいます。
質問です。 DLLの遅延読み込みを使っています。 任意のタイミングで、特定の関数を呼ぶことなく、DLLの遅延読み込みを 行いたいのですが、可能でしょうか? win xp pro vs2005 sp1
二重積分ってどうかんがえればいいの? 簡単なヒントください>< それと1週間前にC++始めました。
C++と関係ない
>>502 LoadLibrary使えばよいのでは?
>>503 まずどの空間上での積分なのか、そしてルベーグ積分なのかリーマン積分なのか、
その辺の仮定から話してもらおうか
君がいってるのは代数の言葉で言えば 「計算ってどう考えればいいの?」 ということと同じ。計算が和なのか積なのかそれさえはっきりしない。 仮定の曖昧な質問は答えようがない
答えられない奴は書かなくていいよ。邪魔だから。
注.:.私.の.有.意.義.な.発.言.に.対.し.、.自.分.の.理.解.不.足.を.棚.に.上.げ.煽.り.、.1.行.レ.ス で.返.す.方.が.多.い.よ.う.で.す.が.、.そ.の.よ.う.な.方.は.ス.レ.の.皆.様.を.混.乱.さ.せ.る.だ.け.で.な.く ス.レ.の.雰.囲.気.を.崩.し.か.ね.な.い.の.で.お.黙.り.下.さ.い.。 ま.た.質.問.者.は.回.答.者.に.知.識.を.披.露.す.る.場.を.与.え.る.貴.重.な.存.在.な.の.で.、 質.問.者.を.見.下.し.た.回.答.、.あ.ま.り.に.も.儀.礼.を.欠.い.た.回.答.も.厳.重.に.禁.止.い.た.し.ま.す.。 忙.し.い.中.、.少.な.い.時.間.の.合.間.を.縫.っ.て.質.問.し.に.来.て.る.わ.け.で.す.の.で.、 そ.の.辺.ご.承.知.下.さ.い.。.な.お.、.当.方.が.質.問.に.対.し.て.有.意.義.な.答.え.で.あ.る.と 判.断.し.た.方.に.は.評.価.い.た.し.ま.す.の.で.各.自.よ.く.調.べ.、.よ.く.考.え.正.確.な.回.答.を.す.る.よ.う.に.。
難しい単語を並べて結局質問に答えないのは厨房
>>503 スレ違いだし数値積分のアルゴリズム知りたいなら本調べろ
ライブラリとソースをググレばいいだけ。 はい次。
ググっても出てきません。やり方を教えてください。 知らないのなら書かなくて結構で宇。
初心者です。cygwinでC++言語の勉強はじめました。 flockが今ひとつ、わからないんですが質問させてください。 下のプログラムで 1、@があると出力は、"ここ" 2、@がないと出力は "ここ:whileに入れました:hogehoge" になります。 どちらも!finのエラーはないので、fin.open("hoge.txt"); ではオープンできてるみたいなのですが、 2、ではgetlineでなにも読めていないようで不思議です。 なんだか、自分でロックして自分が読み込めなくなってるんですが。。。 ロックしてから、読み込んで、表示ということがしたいです。 どのように修正すればよいのでしょうか。 -------------------------------------------------- #hoge.txtの内容:"hogehoge" プログラム: // #include <iostream> <fstream> <string> int n = open("hoge.txt",O_RDWR); flock(n,LOCK_EX |LOCK_NB);//・・・@ std::ifstream fin; fin.open("hoge.txt"); if(!fin){ printf("err:fin");} std::string s; printf("ここ"); while(getline(fin,s)){ printf(":whileに入れました:"); std::cout << s << std::endl; } close(n);
>>515 そら、flock()してるんだからダメだわ。
ttp://bd.tank.jp/diary/20061020.html あたりを見てみ。
ifstreamのコンストラクタにfdやFILE*渡せる実装もあるんで、
その場合は楽なんだが、
gccの場合はその手は使えないようだな。
一般的なworkaroundはどうやら存在しないようだ。
stdioのようにfdopen()やらfileno()を使えないってのは実に不便だな。
つうか糞。
なお、できればflock()よりはlockf()使っとけ。
BSD由来のflock()よりは、後者のが標準的な関数だから。
>>516 詳しく説明していただきありがとうございました。
cygwinのgcc新しくしたら、stdio_filebuf.hがありました。
それで、リンク先のようにしたら、きちんと動きました。
ほんと助かりました。
ありがとうございました。
>>516 ストリームバッファクラスを自作すると言うのは、この問題に対する一般的な解法と言えるのでは?(面倒ではあるが)
ファイルディスクプリ多に限らず、究極的にはどんなものでも読み書きできるようになる。
Boost.Iostreamsを使えば多少はストリームバッファを書くのが楽になる。
STLport使えばいいじゃん。
インライン関数って普通ヘッダファイルに記述しますが、 他のファイルから参照されない関数(privateとか)もヘッダじゃないとダメなんですか。
いいえ。
printf関数で printf("%.[precision]s", ...); ↑ ここ に変数を指定することはできないのでしょうか。 int num; printf("%.nums", ...); のような感じにしたいのですが・・・。
>>522 printf("%*s",nums,str);
プログラミング言語:C コンパイラ: Linux -> gcc-3.3.2 Windows -> Visual C++ 6.0 質問: 1. Perlのchompと同じ機能を持った関数を知りたい。 2. 文字列中の英大文字を英小文字に変換する関数を知りたい。 質問は以上の2つです。 LinuxとWindowsで別の場合は、両方教えて貰えると助かります。 よろしくお願いしますm(_ _)m
>>524 1. 標準関数にはない
2. tolower
Visual C++ 2005 express使っています。 下記のコードを実行した場合、 ★印の箇所でppを設定しなおさなないで 次の行のeraseで削除しようとすると、 ↓のようなダイアログが出て止まってしまいます。 この場合、vt1.insert(pp, 99); で99を挿入した後、 ppは次の要素の反復子になると思うのですが、 間違っているでしょうか? あと、vt1.erase(pp);もppの指している要素を削除した後は、 次の要素を指すので、 vt1.erase(pp); vt1.erase(pp); と続けて削除することも出来ると思うのですが、 これも誤りでしょうか?(これも同じダイアログが出てしまいます。) -+-+-+-+-+-+-+-+-ダイアログ内容+-+-+-+-+-+-+-+-+-+-+-+-+ Microsoft Visual C++ Debug Libraly Debug Assertion Failed! Program:... File: c;\program files\microsoft visual studio 8\vc\include\vector Line:986 Expression: vector erase iterator outside range -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/******************プログラム*******************/ #include <iostream> #include <vector> // for vector using namespace std; void disp_vec(vector<int> &obj); int main() { int i; vector<int> vt1; // 長さ0のint型のvector vector<int>::iterator pp; // 反復子 cout << "-----サイズが拡張されることを確認\n"; for (i=0; i<5; i++) // 値を設定する vt1.push_back(i+100); disp_vec(vt1);//一覧表示 pp = vt1.begin(); cout << "pp = vt1.begin() -> *pp = " << *pp << '\n'; vt1.insert(pp, 99); pp = vt1.begin()+1;// ←ココ★ vt1.erase(pp); disp_vec(vt1);//一覧表示 return 0; }
void disp_vec(vector<int> &obj) // コンテナを出力 { for (int i=0; i<obj.size(); i++) cout << obj[i] << " "; cout << '\n'; } /*****************************************************/
>>526 >この場合、vt1.insert(pp, 99); で99を挿入した後、
>ppは次の要素の反復子になると思うのですが、
>間違っているでしょうか?
ええ
>>526 >あと、vt1.erase(pp);もppの指している要素を削除した後は、
>次の要素を指すので、
> vt1.erase(pp);
> vt1.erase(pp);
>と続けて削除することも出来ると思うのですが、
>これも誤りでしょうか?(これも同じダイアログが出てしまいます。)
ええ
>どう直せばいいのでしょうか? ええ
>>526 挿入・削除を行うと反復子は無効になる。
メンバ関数が返す新しい反復子を使え。
>>532 無効になるんですね。
これは、vectorの場合に限定されているんですか?
listだと、insertの場合に出来ます。★印 listだと、insertの場合に出来ます。★印 #include <iostream> // cp_list1.cpp [cpp] #include <list> // for list using namespace std; void disp_list(list<int> &obj); int main() { int i, idt; list<int> tt1, tt2, tt3;// 長さ0のint型のlist list<int>::iterator pp, p1, p2; // 反復子 list<int>::reverse_iterator rp; // 逆反復子 cout << "-----要素を後ろに入れる\n"; for (i=0; i<5; i++) tt1.push_back(i+100); cout << "-----要素を途中に入れる\n"; pp = tt1.begin(); for (i=1; i<=5; i++) ++pp; // ppを5つ進める
for (i=0; i<5; i++){ tt1.insert(pp, i+300); // 挿入後にppは1つ進む // ←★これは出来る!! } cout << "-----tt1の長さと内容\n"; cout << "tt1の長さ=" << tt1.size() << '\n'; for (pp = tt1.begin(); pp != tt1.end(); pp++) { cout << *pp << " "; } cout << '\n'; return 0; } void disp_list(list<int> &obj) { list<int>::iterator wp; for (wp = obj.begin(); wp != obj.end(); wp++) { cout << *wp << " "; } cout << '\n'; }
>>533 正確には、std::vectorは、
・挿入または削除を行うとそれ以降の要素を指す反復子は無効になる。
・挿入を行った場合再割り当てが起こると全ての反復子は無効になる。
よって、挿入は反復子が必ず無効になり、削除はそれ以降の反復子が
無効になると覚えておけばよい。
挿入・削除によって反復子が無効にならないのはstd::listのみ。但しerase
メンバ関数によって反復子の位置の要素を削除した場合は、その次の
要素を指す反復子を返す。insertメンバ関数は三種類あるが、その内の
一バリエーションのみが新しい要素を指す反復子を返す。
c++builder環境のwinsock2でネットワークプログラミングしてます。 受信のタイムアウト処理するために、selectを使おうと下のコード のようにしました。 //変数の値は下のようにしました。 fd_set fds; FD_ZERO(&fds); FD_SET(fd,&fds); struct timeval time; time.tv_sec = 10; time.tv_usec = 0; select無い場合は普通に受信できるプログラムの中で selectを呼び出すと必ず-1(エラー)が返ります。 ためしに、ShowMessage(select(fd + 1,&fds,NULL,NULL,time)); をいろんな場所で実行してみましたが、すぐに全部-1が表示されました。 違うselectが呼び出されたか、引数がおかしいかぐらいと思うのですが、 何かお気づきの点などありますでしょうか。 よろしくお願いします。
>>538 基本的にはバッチシおk
デバッグ用とは思うけど、printf や puts を埋め込むと使いにくくなる
isupper は必要ない
>>538 大きな問題はとくにない。
強いて言うなら、関数内に表示処理を入れてるけど、汎用性がなくなるし、それはやめといたほうが無難
isupperはなくても大丈夫。ついでにdo whileを使うよりも素直に
for(;*string;++string){
*string = tolower(*string);
}
とかのほうが読みやすい。
>>538 overwrite_linefeed()がPerlのchomp()と同じかどうかっつーと微妙だな。
結局、改行が途中にあった場合にどうしたいかによるんだが。
overwrite_linefeed()は最初に見つけた改行以降を切り捨てるよな。
chomp()は文字列「末尾」が改行なら切り捨てるって仕様じゃなかったっけか?
まぁ、実際にはctime()やfgets()の返してきた文字列(改行が末尾にあることが
分かっている)に使うことが多いんだろうから、どっちでもいいっちゃ
いいんだろうが。
それと、これはささいだが、戻り型をvoidではなくchar*として、
のように、文字列の引数を戻り値としても返すように作っとくと、
printf("%s", chomp(s));
みたいなノリで使えるので、やや使い勝手が向上する。
int mainって戻り値指定しなくてもいいんだな 初めて知った
542の書いたことは、C99とC++だけに当てはまる。 C89なんかだと543の言うとおりごみになる。
>>543-544 おう、そうなのか
基本的にC++だけど、捨てコードでも省略したことなかったから地味にうれしい発見だ
>>547 selectでもいける
たいした手間じゃないしWSAAsyncSelectも試してみたら?
お返事ありがとうございます。 ふむ〜。 selectでも大丈夫でしたか。 "hoge"って文字列を送信して、 タイムアウト受信でその文字列"hoge"を受信するだけで、 select無いときは、普通に受け取れるんですよね。 WSAAsyncSelectを試したり、 もう一回コード見直してみます。 なにかあったら、またよろしくお願いします。
ども。
>>538 です。
>>539-541 悪いところの指摘、アドバイスなどありがとうございます。
>デバッグ用とは思うけど
orz
そんな意図は全く無く、ただ進捗状況として出力させています。
この場合だと、main関数の方に持っていけってことでオッケーですか?
>printf や puts を埋め込むと使いにくくなる
>関数内に表示処理を入れてるけど、汎用性がなくなる
初級者にはビンとこないです。まだまだ経験が足りないということですね。
>isupper は必要ない
>isupperはなくても大丈夫。
これに関しては、手元にある参考書に
「変換できない場合、古い処理系において引数とは異なる値を返すことがある」
とあったので、isupperで英大文字かをチェックしてから、英小文字に変換する仕様にしました。
太古の事は気にすることは無いですか?
>do whileを使うよりも素直に
>for(;*string;++string){
> *string = tolower(*string);
>}
>とかのほうが読みやすい。
個人的な好みで、for文は「初期化」、「ループの継続条件」、「カウンタ変数の更新」の
3つある場合のみ使うようにしています。
私の場合は、どれか1つでも欠けると読みにくくなるので、do while文を使っています。
あと、何かでfor文よりもwhile文の方が高速と見た覚えがあるのですが、その辺はどうなんでしょうか?
ども。
>>538 です。
連投すんません。
>overwrite_linefeed()がPerlのchomp()と同じかどうかっつーと微妙だな。
私もそう思ったので、Perlのchomp関数に失礼の無いように、違う関数名しました。
>overwrite_linefeed()は最初に見つけた改行以降を切り捨てるよな。
>chomp()は文字列「末尾」が改行なら切り捨てるって仕様じゃなかったっけか?
chomp関数の詳細な仕様がわからなかったので、苦し紛れでそういう仕様にしました。
>>541 さんの意見を参考に、「'\0'の前にある'\n'を上書きする」というように仕様を変更しようと思います。
/* '\0'を検索 */
position = strchr(string, '\0')
if(*(--position) == '\n'){
/* '\0'の前にある文字が'\n'の場合 */
/* 上書き */
*position = '\0';
}
こんな感じでどうでしょうか?
>それと、これはささいだが、戻り型をvoidではなくchar*として、
>のように、文字列の引数を戻り値としても返すように作っとく
参考に…、というよりパクらせてもらいますm(_ _)m
ども。
>>538 です。
さらに連投で、長々とすんません。
>>542 >int mainって戻り値指定しなくてもいいんだな
orz
コンパイラが警告さえも出してくれなかったので、すっかり忘れていました。
return EXIT_SUCCESS;
ってやるために<stdlib.h>読み込んでいたのに・・・。
>>543-545 まさに、「ひょうたんからこま」。
勉強になりましたm(_ _)m
//
>>551 // 単純にstrrchr(string, '\n')で見つかったところにナル文字を書けばいいじゃん。
const char * overwrite_linefeed(const char * string)
{
char * position = strrchr(string, '\n');
if (position) * position = '\0';
return string;
}
// おまけ
bool search_and_report_linefeed(const char * string)
{
bool isFound = strchr(string, '\n');
printf("`\\n'%s.\n", isFound ? "を発見しました" : "は発見できませんでした");
return isFound;
}
554 :
553 :2006/12/24(日) 14:51:22
いけね。overwrite_linefeed()の引き数と戻り値はconst付けじゃダメだった。
char str[10] = "abcdefg"; などとしたとき、[defg]だけを出力はできないのでしょうか。 printf("%.*s",4,str[3]); とすると動作してくれないのはなぜでしょうか。
printf("%.*s",4,str+3);
printf("%.*s", 4, & str[3]);
558 :
デフォルトの名無しさん :2006/12/24(日) 16:35:58
>>550 isupperの件。
今時のパソコン上ではANSI/ISOにも従っていないような実装なんて考えなくて良い。
windows使ってるとやたらwchar_t出てくるんですけど、 これってlinuxでも使えるんですか?
使える。 wchar_tはC/C++で(性格こそ異なれど)共に標準に含まれている。 ただし、標準では少なくともcharと同じと定められているだけで、具体的にその大きさなどは定められていない。 たとえばWindowsではUTF-16(古いものではUCS2)だが、LinuxではUCS4(もしくはUTF-32)となっている。
562 :
560 :2006/12/24(日) 19:33:22
ども。
>>538 です。
>>553 orz
ナル文字を検索する方法を考えているときに、前から検索するか、
後ろから検索するか迷っていたのに、改行を後ろから探すという発想が全く無かった。
ところで、ナル文字の後ろのゴミに改行が混じっている可能性はないのですか?
三項演算子使う方法は良いですね。
パクらせてもらいますm(_ _)m
ども。
>>538 です。
>>559 回答ありがとうございます。
>今時のパソコン上ではANSI/ISOにも従っていないような実装なんて考えなくて良い。
了解しました。
プログラミング言語:C コンパイラ: Linux -> gcc-3.3.2 質問: fgets(buffer, 5, stdin)で、1234567890を読み込んだ場合、 もう一度入力をさせるプログラムを作りたいのですが、 1234がbufferに読み込まれ、567890はstdinに残ったままになっているようで、 うまく処理ができません。 stdinに残っている値を処理する良い方法はないでしょうか?
GCCでそれはねーだろ 一番確実なのは while (getchar() != '\n') ;
>>566 そんな鼻から悪魔が出そうなコードを注意点なしに書くのはどうかと。
こうか if (buffer[strlen(buffer)-1] != '\n') { while (getchar() != '\n') ; }
VS2005とかだと strcatはセキュリティーなんのでワーニングになるので 全部strcat_sとかに変えたんですが、 これってlinuxでも通るんですか?
571 :
566 :2006/12/25(月) 00:05:09
すまん。コンパイラ依存なコードだったんだな。 鼻から悪魔が出てくるのは勘弁してくれ。
コンパイラ依存って言うか、知る限りではLinuxじゃ無理
>>570 そいつはMS独自の早漏Safer Cだからよしなさい。
C++/CLIのためらしいね。C/C++標準に取り込まれるかどうかは不明。
>>573 ありがとうございます。
マジすか、じゃぁwarning無視した方がいいんですね。
セキュリティーの話はよく分からないのですが、
クラックに弱くなるんでしょうか。
命令の実行権限うんぬんがどうとか・・・。
単純にバッファサイズ間違えるとメモリが破壊されてしまう
可能性があるってだけですかね?
回答者の質に問題あり
どういう風に問題があるのか訊ねたら 「どうすればそれを答えずに切り抜けられるか」 に必死になりそうだからやめておこう
578 :
553 :2006/12/25(月) 05:04:58
>>563 ナル文字の後のことなんか知ったこっちゃない。
つーか、strrchr()にしたところで文字列終端をナル文字で判断するんだから。
標準関数でナル文字の後に意味をもたせるのはstrtok()の使い方だけだ。
テキストファイルから一行stringクラスへ読み込んで、 その中の半角スペースを除去する処理を組んでいるのですが、 ファイルの中ほどまで読み込んだ辺りで例外が発生してしまいます。。。 下記のようなコードで処理をしているのですが、なにか問題があるのでしょうか? ifstream ifs; string str; string::iterator its; ifs.open("file"); /* ファイルオープン */ while (!ifs.eof()) { /* ファイルエンドまで読み込み */ ::getline(ifs, str); /* 一行読み込み */ for (its = str.begin(); its != str.end(); its++) { /* 文字列終端まで */ if (' ' == *its) { /* 半角スペースを検索 */ str.erase(its); /* 消去 */ } } } }
>>579 eraseしたらイテレータは無効になるんじゃなかったっけ?
Effective STLの9項だな。 for行の最後のits++をやめて、 if (*its == ' ')なら its = str.erase(its);、elseを用意してその中では ++its; これでうまくいくはず。 要は、イテレータはeraseで無効になるが、新しい有効なイテレータをeraseがくれるということ。 mapにも別のやり方がある。興味があるなら自分で調べれ。
str = (char *)malloc(1000) とかで、メモリを確保をしようと思うんだけど、 ↑でいう1000って、1000byte確保って事でいいの?
たった今20秒という大量の時間をかけて mallocでぐぐって一番上に出てきたページを見たところによれば 1000byte確保ってことでいいようです。
すみませんが、質問です。 delete と delete[] を使い分けなければならない理由はなぜでしょうか? 単独のdeleteはポインタの指すアドレス1つ分しか解放しないそうですが、 それなら毎回delete[]を呼べば済むような気がします。 delete[]はどのようにして解放すべき領域を知るのでしょうか?
非常に初歩的な質問で恐縮です。
(2行目以降の)チーム名のみstrng型で、他はint型変数に格納したいです。
しかし、106行目や114行目の
fin >> iRank;
fin.get( chGetbyte );
で、ファイルから読み込めないのですが、
どこに誤りがあるのかがわかりません。
分かる方、ご意見、ご指摘お願いします。
順位,チーム名,試合数,勝数,引分数,敗数,得点,失点,得失点差,勝点
1,浦和レッズ,34,22,6,6,67,28,39,72
2,川崎フロンターレ,34,20,7,7,84,55,29,67
3,ガンバ大阪,34,20,6,8,80,48,32,66
17,セレッソ大阪,34,6,9,19,44,70,-26,27
18,京都パープルサンガ,34,4,10,20,38,74,-36,22
環境は、Visual Studio C++ 2005 Express editionです。
↓に現在のソースをアップしました。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.cgi?mode=thr&no=3276
>>584 new/deleteでは常に1つずつしかオブジェクトを生成・破棄しない。
しかしnew[]は1度に何個オブジェクトを作るかわからない。
だから、多くの実装ではnew[]のときにオブジェクトを何個作ったかを記録する分余計にメモリを確保して記録している。
delete[]はそれを読み取って消すべきオブジェクトの数を知ることになる。
そういう余分な処理を作るとき・消すときに行うかどうか有無があるので、new/deleteとnew[]/delete[]は分かれている。
587 :
584 :2006/12/25(月) 18:07:33
>>586 ありがとうございます。
> 多くの実装ではnew[]のときにオブジェクトを何個作ったかを記録する分余
> 計にメモリを確保して記録している。
この記録の方式は実装依存ということなのでしょうか?
『Accelerated C++』のP184に、
「(new[]で)配列が破棄されるときには、各要素が逆順に破棄されます。」
とあったので、何か決まりがあるように思ったのですが。
>>587 その引用を見る限り、破棄される順番については言及されているが、個数に関しては言及されていないね。
589 :
565 :2006/12/25(月) 20:15:50
げ、俺もずっと疑問系だと思ってた
アレがCore2の性能が悪化する例?SSEでやれよ。
誤爆したゴメ
興味あるので何処の誤爆か教えてくれ
>>585 直すのめんどいからとりあえず動くようにだけしとく
fin.eof()のポイントはタイミング
--- 3276.txt.orig2006-12-25 22:54:51.000000000 +0900
+++ 3276.txt2006-12-25 23:07:06.000000000 +0900
@@ -2,6 +2,7 @@
#include <string>
#include <fstream>/* ファイルの入出力 */
#include <conio.h>/* getch */
+#include <sstream>
using namespace std;
#include "Class_Club.h"
enum enTableItem { Rank, Name, Game, Win, Draw, Lose, ForGoal, AgainstGoal, DiffGoal, WinPoint ,Inbalid };
@@ -92,9 +93,11 @@
}
/* ファイルの末尾まで繰り返し */
-while ( !fin.eof() )
+string linebuf;
+while ( getline (fin, linebuf) )
{
strInLineBuf = cInLineBuf;
+istringstream fin (linebuf);
/* 1行単位で、順位,チーム名,試合数,・・・を抽出 */
for ( iItemCnt = 0 ; iItemCnt < Inbalid ; iItemCnt++ )
@@ -109,12 +112,8 @@ case Name : strName.clear(); chGetbyte = 0; -while ( chGetbyte != ',' ) -{ -fin.get( chGetbyte ); -strName += chGetbyte; -} -fin >> chGetbyte;/* カンマ(',') */ +for (fin.get( chGetbyte ); chGetbyte != ','; fin.get( chGetbyte )) + strName += chGetbyte; break; case Game : fin >> iGame; @@ -146,7 +145,6 @@ break; case WinPoint : fin >> iWinPoint; -fin >> chGetbyte;/* 改行('\n') */ break; } }
Cで最も簡単なウィンドウ(最大化・最小化・閉じるのボタンを装備のみ)を作るのは どうやったらできるんですか? 環境はwindows
ぐぐればすぐできる。
猫でもできる でググれ
>>597 C++Builder起動して新規作成>アプリケーション選択してからF9
601 :
585 :2006/12/26(火) 16:46:59
>>595 助かりました。
ソースを変えて動作確認してから
間違っていたところとか見て勉強になりました。
感謝します!!
>>601 boost::tokenizerとboost::lexical_cast使うともっと綺麗に書けるよ
string linebuf;
while ( getline (fin, linebuf) )
{
/* 1行単位で、順位,チーム名,試合数,・・・を抽出 */
typedef boost::tokenizer <> Tokenizer;
Tokenizer tokenizer (linebuf);
for (Tokenizer::const_iterator itr (tokenizer.begin ()),
last (tokenizer.end ()); itr != last;)
{
iRank = boost::lexical_cast <int> (*itr ++);
strName = *itr ++;
iGame = boost::lexical_cast <int> (*itr ++);
iWin = boost::lexical_cast <int> (*itr ++);
iDraw = boost::lexical_cast <int> (*itr ++);
iLose = boost::lexical_cast <int> (*itr ++);
iForGoal = boost::lexical_cast <int> (*itr ++);
iAgainstGoal = boost::lexical_cast <int> (*itr ++);
iDiffGoal = boost::lexical_cast <int> (*itr ++);
iWinPoint = boost::lexical_cast <int> (*itr ++);
}
/* 読み取ったものを表示 */
...
}
これは酷い・・・
確かに意味はすぐにくみ取れるようになってると思うが、 こうしてみると汚いにも程があるなw
これだからBoost厨は……、って言われるじゃないか。
606 :
579 :2006/12/26(火) 19:59:08
>>580 さん
>>581 さん
仕事でここ見る暇もありませんでした。
お礼が遅れまして申し訳ございません。
回答ありがとうございました。
eraseの行を変更して上手く動くようになりました。
オブジェクト指向を理解できてない見本みたいなプログラムだな
609 :
デフォルトの名無しさん :2006/12/27(水) 18:27:36
Mac OS X 10.4.8を使っているのですが、 __Z11getpriorityii __Z11setpriorityiii なんていうC++(?)のマクロはどこにあるんでしょうか・・・? ググっても1件も載ってなかったので・・・
おそらくそれはC++コンパイラが名前変形 (name mangling)を施した後の名前。
>>609 $ man setpriority
したららしきものが出てきたよ
BSDのシステムコールかこれ?
>>608 俺は
>>603-605 ではないが、俺ならこんなのはscanf()使うな。
stdin以外を処理したけりゃfreopen()使うなりfscanf()で。
char buff[1024];
while (scanf("%d,%1023[^,],%d,%d,%d,%d,%d,%d,%d,%d",
&iRank, buff, &iGame, &iWin, &iDraw, &iLose, &iForGoal,
&iAgainstGoal, &iDiffGoal, &iWinPoint) == 10)
{
strGame = buff;
....
}
>>612 でも
buffのサイズを超えるものだったらまずくない?
>>613 >>585 の仕様を見る限り、そこまでの汎用性はどう見ても求めてられないだろ。
>>612 のコードは、一応バッファオーバーランは起きないようにしてある品。
汎用のコードにするんなら、クウォートや文字列中のカンマにも
対応すべきだろう。チーム名が1024文字以上になるよりは、カンマが
入り込んでくることの方が、ずっとありそうなことだ。
まーこんなゴミみたいな仕事はサクッと片付けるべきだと俺は思うね。
本来C++使うのも馬鹿馬鹿しい仕事だが。
615 :
デフォルトの名無しさん :2006/12/27(水) 23:56:55
初歩的な質問ですいません。 そもそもC言語とC++の違いってなんですか?? こっちだとこういうメリットがあるっていうのが知りたいんですが。
ソースコード全体がプログラムになっているかどうかを判定するようなプログラムって、 どうやって作るんですか? そういうプログラムのことを何か特別な名前で呼びますか?
617 :
566 :2006/12/28(木) 00:12:24
変なハンドル出たorz
>>615 C++はCにクラスやテンプレート等、色んなものをくっつけて強化した言語。
以前はほぼCの上位互換だったが、最新のCの仕様(C99)で互換性は失われた。
特徴は
C: シンプルだが何でもプログラマ任せ
C++: 複雑だが強力
ってとこかな。
FORTRANはF77準拠の処理系が現役だったりするわけで、別に最新規格じゃないといけないわけじゃないし どうせC++も次の規格でC99を踏襲してくるだろ。 つか、仕事で未だにVC++6.0使ってるんだが
>どうせC++も次の規格でC99を踏襲してくるだろ。 それは無い。進行中のドラフト見てみろ。
しかしsnprintfが入るのはありがたい ・・・VCの_snprintfが空気読んでないからな
無いのか。。。。 MS擁護になるけど、 _s付きの関数は標準ライブラリに取り込んで欲しいよなぁ
セキュアCRTが今までなかったのに驚かされるな けど標準入りは今のところ微妙だなぁ・・・
ぶっちゃけさっさとCなんぞ捨ててC++に移行しろ、というMSの声に 聞こえなくも無いw
その前にAPIをC++化しろ
>>626 C++はABIが複雑すぎるからダメ(C++専用になっちゃう)
そのせいでCOMが策定されますた
今は.NETの時代です
んでも、WinFXの構想は既に半コケですネ
以上
>>626 ネームマングリングされたAPIなんて嫌すぎます。
>>628 想像して、飲んでる途中のホットミルクカップに戻しちまった('A`)
xxxAやxxxW、xxxExAやxxxExWはおk?
cygwinでC++についての質問です 以下のソースでgetでのcoutが-1になるのは何が原因なのでしょうか? #include <iostream> #include <fstream> using namespace std; void get(ifstream &is) { char tmp[4]; is.read(tmp, 4); cout << is.tellg() << endl; } int main(int argc, char *argv[]) { ifstream ifs(argv[1], ios::binary); ifs.seekg(4, ios::beg); get(ifs); return 0; } 開くファイル 53 54 42 31 EB 36 00 00
>>631 std::ios::failbitが立っている時のtellg()が返す値は無意味。
633 :
609 :2006/12/28(木) 12:42:09
>>633 Mac OS X のことは知らないが、
VineLinux なら /usr/include/sys/resource.h にあった。
下のコマンドうってみては?
grep priority /usr/include/*.h
grep priority /usr/include/sys/*.h
>>633 find /usr/include | xargs grep priority
include ファイルを調べるのではなく、 リンカへのオプションでライブラリ追加しなきゃいけない希ガス
structA* a = new structA();とstructA* a = &structA();は 同じことなのでしょうか?
右きめぇ
win32アプリケーションで作成中のエラーです ------ ビルド開始: プロジェクト: message, 構成: Debug Win32 ------ コンパイルしています... ModelMain.cpp c:\c++練習\sample\sec02\modelapp\modelmain.cpp(27) : error C2440: '=' : 'const char [9]' から 'LPCWSTR' に変換できません。 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 c:\c++練習\sample\sec02\modelapp\modelmain.cpp(44) : error C2664: 'CreateWindowExW' : 3 番目の引数を 'const char [24]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照) 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 c:\c++練習\sample\sec02\modelapp\modelmain.cpp(58) : warning C4244: 'return' : 'WPARAM' から 'int' への変換です。データが失われる可能性があります。 ビルドログは "file://c:\C++練習\message\Debug\BuildLog.htm" に保存されました。 message - エラー 2、警告 1 ========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ========== 参考書を見てまったく同じように打ったのにエラーが出てしまいます このエラーの意味と解決方法を教えていただきたいです コードは長いんですが張ったほうがいいんですかね・・・ 78行あるので貼れないと思いますけど
>>641 想像だが、多分君の環境ではUNICODEが定義されてるんだろうな。
んで、サンプルはUNICODEが定義されていないことを改定している。
本来、TCHARを使うべきところでcharなんぞを使ってる時点で
そのサンプルは糞だが、
プロジェクトのプロパティで
ユニコードではなく「マルチバイト文字セットを使用する」ように
設定してやればいいはずだ。
次からテンプレにいれとくか
>>642 Visual C++ 2005 Express Editionを使用しています
サンプルはプログラマ養成入門講座 Visual C++@と言う本のコードです
今書き込んだあと一度プロジェクトを削除してもう一度やろうとしてみたんですが
プロジェクトを作成しようとしてアプリケーションウィザードを開くと白くなり
その先に進めずプロジェクトが作れなくなってしまいました・・・
Platform SDKをさっき入れていろいろ設定いじったのでどこか間違えたのかもしれません・・・
2005からデフォルトでUNICODEだから とりあえずソースファイルの一番先頭(一行目)に #undef _UNICODE って入れてからまたコンパイルしてみ
原因がわかりました XML 解析中に次のエラーが発生しました: ファイル: C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults\CoreWin_Express.vsprops 行: 10 列: 1 エラー メッセージ: 修飾名の文字が無効です。 ファイル 'C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults\CoreWin_Express.vsprops' を読み込めませんでした。 システム プロジェクトの既定のファイル 'C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults\CoreWin_Express.vsprops' を読み込めませんでした。 このファイルのインストールなしでプロジェクトを読み込むことができません。 製品を再インストールしてください。 XML 解析中に次のエラーが発生しました: ファイル: C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults\CoreWin_Express.vsprops 行: 10 列: 1 エラー メッセージ: 修飾名の文字が無効です。 ちょっとサイトのほうでもう一度確認してきます。
>>645 環境が明記されてるし、プロジェクトのプロパティで UNICODE のチェックを外すほうが良いのでは?
CoreWin_Express.vspropsは<tool/>の/>を誤って消していたのが原因でした
ソースの1行目に#undef _UNICODEを入れて見ましたが同じくエラーが出ました・・・
>>647 のチェックを外すというのは
UNICODE 応答ファイルの使用を いいえ にすると言う事ですよね?
同じくエラーが出ました
c:\c++練習\sample\sec02\modelapp\modelmain.cpp(28) : error C2440: '=' : 'const char [9]' から 'LPCWSTR' に変換できません。
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
c:\c++練習\sample\sec02\modelapp\modelmain.cpp(45) : error C2664: 'CreateWindowExW' : 3 番目の引数を 'const char [24]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照)
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
c:\c++練習\sample\sec02\modelapp\modelmain.cpp(59) : warning C4244: 'return' : 'WPARAM' から 'int' への変換です。データが失われる可能性があります。
ビルドログは "file://c:\C++練習\message\Debug\BuildLog.htm" に保存されました。
message - エラー 2、警告 1
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
[全般]の文字セットだよ
>>649 勘違いしていました・・・
マルチバイト文字セットを使用するを選んだところ
------ ビルド開始: プロジェクト: message, 構成: Debug Win32 ------
リンクしています...
MSVCRTD.lib(crtexe.obj) : error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。
C:\C++練習\message\Debug\message.exe : fatal error LNK1120: 外部参照 1 が未解決です。
ビルドログは "file://c:\C++練習\message\Debug\BuildLog.htm" に保存されました。
message - エラー 2、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
少しエラーが変わりました
設定なしでも同じでした
WinMainから始まるコードなら [リンカ]-[システム]-[サブシステム] をWindows (/SUBSYSTEM:WINDOWS)にする そうでないならワカンネ
>>651 ------ ビルド開始: プロジェクト: message, 構成: Debug Win32 ------
コンパイルしています...
ModelMain.cpp
c:\c++練習\sample\sec02\modelapp\modelmain.cpp(59) : warning C4244: 'return' : 'WPARAM' から 'int' への変換です。データが失われる可能性があります。
リンクしています...
マニフェストを埋め込んでいます...
ビルドログは "file://c:\C++練習\message\Debug\BuildLog.htm" に保存されました。
message - エラー 0、警告 1
========== ビルド: 1 正常終了、0 失敗、0 更新、0 スキップ ==========
正しい値が入らないみたいですが実行可能でした
とりあえずこれで次に進めるのでこのままで行きたいと思います
ありがとうございました。
>>627-628 GDI+のネイティブ版<gdiplus.h>のように、
DLLはCリンケージの関数を公開するがヘッダでC++クラスを使ったAPIを提供するという手もある。
言語:C コンパイラ:Visual Stdio C++ 状況: PathIsDirectory関数を使うために、shlwapi.libをリンクに追加して、 #include <shlwapi.h>をソースに追加したら、 shlwapi.hに関するエラーが約200出た。 質問: PathIsDirectory関数は、Cでは使えないってこと?
プログラミング関係でファーザーっていう用語あります? ぐぐっても出てきませんが。
>>655 father?
どんな場面で出てくるの?
657 :
質問1/2 :2006/12/28(木) 22:27:34
超初心者的で申し訳ありませんが、質問をさせていただいてよろしいでしょうか。 質問内容は、サブクラスsubAで継承した関数subA.funcを使ったとき、 ベースクラスAでもともと定義されている関数A.funcに参照渡しされている引数class Aの代わりにサブクラスsubAを使えるかと言うことです。 簡単なコード例を書きますと、以下のような使い方はできるか、ということです。 class A { public: double a; double b; double func( A& AObj ); }; double A::func( A& AObj ) { double z = 0.0; z = AObj.a + AObj.b; return z; } class subA : public A { public: double c; }; int main () { subA suAObj; suAObj.a = 1.0; suAObj.b = 2.0; subA.func( suAObj );
実際、VC++2005でコンパイルしてみましたところ、 error LNK2019: 未解決の外部シンボル "public: double __thiscall A::func(class A,double)"?(・・・・・・)が関数 _main で参照されました。 とのエラーメッセージが出るのでおそらくは駄目なのでしょうが、この方法の代わりにどのような方法を使えばよいでしょうか。 サブクラス一つ一つについて、定義の際、 double subfunc( subA& subAObj ); と書かなければならないのでしょうか。 最後に、クラスについては勉強し始めたばかりですので、何か間抜けなことを書いていたならすみません。
ポインタで渡してみ
>>657 解決方法
1.func を static にする
2.subA.func( suAObj ); を suAObj.func( suAObj ); にする
3.this を使う
>>660 1については、staticにしなければならない意味がよく分かりません・・。
2については、この場合、「オーバーロードされたメンバ関数がAにありません」とエラーが出ます。
>>659 >>660 の3
thisポインタを使った方法でやれ、ということですね。
今まで、自身のメンバ変数を引数に指定する必要は無いことすら知りませんでした。
この方法はうまくいきました。
662 :
661 :2006/12/28(木) 23:25:59
663 :
661 :2006/12/28(木) 23:34:58
すみません、2の方法を使ったコードを見直していたら、 2でエラーが出たのは、ヘッダファイルでのメンバ関数宣言で引数を書き忘れていたためエラーが出ていただけでした 2の方法でも問題なく動作しました、何度もすみません
>public: double __thiscall A::func(class A,double) なんでソースにでてこない、引数が「class A, double」なんて メソッドについてエラーがでるんだ?
665 :
661 :2006/12/28(木) 23:42:26
>>664 >>647 は本来もっと複雑な書きかけのプログラムでして、
もともとの関数はもっと多くの引数をもっていて
class A, double a, double b,...と続くのですが、
>>647 には書く必要が無いため省略しています
そのAの後のdoubleを消し忘れただけです。すみません。
今Visual C++ 2005 Express Editionを使っているんですが 勉強に使っている本がVisual C++ 6.0を使用しているみたいでまったく同じコードでもエラーが出てしまいます サンプルもよくわからないエラーで使用不可能なので勉強がまったく進められません・・・ もう配布終了になっているVisual C++ 6.0を入手する方法はないですか? また持ってる方はいないでしょうか・・・ 6.0と同じ環境にできるならそれでも構わないです よろしくお願いします
>>667 その事を忘れてました・・・
本なんですが3冊セットになっててまだ1冊目の半分程度しか進めていないので買い換えるのはもったいない気がして・・・
2005をを6.0に似た環境にする設定とか無いですかね・・・
エラーの内容は
>>641 で質問した内容+αといった感じです
6.0のソースを使えるような設定に出来ればそれで解決なんですが・・・
どうしてその本にこだわってるのか知らんが、糞みたいな方法を覚えるより本を買い換えたほうが絶対得だと思うが
>>668 マルチバイト文字セットとforスコープのオプションで大体うまくいくと思うけどな。
>>669 金銭面できついので出来るだけこの本で勉強したかったのが一番の理由です
何か2005でも動くソースでお勧めの本とかありますか?
サンプルコードは何やってるかわかればいいんだから 割り切って読むだけにしとくのもひとつの手。
>>672 MSのPlatform SDK(タダで落とせる)には、サンプルコード沢山着いてくるぞ
後はwww.codeguru.comとかその手のサイトが海外にいくらでもある
>>671 俺はVC6しかないけど
for (int i=0; ...) { }
// ここで i は有効(VC6) 2005だとデフォ無効シンボル
ってことかな?
俺は寧ろ VC6 の方で #define for if(0);else for とかやってスコープ切ってるけどな。
>>677 yes
てか今のC++コンパイラではiはfor内のみ有効が普通。
VC7以降や某のコンパイラはVC6で書かれたソースの互換性維持のためにオプションでfor以降有効に変更できるけど。
>>678 そういう意味だったのか
たまにそういう記述みかけるけど、なんだか解らんかったよ
681 :
デフォルトの名無しさん :2006/12/29(金) 16:24:08
struct hoge { int i,j,k; hoge(){} hoge(int _i, int _j, int _k){ i = _i;j = _j;k = _k; } }; void func() { int a,b,c; hoge* ph = 0; 〜略 for(〜){ ph[〜] = hoge(a,b,c); } } 上のようなプログラムを見まして 構造体をnewもせずに突然hoge(a,b,c)とか書いてるのが謎だったのですが、 これは一時オブジェクトというものであると教えていただきました。 で、それをキーワードにググって見たんですけど、 これがどういうものでどういうときに使ってnewとはどう違うか等、 私のような初心者にも分かるような説明が見当たらなかったもので、 どなたか噛み砕いて教えていただけないでしょうか。お願いします。
>>681 単純に考えよう。
int * intOnHeap = new int;
intOnHeap[0] = int(10);
と
std::vector<int> intArray;
intArray.push_back(int(10));
なら判るのかな? それなら
hoge * hogeOnHeap = new hoge;
hoge[0] = hoge(a, b, c);
と
std::vector<hoge> hogeArray;
hogeArray.push_back(hoge(a, b, c));
も同じことだ。
>>681 オブジェクトが置かれるメモリ空間には、スタックとフリーストア(&ヒープ)がある。
一時オブジェクトはスタックを使う他、最適化で無駄なオブジェクト構築が
省かれる可能性がある。
スタック:
普通に変数宣言したり一時オブジェクトを作成することで確保される。
確保が高速。明示的な解放が不要。
サイズが限定されているのであまり大きなメモリは確保できないが、
コンパイラのオプションで変更は出来る。
フリーストア(&ヒープ):
new(またはmalloc系関数)で確保される。newで確保されるのはフリーストア、
mallocで得られるのはヒープだが使う方としては違いは無い。
確保が低速。明示的な解放(deleteやfree)が必要。
確保サイズに上限は無いが、確保に失敗する可能性がある。
失敗すると例外std::bad_alloc送出(古いコンパイラはNULLを返す)
これで得られるのはメモリアドレスなので、ポインタや参照を通して
操作する必要がある。
>>681 for(〜){
{
hoge tmp(a, b, c);
ph[〜] = tmp;
}
}
意味的にはこれと同じ
685 :
デフォルトの名無しさん :2006/12/29(金) 17:12:46
C言語の質問させてもらいます iとjの変数があって 37と入力したとき iに3、jに7を代入する方法はありませんか?
char buf[100]; int i, j; gets(buf); i = atoi(buf) / 10; j = atoi(buf) - i * 10;
#include <stdio.h> main() { char buf[100]; int i,j; char *buf_ = buf; gets(buf); i = (int)*buf_ - '0'; buf_++; j = (int)*buf_ - '0'; printf("i: %d j: %d\n", i, j); }
>>686 ×j = atoi(buf) - i * 10;
○j = atoi(buf) % 10;
どっちでもいいじゃないか
690 :
681 :2006/12/29(金) 17:22:20
>>682-684 三つ合わせて読んだら大変よく分かりました。
かなりすっきりできました。ありがとうございました!
>>688 ×ではなくてせめて△にしてくれ。
間違いじゃないんだから。
i = _getch(); j = _getch();
693 :
デフォルトの名無しさん :2006/12/29(金) 18:10:07
>>684 基本的には
>>684 だけど、オブジェクトの寿命を考えたら同じとは言えないのでは?
>>684 のケースでは tmpを宣言したブロックないではtmpが存在していることを保証できるけど、
>>681 の例では
> ph[〜] = hoge(a,b,c);
の行を抜けたら一時オブジェクト hoge(a,b,c) の実体はどうなるか分からないんじゃなかったっけ?
この場合はすぐに代入してph[〜]のほうしか使わないから問題ないけど、
オブジェクトのアドレスを取ったりするケースでは問題があったと思う。
間違ってるかもしれないので詳しい人フォローおねがい。
一時オブジェクトはconst変数への束縛がある時を除き、 代入または初期化が済んだら即解体されると覚えておけばよい。
std::string buf = "37"; int i,j; std::string::iterator it = buf.begin(); i = *it - '0'; it++; j = *it - '0';
コンソールアプリケーションで、 ビルドして生成されるEXEファイルのアイコンを 変えたいです。 ([ソリューションエクスプローラ]から[リソースファイル]-[追加] から[既存の項目の追加]で、オリジナルのアイコンを選択して、 ビルドしましたが、アイコンは変更されませんでした) どうやってやればいいか、教えてください。 環境ですが、私はVC++2005ExpressEditionを使っています。
コンソールアプリケーションにはアイコンも糞もないと思うが。
>>697 アイコンを含むリソースファイルを .exe に結合すれば Windows が勝手にアイコンを表示するはず
有力な可能性は .bmp の拡張子を .ico に変えただけのファイルなんじゃないかということ
おそらくはアイコンを使えというrcファイルを書いたのではなく ソリューションエクスプローラ(だっけな?)に表示できる状態にしているだけに俺は1票
ご回答感謝します。
>>699 アイコンの作り方が間違っているんでしょうか?
ちなみに私は(彩彩畑という)ソフトを使って、*.gif画像を元に*.icoを生成
しました。
>>700 *.rcファイルって検索したらテキストファイルらしいですね。
今この種類のファイルはないんですが、これも
用意しなければ、アイコンは表示されないっていうことですか?
いろいろいじってみました。
>>700 さんの仰っているいるとおりですね。
*.rcファイルを作ってみました。
rcの中身を↓のようにしました。
IDI_ICON1ICONDISCARDABLE"TEST.ico"
書いている内容は最後の" "の部分しかわかりませんが、
とりあえず、アイコンを変更できました。
ありがとうございます。
>>701 アイコンファイルをバイナリエディタで開いてみて、
ファイルの先頭が BM または GIF で始まっていた場合には
アイコンを作りなおせばいいと思う。
それ以外の場合は、VC++2005ExpressEdition を持ってないのでオレには分かりません。
よくC言語をマスターしたら他の言語も勉強しろって言うけど C言語をマスターするってどの程度のレベル? それなりのプログラムを書けたらとりあえずはマスターしたことになるのかな それともその人の気持ち次第ってこと?
規格書に書いてあることが理解できて応用できるくらい?
宿題スレに出される問題がすらすら解けるぐらいじゃね?
C言語ならまかせろ って言えたらマスターかな・・・1年じゃ無理だろうな・・・
708 :
デフォルトの名無しさん :2006/12/31(日) 01:31:23
どの言語ででしょうけど(私はCなんですが) 反復の制御で No 1:** ・・・ No 10:** ではなく No 1:** ・・・ No 10:** というようにスペースでズレないように 出力するにはどうしたらいいんですかね?
あぁ…そうか書き込みじゃこうなるorz No--1:** No--10:** ではなく No--1:** No-10:** (-は半角スペースとして) です。申し訳ない。
>>208 > どの言語ででしょうけど(私はCなんですが)
日本語でおk
for (i = 1; i <= 10; ++i)
printf("No %2d:**\n", i);
申し訳ない どの言語で「も」でしょうけど でしたw ありがとうございます。出来ました。
712 :
デフォルトの名無しさん :2006/12/31(日) 11:17:15
deleteについて質問です。 class DataList { public: int nData[ 100 ]; DataList *pDataListNext; }; の様なデータ構造を作っています。 配列が一杯になるごとに、新たなクラスインスタンスをnewしています。 逆に削除するときに、 pDataListNext = NULL; delete pDataListNext; とした場合、ヒープ領域のデータは正しく解放されるのでしょうか。 (最後尾のインスタンスの時はpDataListNextがNULLである、としているためdelete前にNULLを代入しています。) よろしくお願いします。
>>712 解放されない。メモリリーク。
deleteは受け取ったアドレスのメモリを開放する。
>>712 はNULLを受け取っているので
何も解放しない(エラーも出ない)。deleteしてからNULLを代入するのが正しい。
されない
どうしても先にdelete前にNULL入れたいなら、一時変数にポインタコピーしてそれをdeleteすればおk
デストラクタで連鎖させないと先に2つ以上繋げてる時にメモリリーク起きない?
>>716 当然リンクの接ぎ換えはやってんじゃないの
C++の知識はクラスや仮想関数を勉強した辺りです 新たに本を買おうと思うんですが 「ひと目でわかるMicrosoft Visual C++ 2005アプリケーション開発入門」 この本を買ったことがある方いませんか? これからの勉強内容に見合うかどうか教えてください また他にお勧めの本があればあわせてお願いします
何を勉強したいかによるだろう
ofstreamでファイル記述子が必要な場合は、どのように取得すればよいのでしょうか?
基本的に無いと思え。 iostream的には、逆にファイル記述子を基に読み書きするバッファクラスを作れ、という感じだと思う。
下記のように、スカラ型newで確保したメモリをベクタ型deleteで開放した場合 どのような問題が起こりうるでしょうか? 例: int *i new int; 〜中略〜 delete [] i;
>>723 じゃVCの場合だと、どんな挙動しますかね?
VCの場合って言ってんのに、 「未定義」 ってオマエ・・・アホが答えるな
答になってないと勘違いする程度にお前がアホなだけ。
平たく言うと「何が起こるかわからん」ってことだよな。
ハードディスクをフォーマットされても文句は言えん。
bool型は↓のように~でひっくり返すとtrueとfalseが入れ替わることは保証されてるの? bool b = true; b = ~b;
b = !bにしろ
未定義だろうとなんだろうと、実際問題実行すると何かしら挙動がある。
C/C++での未定義は、どんな挙動を起こしても良いし、その挙動を文書で明示する必要が無いと言う動作に対して用いられる。
(ということだったと記憶している。違ったらすまん)
で結局何が言いたいのかというと、
>>724 自分で試せ。
ついでに言うと、そうしたほうが人に訊いて答えが帰ってくるのを待つよりずっと早く答えがわかるだろうに。
733 :
デフォルトの名無しさん :2007/01/04(木) 00:58:06
技術の質問でなくてすまんですが、アドバイスください。 45歳になるおっさんですが、Javaの設計、PGを7年ほどやってきた者です。 Cの市販本でCを習得した後(ポインターにはひどく苦しんだが)、 C++も市販本で習得しました。 C++のプログラマーでそこそこやりたいのですが、どういう分野を 狙ったらいいでしょうか? たとえば、組み込みとか、制御系とか、ゲームとか? ちなみに、JavaからC++に乗り換えたいのは、Javaはいろいろ せわしく新しいものが出てくるし、開発規模の大きいものが多く、人間 関係に疲れたからです。
そんな理由でC++をやろうとはあまり関心できない。 C++だってまだ発展しようとしている言語。いくらでも新しいことは出てくるし、学ぶネタは尽きない。 ただ学問・理論的な方向へ走っているきらいがある(実用が追い付いていない)からそう見えない感じもするが。
>>733 おまいは大きな勘違いをしている
BoostやらC++09やら現時点でC++を知っている者ですら
新しいC++はより変態的になっていっている
記述もJavaと違って変態的なものが書けてしまうので、
そんな理由ならやめた方がよい
つうか言語以前の問題として、高々経験7年の45歳の業務系Javaプログラマが 今から制御系とかゲームプログラマにデューダって 普通に無理だから諦めれ
738 :
デフォルトの名無しさん :2007/01/04(木) 02:27:28
733ですが、決して甘く考えたつもりではないのです。
しかし、
>>737 さんの普通に無理だからが、やっぱりなあと、訊いておいてなんですが
納得するところです。
でも、一人でしこしこ、最初は無収入覚悟で、5年後くらいから月20〜30万くらい
稼げるかも知れないわずかなチャンスのあるのは、どんな分野でしょうか?
>>738 制御とかゲームとかだと、業務系より高いスキルレベルや専門知識
要求されるぞ。ただでさえ高年齢の転職はハードル高いのに、
今のアンタの手持ちのスキルじゃ、「経験者」とは見なされないだろう。
回路図とかは読めるのか?
言語の話をすると、C++はCよりもずっと強力だが、複雑で難解な言語なので、
ポインタが難しいとか言ってるレベルでは話にならない。
計算機のメモリモデルとかCPUのアーキテクチャとか、理解して無いだろ?
はっきり言うが、45にもなって2chでそんな甘い書き込みしてる時点で
「甘く考えすぎ」じゃないのか。
大した手持ちの技術は持ってない、人間関係には疲れたから元の職種は嫌だ、
でも20〜30万ぐらいは稼ぎたいな。
はいはい。
まーやるんならせめてマ板でやれや。「プログラマ板」な。
こっちは技術の話をする板であって、オッサンが転職相談する板じゃないから。
740 :
デフォルトの名無しさん :2007/01/04(木) 02:48:30
733です。
>>739 さん、真実なアドバイスありがとうございました。
”回路図とかは読めるのか?”
ああ、これやはり本当なんですか。
制御の仕事はハード系の知識がないとダメというのは。
>>740 私の勤める会社に来ませんか?
業務系部署もありますがそれよりも私の所属する制御系部署で歓迎します。
制御系といってもハードよりの仕事ばかりではありません。
C/C++を使った各種演算解析画像処理プログラムもあればファームウェアとGUIの
ブリッジになるようなミドルウェア的な仕事もあります。
経験7年あればプログラマとしては充分な勘はお持ちでしょうし、
プロジェクトリーダとしての経験があるならPlaingManager的な遣り方でもいいでしょう。
結果を出してくれるという前提条件はつきますが、無給などと言わず前職給与を基準に考慮できるはずです。
∩___∩ | ノ ヽ'''''';、 ,,......-/ ● ● | ) ”” ; | ( _●_) ミ § ;; 彡、 |∪| 、`\__===・ いやいや、釣られないクマよ ; / __ ヽノ /´ ――┴;; ; (___) | ―――'"  ̄ ̄ ̄ ̄ ̄) ,,..-'''⌒;, /
∩___∩ | ノ ヽ'''''';、 ,,......-/ ● ● | ) ”” ; | ( _●_) ミ § ;; 彡、 |∪| 、`\__===・ 腹、減ったよ ; / __ ヽノ /´ ――┴;; ; (___) | ―――'"  ̄ ̄ ̄ ̄ ̄) ,,..-'''⌒;, /
745 :
デフォルトの名無しさん :2007/01/04(木) 12:16:02
ちょっとスレ違いですが、Windows2000で、接続したUSBデバイスのハードウェアID調べるにはどうしたらいいでしょうか?
>>745 自分でも分かってるようだがそういうのはWin32APIスレ向きだろ。
まー俺はよく知らんが、
SetupDiCreateDeviceInfoList()
SetupDiGetClassDevsEx()
あたりのDevice Management APIが使えるんじゃないか?
>>746 確かにそうですね。
レスありがとうございます。
助かりました。
>>732 もちろん真っ先に自分で何パターンか試した。
で、デバッガで見たところ問題がないように思えるので、
本当に大丈夫なのか、もっと詳しい人がいないかな?と
ここで聞いてみたんだけどね。
749 :
748 :2007/01/04(木) 14:01:14
ちょっと言い訳すると、うっかりこの間違いに起因 するバグが出たときに(もちろん気をつけてはいるが)、 どういう挙動が考えられるかが予め解っていれば 原因究明が速くなると考えて、経験者に聞きたかったわけですよ。
言い訳し過ぎw
>>732 未定義のいやらしいところは、「確定挙動とは限らない」も含むんじゃね?
前回実行時と今回実行時で挙動が変わる ってのもありえるような…
マニュアルを調べて書かれてないなら 処理系ベンダさえ放棄している未定義だから このマシンでどう動きますかって言うのは プログラマ的にナンセンスなんじゃね? 一口にVCと言ってもバージョンもランタイムライブラリもいろいろある。 OSも関係するかもしれないし。どうなるって言えるもんなのかね。
じゃ聞き方を変えて、 下記のように、スカラ型newで確保したメモリをベクタ型deleteで開放した場合 (または逆の場合など)に、何か問題がおきたケースってありますか? できれば処理系や環境、そのほか貴方が関連すると思われる事柄を 添えて、事例を教えていただけると助かります。 例: int *i new int; 〜中略〜 delete [] i;
>>753 好きにしろ。
思う存分、鼻から悪魔を召還するがいいさ。
VCでPOD型なら、ひょっとしたら問題にならずにすむかもしれないよ。
int *i new int;
それより、C++ってのはいつからこんな文法になったんだ?
それから、いつからスカラ型とかベクタ型なんてものが、組み込み型の仕様に盛り込まれたんだ?
2005だとクラスのデストラクタがとんでもない回数よばれたお。
2005だけどクラスのデストラクタがとんでもない回数よばれないお。
bcc5.5.1だとデストラクタが12回呼ばれた後にエラー出て落ちたお。 聞いてねーよとか言うな
聞いてるよ
759 :
デフォルトの名無しさん :2007/01/04(木) 18:55:51
やさしいCを読み終わったんですが、次は何読めばいいですか? C言語の用語集・リファレンス集みたいなやつで、ポケットサイズのものが欲しいんですが、 いいのはありませんか?
>>759 何を読めばいいですかとか言ってる時点でダメさ丸出し。
なんか書いてみてわかんなかったところを埋めろ
関数の中で変更されたくない引き数にconst付ける事がよくあると思うのですが それはchar*型の引き数だけでint*型にはつけないのですか?
すいません int*型→int型です。 (コンストラクタのあたりでの疑問です。)
>>761 どんな型でも変更しないなら付けとくべき
764 :
759 :2007/01/04(木) 19:48:02
>>760 わからないことだらけなんですが・・。
わからないところを調べるために、
そうおうポケットリファレンスみたいなのが欲しいんです。
パソコンの使えないところでも調べられるように書籍が欲しいんです。
リファレンスなら C, C++ 規格書と言いたいところだけど高いから C(C++)言語辞典あたりが手ごろな値段だったと思う
・C++ランゲージクイックリファレンス ・C++ライブラリクイックリファレンス
orz ...よりによって団子と全く同じことを書き込もうとした。ちょっと首吊ってきます。
関数内で引数の値をうっかり変更しないようにとか
770 :
デフォルトの名無しさん :2007/01/04(木) 20:45:28
すいません、多次元配列の動的確保の構文についての質問です。 自前のクラスMyClassのポインタ配列を動的に確保したいのですが ネットで調べたところ以下のような方法で出来ることがわかりました。 int tblSize; // ここが動的に変化する **MyClass clsTbl = new MyClass*[tblSize]; for(int i=0;i<tblSize;i++) { clsTbl[i] = new MyClass; } 実際に動いてるので問題ないのですが、下記のnew構文の意味がよく分かりません。 この↓書き方がしっくりこないんです。 new MyClass*[tblSize]; ポインタの配列なので、こういう場合は new (*MyClass)[tblSize]; というのが正しいように感じるのですが、なぜこのような書き方になってしまうのでしょうか? ご存知の方、いらしたら教えてください。
771 :
759 :2007/01/04(木) 20:49:08
>>765 C言語辞典が良さそうですね。
>>766 だと2冊持ち歩かないといけなくなるし、本のサイズもでかい。
くだらない質問ですがお願いします。 int型をstringクラスへ変換する方法がわかりません。 strstreamに出し入れしてstringに変換する方法はわかるのですが、 Cの標準関数「itoa」やjavaの「String.valueOf」のように 関数を呼んで変換する方法があれば教えてください。 また、どうやって変換する方法がC++では一般的なんでしょうか。
>>772 strstreamは古い仕様。stringstreamにしろ。
itoaは標準関数ではない。
boost::lexical_cast使えば?
中でやってることはstringstreamと同じだけど。
キャスト演算子は使えないの?
C++初心者です。 wstringとw_charについて勉強したいのですが、 私の持っている本には、 説明がありません。 WEB上で、これらを説明しているHPがあれば教えてくれませんか?
>>776 wstringはbasic_stringクラステンプレートをcharではなくwchar_tで適用してるだけでstringとおんなじ。
wchar_t はワイド文字を格納する為の型。sizeof(wchar_t) はコンパイラの実装により変化するので注意。
以上、おしまい。
itoaは標準関数じゃないので注意
780 :
774 :2007/01/04(木) 21:52:49
ある物体を45度づつずらして5方向方向から撮影しました。 次にその画像(BMP)を2値化、線化しました。 これを撮影した時と角度をあわせて3次元配列に読み込みたいんですがどうすればよいでしょうか? どうか教えてください。 環境はVC++6を使用しています。
>>778 itoaはAnsi Cで定義されてない。Windows用のコンパイラは大抵使えるけど。
sprintf使っちゃうのも手だわな。どうせCランタイムはリンクされるんだし。
でも非セキュアな関数はあまり勧められないな
「itoaは標準でないから注意」と書く人が 何も注意を書かずにboost::lexical_castを薦める不思議
itoaを標準と勘違いしてるから正しただけ。 別に標準じゃないからダメと言ってるわけではない。
不思議と感じる
>>784 が不思議なだけだな、さすがにこれは。
すみませんが、よろしければ
>>770 にも誰か答えていただけないでしょうか・・・
MyClassへのポインタ型の変数pを宣言するときこう書くだろ。 MyClass* p; 変数を1つ宣言する構文は大雑把に言って「型名 変数名;」 new[]の構文はnew 型名[要素数] こういう連想はだめか?
>>770 new ???[N];
???には型名が入るわけだが、MyClass* はMyClassクラスのポインタだが
*MyClass なんて型は無い。
791 :
770 :2007/01/05(金) 02:36:21
ありがとうございます。 すいません元の文章でここんとこ↓間違ってますね。すいません、 × **MyClass clsTbl = new MyClass*[tblSize]; ○ MyClass **clsTbl = new MyClass*[tblSize]; てことは、後の部分もこれでいけるかと思ったんですが、下の書き方はコンパイルエラーになってしまいますね。 new (*MyClass)[tblSize]; ←そもそもあり得ない new (MyClass*)[tblSize]; ←コンパイルエラー new MyClass*[tblSize]; ←正しく動く 括弧がつくと意味が変わってしまうんでしょうか? どちらも MyClass* という型だと思うんですが。
792 :
790 :2007/01/05(金) 02:42:33
>>791 かっこ付くと意味がぜんぜん違う
そこらへんから分かってないのか ちょっとまって
なかなか言葉での説明は難しい
793 :
790 :2007/01/05(金) 02:47:59
まだ考え中
>>791 はまだおきてる?
途中まで書いた
new MyClass*[tblSize];
と
new (*MyClass)[tblSize];
じゃまるで意味が違う。
簡単な例で考えてみればいいと思う。
たとえば、
new int*[size]
と
new (*int)[size]
で考えてみればいい。
前者は、intポインタ型の配列を作るという意味。
後者は意味不明。たぶん別のものとごっちゃになってる。
intポインタ型の配列を作りたい場合、普通は次のようにかく。
int* p[5];
これはintポインタ型の配列(要素数は5個)を作るという意味。
使用例は下のコードを見て。
int array[5] = {1, 2, 3, 4, 5};
int* p[5];
for(int i = 0; i < 5 ; i++) {
p[i] = &array[i];
cout << p[i] << endl;
}
794 :
790 :2007/01/05(金) 02:49:14
次の例。 intポインタ型の配列(要素数は5個)をnewを使って作りだす 場合は以下のようになる。 int** q = new int*[5]; int型の配列を確保する場合は、 int* r = new int[5]; ってやるんだから、intポインタ型の配列を確保する場合は int** r = new int*[5]; ってやると考えればわかりやすいかもしれない。 (ごめんわかりにくかったら) ここで int** q = new (int*)[5]; はダメだよ。意味が違う。 たとえば次のコードは分かる? int array[5] = {1, 2, 3, 4, 5}; int* p; int (*q)[5]; p = array; q = &array;
795 :
790 :2007/01/05(金) 02:50:04
ここまで書いた やばいねむいがんばる
796 :
デフォルトの名無しさん :2007/01/05(金) 02:53:30
newはint型のポインタをメモリに確保する。 int* ptr = new int; つまり、int一個分の領域をヒープに確保するわけだ。 int* ptr = new int[1]; C++で一次元配列int[]はint*と同じなので、配列のサイズが増えても書き方は同じ。 int* ptr = new int[100]; メモリ上にどんだけ確保してもptrに返るのはその先頭アドレスとなる。 で、次に下の書き方ではintのポインタをメモリに確保する。 int** ptr = new int*; これは上の同じ理屈でこう書ける。つまりintのポインタ一個分を確保するってこと。 int** ptr = new int*[1]; 当然、サイズが増えても先頭のポインタは変化しないので、こう↓かける int** ptr = new int*[100]; 括弧に関してはワカラン。「そういう文法だから」でいいんじゃね? だって、普通の変数の宣言で (int*) ptrInt=NULL; なんて書き方できないっしょ?
797 :
790 :2007/01/05(金) 02:56:29
798 :
デフォルトの名無しさん :2007/01/05(金) 03:07:40
D&Eの長い前書きを読んでいて良く分からないところがあったので、 スタイルブックを注文したよ。 この後プライマーを読んでみようかと。
799 :
796 :2007/01/05(金) 03:08:08
ワカランですばい。
800 :
790 :2007/01/05(金) 03:08:18
地震だこえー
801 :
790 :2007/01/05(金) 03:10:11
いま解説書いてるまってちょ
802 :
796 :2007/01/05(金) 03:11:28
790のやさしさに全米が泣いた
803 :
790 :2007/01/05(金) 03:17:12
もし int *q[5]と書いたとする。 これは int* q[5] と同じってのは当たり前だよね。 さっき説明したみたいに、intポインタ型の配列を5個作るという意味。 じゃあ、int (*q)[5] って書いたらintポインタ型の配列を5個作るという 意味には残念ながらならない。 これは、要素数5個の配列全体のアドレスを入れるものだと考えればよいと思う。 イメージ図を貼り付ける。 当然のごとく int array[6] = {1,2,3,4,5,6} //要素数6個になった int (*q)[5]; q = &array; はダメね。qに要素数6個の配列全体のアドレスを入れようとしてるから シンタックスエラー。 また、 int array[5] = {1, 2, 3, 4, 5}; int* p; int (*q)[5]; p = array; q = &array; って所にもどって解説。 あ、一つ注意ね。 p = array は p = &array[0] ってかくのが面倒だから省略しただけね。 二つはおんなじ意味だから注意。 じゃあ、ここでpをインクリメントすると、どうなる?
804 :
デフォルトの名無しさん :2007/01/05(金) 03:24:37
constとポインタの組み合わせも複雑怪奇だぜ。 エキスパートCで嫌になった。
805 :
790 :2007/01/05(金) 03:26:08
>>778 boost::formatが汎用的にはいいかも。lexical_castには基数変換したりといった
高級な能力は無い。
ただし、グローバルロケールがclassic以外の物にセットされていると、
iostream系は全て余計な動作をする(カンマを挟んだり)ので要注意かな。
ぶっちゃけsprintfは悪くない選択肢。Cならまずコレだし。
std::string result;
{
std::stringstream ss;
ss << "0x" << std::hex << std::uppercase << std::setw(8)
<< std::setfill('0') << 12345678;
result = ss.str();
std::cout << result << std::endl;
}
{
char buff[16];
std::sprintf(buff, "0x%08X", 12345678);
result = buff;
std::cout << result << std::endl;
}
{
std::stringstream ss;
ss << boost::format("0x%08X") % 12345678;
result = ss.str();
std::cout << result << std::endl;
}
807 :
790 :2007/01/05(金) 03:31:36
ここで、arrayの最初の要素のアドレスが100番地だと仮定。 でpが100番地を指してるとして、インクリメントすると、 100番地 + 4番地 なので 104番地ってなる (ここでintのサイズ つまりsizeof(int)を4と仮定した) じゃあ、qが指してる場所が100番地だとしてqをインクリメントすると、 100番地 + 20番地なので120番地を指すことになる。 (なぜなら sizeof(int) * 要素数5個なので) なんか眠くて頭おかしくなってる。(まあもとからry) 余計なことまで説明してるような気がする。かえって混乱させたかも 用は int *q[5] と int (*q)[5] が違うってことを言いたかった。 やっぱ俺では説明力不足だわ。 あってるか自身もなくなってきたし
808 :
790 :2007/01/05(金) 03:37:38
ああ、ぼけてる いま自分で書いたの読み返してる。
>>803 3行目〜4行目
>さっき説明したみたいに、intポインタ型の配列を5個作るという意味。
>じゃあ、int (*q)[5] って書いたらintポインタ型の配列を5個作るという
じゃなくて、
さっき説明したみたいに、intポインタ型の配列 (要素数は5個) を作るという意味。
じゃあ、int (*q)[5] って書いたらintポインタ型の配列 (要素数は5個)を 作るという
になおして
790はとりあえずおねんねしろ
C/C++の宣言は内側から外へ向けて読んでいく。 配列の[]や関数の()は他よりも優先順位が高い。 ()により優先順位を明示することも出来る。 時には複雑怪奇な宣言にも出会うだろうが、基本はそれで読めるはず。 int *q[5] は q -> [5] -> * -> int の順で読める。 「q is an array[5] of pointer to int」 「q は int* を格納する5要素の配列」 int (*q)[5] は q -> * -> [5] -> int の順で読める。 「q is a pointer to an array[5] of int」 「q は int を格納する5要素の配列へのポインタ」
811 :
デフォルトの名無しさん :2007/01/05(金) 03:51:57
int array[5] = {1, 2, 3, 4, 5}; int* p; p = array; これ、コンパイル通る?
812 :
790 :2007/01/05(金) 03:53:56
話をぶった切りますが。 日本語版VC++2003のclコンパイラで、Shift_JIS(CP932)以外のエンコードの ソースをコンパイルする方法はありますか。例えばUTF-8など。 ありがちなのは、海外の、Latin-1なソースをコンパイルしたいケースなのですが。
814 :
790 :2007/01/05(金) 04:03:07
まあ ポインタは難しいからこれだけの解説で分かったら凄いと思う。
俺でも結構間違えるし。(ここに書いた解説もなにか間違ってたらごめん)
この手のことは、K&Rの100ページ(日本語版でもページ番号同じかなぁ)、
5.7 multi-dimensional arrays って所にのってる。
けど、K&R難しいから、日本語でオススメな本で、
ポインタ完全制覇 って本と ポインタが理解できない理由 っていう本が
分かりやすいから、読んでみるといいかも。
前者には
>>810 の言ってたようなことも書いてある。
じゃあ おやすみなさいもう寝ます
815 :
デフォルトの名無しさん :2007/01/05(金) 04:04:09
あ、すまん、pとq間違えてた。寝るわ
>>816 たまたまバイトのナラビがShift_JIS的に不正でない&ワイド文字を一切使わない
という条件でしか上手く行かないでしょ、それは
NT系OSだと内部的にUTF16に変換する際に暗黙にカレントのACP使う筈だから、 仮にAバージョンのAPIを使うとしてもダメだな。 つまり論外。
クラスAと、Aを親に持つ全てのクラスをfriendクラスにすることはできるでしょうか? いちいち全部かかないと無理でしょうか
820 :
デフォルトの名無しさん :2007/01/05(金) 11:27:36 BE:717451968-2BP(3001)
初心者にもなってなくてごめんなさい スレ違いかな、そうなら指摘して頂いたらありがたいです。 CとかC++言語の勉強がしたいのですが、どんな本がお勧めでしょうか? アマゾンで買おうと思ってます
822 :
デフォルトの名無しさん :2007/01/05(金) 14:28:22 BE:717451968-2BP(3001)
823 :
デフォルトの名無しさん :2007/01/05(金) 14:35:13
8 9 a b c d e f 10 11 ... みたいに16進数で書かれたファイルを読み込みたいのですがどうすればいいですか? ifstream ifs("log.txt"); ifs >> value1 >> value2 ってやったら a b c d e f を識別できづに 0 になりました
>>823 文字列で読んで、区切り文字で切って、16進数の文字列から数値に変換する。
825 :
823 :2007/01/05(金) 14:48:49
自己解決しました ifstream ifs("log.txt"); ifs >> hex >> value1 >> value2 でいけました。ありがとうございました。
>>788-814 791です。
すいません、なんか色々解説してもらったのですが
まだ完全には理解しきれていないようです。
色んなパターンでコンパイルしてみたり、C++の文法を読み直して
きっちり理解したいと思います。
ありがとうございました。m(_ _)m
827 :
デフォルトの名無しさん :2007/01/05(金) 15:33:16
だれかプライマー4版読破した人いる?
828 :
デフォルトの名無しさん :2007/01/05(金) 18:13:02
質問させてください。 初心者本を片手につい先程C言語の勉強を始めたのですが 以下のものがコンパイル出来ません。 #include <stdio.h> void main(void) { int n1, n2, sum;/* 整数型の変数を3つ宣言する */ scanf("%d", &n1);/* n1に数値を入力 */ scanf("%d", &n2);/* n2に数値を入力 */ sum = n1 + n2;/* sumにn1とn2の和を入れる */ printf("%d\n", sum) /* sumの内容を10進数で表示する */ } エラーメッセージには ex0201.c:関数`main'内: ex0201.c:13:error:文法エラー before '}' token と表示されます。 "%d"と"%d\n"という部分が原因のようなのですが、 何度見返してみても本通りに入力しているのでどうすればいいのかわからず。 どなたか解決方法を教えて頂けるとありがたいです。
>>828 エラーメッセージも読めんのか
ex0201.c:13:error:文法エラー before '}' token とあるだろ。
最後のprintf文の尻にセミコロンつけとけ
>>829 早いレスありがとうございます。
何度も見直したはずなんですが、すいませんorz
832 :
デフォルトの名無しさん :2007/01/05(金) 18:22:20
>>828 みたいなのを見ると
自分がそれなりには成長してきたことを実感できる
対象外でしょ
入力部分を [TextBox1] [ComboBox1] [TextBox2] と言う感じに配置をしたのですがコンパイルして実行した時Tabキーを押すと Text1 → Text2 → Combo1 の順番で移動してしまいます このTabキーを押した際の移動の順番を指定するプロパティはありますか? また何が原因なんでしょうか よろしくお願いします
整数型変数3つからなる構造体を、10万個つくるプログラム作ったら、 予期せぬ〜と言うメッセージがでてコンパイルできませんでした。数を減らすとコンパイル可能です。 こういう場合どういった手法で解決に導くのでしょうか? 環境はVC++2005です。
スタック変数に大きなデータは確保できない。スタティック(グローバル)変数にするかヒープに確保しましょう。
838 :
836 :2007/01/05(金) 20:03:58
>>837 即レスありがとうございます。
大変参考になります。
>>835 Win32の話ならWin32APIスレへどうぞ
>>835 タブオーダ変えればよいだけ
まあwin32apiスレで
>>836 >>837 の言うとおりだか、コンパイル時にスタックサイズを大きく指定することでも回避可能。
>>839-835 すいませんスレが分かれているとは知りませんでした・・・
次からそちらで質問します
ありがとうございました
スレタイにもあるとおり、ここでWin32のことを訊いてもいい。 ただ高度なことは専門のスレで訊いた方が答えが返ってきやすい。
struct A { int a; template<int a> void func() { cout << a << endl; } }; int main() { A a; a.a = 1; a.func<2>(); return 0; } ↑のようなプログラムを実行するとVC++とgccでは2と出力されます。 しかしbccでは1と出力されました。 テンプレート引数とメンバ変数の優先順位は決まっていないのでしょうか? それともどちらかのコンパイラのバグでしょうか?
>>845 レスありがとうございました。
bccのバグですか。
古くはVer5.5から最近のTurboCの5.8でも直ってないみたいです。
847 :
デフォルトの名無しさん :2007/01/07(日) 20:28:16
ちょっと聞きたいんですが C/C++を勉強してしばらくになります CでもC++でも、有る程度まで関数やクラスの作り方は覚えると思うし よく使う関数なら勝手に覚えてしまうと思うんですが それ以上のCなら普段使わないけど、知ってたら便利な標準関数やソートなどのアルゴリズム。 C++ならコンテナ(vector,list,deque並びにutilityやalgorithmまで含んで)等 それに加えてboost。 どこまで覚えて普通なのか。普通の基準は曖昧だと思いますが、普通にSTLで使える 物だけでも組み合わせ等で山ほど覚えることがあると思いますし・・・ なんか、参考書の例題見て便利だなとは思いますが覚えきるなんて無理で無駄だと 思い出しました。 CならC++で描く必要のないレベルのプログラムならCで書く。 C++なら、クラスの実装やテンプレートの実装の部分を確実な物を書けるように それとiostreamの理解、そしてSTLのvectorなりのコンテナの一つで 良いからアロケーターまで理解する。 といった感じで(iostreamやvectorを理解しきるの為の本自体有るのかさえ知らないし Cなら例えばprintf文をデバッガで追いまくるとアセンブラのファイルにたどりついてしまい アセンブラも勉強か・・・とまで思った次第なので言い切れないですが)良いのでしょうか。 それともそこまで深く追うより、プログラムをガリガリ書いて、プログラミング自体を鍛錬すべき なのでしょうか。 なんか、boostを知って、ちょっとサンプルソース書いて理解して覚えようかと思ったのですが これじゃキリが無いって思い出してどうすべきなのかが迷っています。 変な質問してすいません。
所詮はライブラリなので、必要なものだけ覚えればいい 何かを作るのに不足さえなければ別にSTLすら要らない。
>>847 の書き込みから推定される習熟度まで達しているんだったら STL/boost あたりは暇な時にでも覚えて、
>それともそこまで深く追うより、プログラムをガリガリ書いて、プログラミング自体を鍛錬すべきなのでしょうか。
そうしたほうが有意義だと思うよ。
あと、他の言語に浮気するのもいいと思う。
覚えてるやつなんていないだろ。 それよりもすぐにリファレンスを引ける環境を整えるといいよ。 最近の統合開発環境のインテリセンスは異常に親切だしなぁ
s/思い出し/思い始め/ こういう意味か、最初は分からんかった。 必要になったときに本を調べるか それらしい言葉でググるだけで事は済むさ〜
>850,851 に同意 "普通"は、 ・あ、あの本に書いてあったな とか ・XXXXXってキーワードでぐーぐる先生に聞いたらわかるな とかレベルぢゃねの? 暗記ってのは別の能力だろ。。。まぁ「すげー」って言われるのはこっちの能力なんだけどね(´д`)
853 :
847 :2007/01/07(日) 22:12:27
レスありがとうございます。 ガリガリ書いていくことにします。
C++はある程度覚えたら一度別の言語に移ってから 戻ってくると理解が容易になる気がするな。 PythonかRubyがお勧め。普段のツール作りにも役立つし。
855 :
デフォルトの名無しさん :2007/01/08(月) 23:18:30
【ネガティブ派遣根性チェック】 3つ以上、思い当たる点があればアナタの性格はひん曲がっており、ネガティブ負け組人生を歩んでいます。 □派遣先の社員の意見にはたとえ間違っていても反対しない □派遣先から「いつまでもここで仕事してくださいね」と言われるようになりたい □自社に仕事を持ち帰れるように言われるとムカつく □自社で仕事なんてできるわけがない □派遣/受託の差異を指摘する人間はムカつく □派遣先には仕事だけでなく自分のプライベートについても指示して欲しい □自分の月額金額を知らない □派遣先社員より自分の生涯収入が低いのは当然だ □派遣先に尻尾を振り、いつまでも一緒に仕事をすることが大切だ □今のプロジェクトが終わっても同じ派遣先に常駐したい
クラスオブジェクトへのポインタについての質問です。 基底クラスへのポインタ(*base_p)、派生クラスオブジェクト(obj)があって、 <式> base_p = &obj; を行う場合、継承関係がprotectedでもエラーになるのは、 @派生クラス内の基底クラス部が継承によりprotectedになるため A<式>の処理はobjを基底クラス型にキャストするわけではない Bだから派生クラス内の基底クラス部メンバは全てprotected以下の アクセス性で実質使用不可 ということでいいのでしょうか? 長々すみません
>継承関係がprotectedでもエラーになるのは 何言いたいのか意味わかんね 外部からprotected:にアクセスできないのは何故かって話なら protected:だからだがそれが何か
858 :
デフォルトの名無しさん :2007/01/09(火) 19:20:39
VC6でお仕事してます。 printfの頭にくっ付けて、そのままの書式でfprintfしてくれる クラスを同僚から貰って重宝してるのですが、ソースを見ても ちんぷんかんぷんですた。 こんな私におすすめのクラスの教科書をご教示下さい。
クラスはあまりカンケイないんじゃね?
↓のように重複してfinを使ってオープンするのを避けるために、 ifstream fin; fin.open( "ファイル名", ios::in); fin.open( "ファイル名", ios::in); fin.openの前に、finの値をチェックしたいのですが、 どうすればよろしいでしょうか?
C++について質問なのですが、以下のプログラムでchに漢字やひらがなを格納すると isalpha、isalnum双方とも1が出力されるのですが、isalphaは英字のみ、isalnumは英字、数字 のときのみ1を出力するはずなのにどうして日本語も1が出力されてしまうのですか? 日本語を正しく評価することはできないのですか? #include <iostream> #include <locale> using std::isalpha; using std::isalnum; int main(void){ std::locale loc; char ch; std::cout << isalpha('ch',loc) <<std::endl; std::cout << isalnum('ch',loc) <<std::endl; return 0; }
なんでクオートで囲んでるの?
864 :
861 :2007/01/09(火) 20:28:27
2バイト文字をはじく方法とかありませんでしょうか?
865 :
861 :2007/01/09(火) 20:30:27
>>862 すみません、タイプミスです。ただしくは、
std::cout << isalpha(ch,loc) <<std::endl;
std::cout << isalnum(ch,loc) <<std::endl;
でした。
866 :
デフォルトの名無しさん :2007/01/09(火) 20:58:12
はじめまして。 Windows フォームアプリケーションを使用してツールを作ろうとしています。 そこで質問なのですが、ファイルを読み込みファイル名をリストボックスに表示したいのですが、 リストボックスに追加する方法がわかりません。 this->ListBox->? ↑これにどの関数を使えばよろしいのでしょうか? 初心者ですが、宜しくお願いいたします。
867 :
デフォルトの名無しさん :2007/01/09(火) 22:20:21
VC++で開発しています。 以下のような外部プログラムを起動元プログラム実行形式ファイルの中に 組み込むことは可能でしょうか? ・本体.exe ・外部.exe 本体.exeから外部.exeを外部プログラムとして呼び出す場合はCreateProcessなどを 使えば実現できますが、外部.exeを別個でおくのは煩わしいので、 本体.exeの中に隠蔽して、内部的に外部プログラム起動のような形で 利用することは可能でしょうか? 本体.exe (外部.exe内蔵) 可能であればその方法など教えていただけたらありがたいです。
リソースに組み込んで実行時に展開
こんばんは。 LinuxでDNSサーバのアドレスを設定したり、ルーティング情報を設定したり するにはどうすればよいでしょうか。言語はCです。 コマンドで設定するのではなくプログラムで操作したいのです。
↓のソースをコンパイルしてリンクするとこんなエラーになります。 関数テンプレートを使わない場合は発生しないのですが、 どこが間違っていますでしょうか? main.obj : error LNK2019: 未解決の外部シンボル "class std::basic_string<char, struct std::char_traits<char>,class std::allocator<char> > __cdecl File_Func::Push_back_filename<char *>(char * const &,class std::bas ic_string<char,struct std::char_traits<char>,class std::allocator<c har> > const &)" (??$Push_back_filename@PAD@File_Func@@YA?AV?$basic _string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABQADABV12@@Z ) が関数 _main で参照されました。 D:\func_template\Debug\func_template.exe : fatal error LNK1120: 外部参 照 1 が未解決です。
//main.cpp #include <string> #include <fstream>/* ファイルの入出力 */ #include "Class_Club.h" using namespace std; int main(int argc, char *argv[]) { string strOutFilePath; File_Func::Push_back_filename( argv[1], "_Result" ); } //Class_Club.h #include <string> using namespace std; namespace File_Func { template<class TypeFilePath> string Push_back_filename( const TypeFilePath& FilePath, const string& AddName ); //OKstring Push_back_filename( const string& FilePath, const string& AddName ); }
//file_func.cpp #include <string> using namespace std; namespace File_Func { template<class TypeFilePath> string Push_back_filename( const TypeFilePath& FilePath, const string& AddName ) //OKstring Push_back_filename( const string& FilePath, const string& AddName ) { string strFilePath = FilePath; string::size_type index_f = strFilePath.rfind('.', strFilePath.length( )); if ( index_f != string::npos ) { strFilePath.replace( index_f - 1, AddName.length() - index_f, AddName ); } return strFilePath; } }
874 :
871 :2007/01/10(水) 11:27:55
以上です。よろしくおねがいします(m。_。)m オネガイシマス
876 :
871 :2007/01/10(水) 11:55:14
>>875 拝見しました。難しくて内容をあまり理解できません。
これは、LNK2019エラーを出すのでしょうか?
ちなみに私の環境は、Visual studio C++ 2005 Express Editionです。
>>871 template<class TypeFilePath>
string Push_back_filename( const TypeFilePath& FilePath, const string& AddName )
を実体化できないから
Push_back_filenameの定義をヘッダに書くか 今のPush_back_filenameの定義のあとに template string Push_back_filename (char* const&, const string&); として実体化しておく
879 :
871 :2007/01/10(水) 12:34:26
>>877 関数テンプレートの使い方が間違っているのでしょうか?
宣言の仕方は↓のようにすると思います。
template<class Type>
戻り値 関数名( Type 引数)
もともと上のサンプルのような関数テンプレートは定義できないのでしょうか?
>>879 そういうのはコンパイルエラーとなる
今回のはリンクエラー
無限の型候補の中から実際のTypeFilePathはいつ決定されるのかを考えるといいよ
>>879 Push_back_filenameはmain関数をコンパイルするときに
初めてTypeFilePathが決定され,実体化できる
だからPush_back_filenameの定義はmain関数から見えるとこにおく(878の前半の解法)
この場合file_func.cppをClass_Club.hとしfile_func.cppを消す
またはプログラマが明示的に必要な型で実体化しておく(878の後半の解法)
export templateをサポートしてないから
883 :
871 :2007/01/10(水) 15:30:38
皆様、丁寧な回答ありがとうございました。 よく理解できました!
>>883 別件だけどヘッダ内で
using namespace std;
するのはnamespaceの存在意義を考えると良くない
885 :
デフォルトの名無しさん :2007/01/11(木) 22:18:54
class List { int nData; List *pNext; }; のようなクラスで、pNextを必要に応じてnewで確保していったとします。 デストラクタを自分で定義しない場合、Listオブジェクトが破棄されるときに、ヒープ領域は解放されますか? それとも、自分でデストラクタを定義して、ポインタを辿って一つ一つ解放する必要があるのでしょうか? お願いします。
>>885 解放されるわけ無い。
デストラクタで解放するべきかどうかはわからない。
デストラクタを定義しないなら、new/deleteはmalloc/freeと同じだからな。
れすサンクス。 言われてみれば当然ですね。 すれ汚し失礼しました。
C/C++の解説のサイトをみながら2005Express使って勉強してるんですが(まだ全然です) PCの関係でIEと同時に立ち上げるのが厳しい状況です C/C++基礎からやり直そうとおもってます なにか良い書籍はないでしょうか?
エディタ+nmake/clにしとけ。
891 :
デフォルトの名無しさん :2007/01/12(金) 05:34:24
若いの オラが村では派遣の問題を口にしちゃなんねーだ お前さんはまだわけぇから言いたいこともあるべぇ だべな、派遣問題を口にすると怒る者がおるでよぉ 問題の指摘は駄目だっぺぇ 派遣のことは口にしちゃなんねぇ この村みたいな糞田舎で悲惨な生活するためにはよぉ 駄目のものを駄目と言ってはなんねえだべさ
すみませんが、質問です。 getline(ifstream, string) で、取得する文字数の上限を指定するにはどうし たらいいのでしょうか?
ifstream::getline
894 :
892 :2007/01/12(金) 20:35:16
ちょっと説明を加えますと、データファイルを1行ずつ読み込むときに、1万文 字を超えたら読み込みを打ち切って、その先は無視したいのです。これは不正 なデータでメモリがあふれるのを避けるためです。 string#max_length()に達したら止まりますが、これは1万よりだいぶ大きいの です。変更できるか調べましたが、どうも固定のようです。 <cstring>の getline()なら受け取り文字数を指定できるのですが、受け取り 手の引数がchar* なので、できるならそのままstringでうけたいです。 以上です。よろしくお願いします。
895 :
892 :2007/01/12(金) 20:39:45
>>893 すみません、勘違いをしていました。
<cstring> のgetline ではなく
istream::getline でした。
結局、文字数の上限を指定するにはこれを使うしかないのでしょうか?
896 :
デフォルトの名無しさん :2007/01/12(金) 20:51:43
Cの初心者です。あるプログラムを組んで走らせたところ、とりあえず結果が表示されました。そして最後にgetcharで何かキーを 打ち込んだら終了になるようにしたんですが、キーを打ち込んだらエラーが出て、プログラムの最後の括弧が 抜けられませんでした。そのときのメッセージが Runtime Check Failure #2 Stack around the variable 'pk' was corrupted と出ました。変数のエラーだと思うんですがもうプログラムは最後まで走ってるから 関係ないと思うんですけど、よくわかりません。原因分かる方がいらっしゃれば教えてください。 分かりにくい文章ですいません。
配列に確保したサイズを超えて書き込んでるとか。
898 :
896 :2007/01/12(金) 20:59:42
それでも計算結果は表示されるんですか?もっと早い段階でエラーが出たりしないんですか?
899 :
デフォルトの名無しさん :2007/01/12(金) 21:15:20
new, deleteでメモリを確保/解放した際に、 解放し忘れのオブジェクトがあるかチェックする方法はありますか?
>>898 出る場合もあるし、出ない場合もあるし、鼻から悪魔が出ることもある。
901 :
896 :2007/01/12(金) 21:31:56
配列の範囲外に値を入力してました。でもプログラムは最後まで走ってます。なぜだか分かりますか?
902 :
896 :2007/01/12(金) 21:33:10
>>897 ,900
連投すいません。ありがとうございます。
プログラムの動作上必要な領域を破壊していなければ動くよ
>>901 範囲チェックをしないから。
範囲外アクセスしてどうなるかは神のみぞ知る。
#include <stdio.h> struct type{ int n; char s[8]; }types; struct type main() { types.n = 0; printf ("%d\n", sizeof (types)); return types; } というコードをbcc32でコンパイルしました。 できました。 実行すると、 「問題が発生したため、n.exeを終了します。ご不便をおかけして申し訳ありません。」 とエラーメッセージが表示されます。 興味本意で試してみたのですが、struct type{int n;}types;ではできた為気になります なぜエラーメッセージが表示されるようになったのでしょうか
mainはint以外返しちゃらめぇ
>>901 配列の範囲チェックをしないから。そもそもa[i]は(宣言以外では)*(a+i)と等価。
ポインタ演算の形だとピンと来ないから配列という形でわかりやすくしてるだけ。
だから可変長メンバを持つ構造体なんて反則スレスレの事も出来る。
struct hoge{
int a;
char s[1];
};
// メンバsを20byte分確保するmalloc
struct hoge *p = (struct hoge *)malloc(sizeof(struct hoge)+sizeof(char)*(20-1));
p->s[5] = 'n';// エラーにならない(はず)
ANSI Cではこれは反則。でも大抵の処理系では動く。
C99では専用の書き方(char s[])があるけど。
>>906 mainを呼び出す側からしたら
自販機でジュースが出てくると思ったら、ウンコが出てきたようなもの。
そいつはお得だ
問題はそれをお得だと思わない奴がいるということ。
そんな奴は1億人に1人もいないからほっとけ
環境は窓XP、VC++.NETです。
ttp://ruffnex.oc.to/kenji/text/dll_inj/in_dll.cpp ↑のようなのを発見したんだが、
#define TARGET_EXE_NAME
↑で指定したアプリ(プロセス)に
#define DLL_FILE_NAME
↑で指定したDLLファイルを寄生させて、TARGET_EXE_NAMEが起動している間、DLL_FILE_NAMEも走り続けるって物。
まぁTARGET_EXE_NAMEにDLL_FILE_NAMEをマッピングするということですね。
そこで聞きたい。
↑の場合だとDLLを寄生させているが、実行ファイル(exeファイル)も寄生させることは可能なのか?
IEが起動してる間、IEと一緒に使うアプリも同時に起動し続ける、みたいな・・・
出来るならどういう風にすれば出来るか教えてくれまいか?
ウィルス乙
ぐぐればcode projectその他にいくらでもソースはある 「Dll Injection」 とかとして有名 激しくWinAPIスレどうぞ LoadLibraryできるしろものなら何でもOKだと思うけど、 DllだとDllMainがロードのトリガーとして動作するから扱いやすいってことだと思う(exeでしたことはないが
918 :
914 :2007/01/13(土) 13:30:33
>>916 なるほど、こんなwebがあったとは・・・
英語苦手だから解読に時間かかりそうですが、じっくり探してみたいと思います。
ありがとうございます。
>>917 気にするな。気になるなら今後どちらかに統一するが・・・
>>918 Advanced Windows嫁
質問するなら“普通は”敬語
現在VC++2005 EEのC++言語でコンソールアプリを作っています。 特定の形式のファイルをドラッグアンドドロップすると解析した結果のファイルが 出力されるようにしているのですが。2点問題があります。 1. ドラッグアンドドロップされるファイルのパス名に半角空白が含まれていると、 引数で与えられるchar *argv[]が分割されてしまう。 (例:C:\Document and settings\hoge.txtだとargv[1]="C:\Document" argv[2]="and" argv[3]="settings\hoge.txt") 2. 複数ファイル連続処理に対応しようとして、ifstreamオブジェクトを close → 別ファイル名でopenを行うと、 何故かopenで失敗する。 以上2点、わかりにくい説明で申し訳ありませんが、解決法等わかる方教えていただけませんでしょうか。 よろしくお願いいたします。
>>919 まぁ待て、日本人じゃないのかも知れん。
922 :
デフォルトの名無しさん :2007/01/13(土) 22:50:17
郷に従え
壕に入ったら郷ヒロミ
>>920 引数にプログラムのフルパスしか入れないのなら
char *path;
int i;
for(i = 0; i < argc; i++) {
strcat(path, ' ');
strcat(path, argv[i]);
}
すればいいのでは
2.のopenに失敗しているのは出力ファイル生成でかな?
分かりやすいようにofstream ofs(path);のほうがいんでないか
>>924 そんなことしたら鼻からなんかニュルッっと出てくるよ。
>>920 俺も2で悩んだことあるよ
clear()したら何故かいけたけど
鼻かなにがニュルッっと出てくるの?
よくあるケースでは悪魔がでてくるらしいが、 なにしろ未定義なので何が出てきても文句は言えない。
Cの構造体で質問させていただきます。 typedef struct _particle { float xpos, ypos, //現在地 vx, vy,//速度 v0, vx0, vy0//諸速度 deg,//仰角 deg_r, //方角 r, g, b, alpha; } particle; particle* particles = NULL; particles = (particle*)malloc(sizeof(particle) * num_particle); このようにしてパーティクルを定義し ループでデータをほうりこんでやってるのですが int num_particle = 100; for(k=0;k<num_particle;k++){ particles[k].xpos = rand()%10; * * このパーティクルの数が117をこえると fireworks.exe の 0x10219f99 (msvcr80d.dll) でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x92d80baa を読み込み中にアクセス違反が発生しました。 となりうまく生成できません。 データ破綻がおきてるようなのですが構造体の作り方が問題なのでしょうか
932 :
931 :2007/01/14(日) 18:42:57
void display(void) の中の free(particles); でメモリ解放しちゃってるジャン。
>>932 VC++ 使ってるならデバッグ実行すれば一発でわかるだろうに。
とりあえずソース見ただけで言えることを。
96行目にある free() が臭うな。
あとは、ローカル変数使え。
ループカウンタがグローバルとか、正気の沙汰じゃない。
>>933 if(particles[0].ypos < -200){
//free(particles);
//particles = (particle*)malloc(sizeof(particle) * num_particle);
if(rand()%5 == 2 || rand()%5 == 4){
けずってみたのですがやっぱり msvcr80d.dll で例外がでるみたいです。。。
>>934 ループカウンタはそうですねf^^すぐなおします。
やっぱりfree()が怪しいですかね。。
バイナリのデータを読み込みで質問です 1バイト目に文字 2〜4バイト目にサイズが入ってるとして char cdata; int idata; ifs >> cdata >> idata; こんなのを書くと、intのサイズが4バイトじゃないときやばいですよね? けどcharで4バイト読み込んでintのサイズを計算するのは なんか無駄が多いような気がするけど そういうものでしょうか?
>>936 それ、バイナリ入力してないよ。なんかいろいろ考え直せ。
>なんか無駄が多いような気がするけど いいえ。
939 :
936 :2007/01/14(日) 21:46:39
>>937 charには読み込めたので試してなかったのですが
試してみたらintには読み込めなかった・・
もっかい調べなおしてきます
ありがとうございました
>>938 すみません、省略してしまいましたが
俺がぱっと思いついたのはこんなのです
idata = cdata1 + cdata2*256 + cdata3*256*256 + cdata4*256*256*256;
なんかもっといいやり方があるような気がするんですが・・
普通ならcharの配列に読み込んで構造体とかintのポインタにキャストしたりするな
941 :
936 :2007/01/14(日) 22:38:12
>>940 ありがとうございます
あれから、キャストを使う方法と
ifstreamにreadメソッドというのを発見したので
ifs.read((char*)&int,4);
こういう風な感じで書いてみました
通常はこれでうまくいく?のだと思うんですが
実は今読み込もうとしてるのはsmfファイルで
smfファイルフォーマットはビッグエンディアンらしく
00 00 00 06を読み込むと
06 00 00 00になるみたいです
(idata = idata >> 24;とやってみたところ6が出力されたので、おそらく。
というわけで、今回はchar配列に読み込んで
逆順にシフトする方法で対応することにしました
回答してくださった方、ありがとうございました
942 :
920 :2007/01/14(日) 23:18:16
>>924 さん
>>926 さん
>>927 さん
ありがとうございました。2番は
>>827 さんの方法(clear)で何故かOKになりました。
1番は試行錯誤の挙句、argv[]の型をchar *からwchar_t *型に変更したら
何故かOKになりました。。。原因は不明です。
規格外のプログラムになるので納得は出来ないのですが、
動くものでないとどうしようもないのでこれで行こうと思います。
あと、
>>924 さんの方法だとファイル一つにしか対応できないので
無理でした。
1番についてだけど 普通空白を含むパスは"で括ってプログラムに渡すもんです
>>943 俺920じゃないけど疑問が
exeアイコンにD&Dで渡す際に"付けれるのかな?
プロンプトかbat使うときならいけそうだけど
できるに決まってんだろ
じゃあ書けよ
C言語で #include <stdio.h> int main(int argc,char *argv[]) { int i; printf("引数の総個数 = %d\n", argc); for (i = 0; i < argc; i++) { printf("%d番目の引数 = %s\n", i, argv[i]); } } このプログラムの名称を「SMPL.C」とし、次の手順で実行するものとします。 コンパイル、リンクして、「SMPL.EXE」を作成する。 引数として「ABC DEF GHI」を指定することとし、 A:\>SMPL ABC DEF GHI とコマンドラインから入力する。 (注) Aドライブで実行したとします。 実行結果を確認する。 というのがあったのですが、コマンドラインから入力というのがどうすれば良いかわかりません コマンドラインとは何ですか?具体的にどうすれば入力できるんでしょうか?
つ コマンドプロンプト
わろた
>>948 ありがとうございます、解決しました
そんなところから入力できるとは露とも知りませんでしたorz
MSVC++でDLLを作る場合の質問です。 Cリンケージの関数をDLLにエクスポートする場合、 DEFファイルを使う方法と__declspec(dllexport)を使う方法があります。 ・C++リンケージの関数をDEFファイルを用いてエクスポートする場合、 EXPORTSセクションにはどのように名前を書くのでしょうか。 ネームマングリングされた名前(??5icu_36@@YAAAV?$....とかそんなの) を書くのでしょうか? ・C++リンケージの関数に、cdeclやstdcallのような呼び出し規約の違いは ありますか? ・クラスを__declspec(dllexport)とともに宣言する方法は簡便ですが、 MSDNの記述によれば、これによって全てのメンバがエクスポートされると あります。この場合、ヘッダにインライン記述されているメンバ関数も、 DLLの関数が使われてしまう(インラインされない)ことになるのでしょうか? ・C++リンケージの関数やクラスを、異なるコンパイラ(gccなど)から 使用する手段はありますか?
>>951 1. そのとおりでマングリングするしかない。
2. ある。マングリングと呼び出し規約は別問題。
3. DLLを利用する側のヘッダにもinlineで定義すれば平気では?
もっとも、VC++はDLL内の関数をインライン展開できるとMSのサイトに書いてあるのを見た覚えが俺にはある。
4. 絶望的に無理。おとなしくCリンケージにしろ。ただし、COMの影響で仮想関数の呼出はできるはず(マングリング関係ないし)。
>>952 有難うございます。
つまり、現実的には、
・C++リンケージのDLLはコンパイラ依存にならざるを得ない。
・MSVC++でC++のDLLを作りたければ、何も考えずに
classを__declspec(dllexport)するのが一番楽だし
インライン関数のインスタンス化について心配する必要も無い。
・言語、コンパイラ依存を避けたければおとなしくCOMか.NETにしろ。
ってことでしょうか。
一応言っておくと、classをexportするのは、 ヘッダとDLLのバージョン管理とか互換性確保とかが面倒だぞ。
pimplイディオムを使えば 最小限のインターフェースだけ公開できるね
他スレの話ですみませんが、質問です。
C++は難しすぎ 難易度:2
http://pc10.2ch.net/test/read.cgi/tech/1071697977/114-122n 116で、どうしてenumを使うのでしょうか?
const static でもいいと思うのですが。
template <int n> struct Sum1 {
const static int X = Sum1<n-1>::X + n;
};
template<> struct Sum1<1> {
const static int X = 1;
};
そしてもう一つ、122はどうして実行時に計算されるのでしょうか?
sum<i-1>が再帰して完全に実体化するまで、コンパイルは終わらないと思うし、
もしそうなら、計算はコンパイル時に終わっているのでは?
957 :
951 :2007/01/15(月) 19:50:16
>>954-955 結局、そうした実装の手間と非効率を引き換えにリンク互換性を
追及する行為の行き着く先がCOMだと認識していますが、それで
合ってますか。
>>956 122の場合、コンパイル時に「operator()の数珠繋ぎ」が作られて、
その無駄に長〜い式の答が実行時に計算される。
>>956 えーとそれはenumハックと呼ばれるテクニックで、
const staticが動かなくてもenumのほうは動くというのがよくあるからだと思う。
VC6とかVC6とかVC6とかVC6とかで。
他にもVC6とかVC6とかもあるぞ。
961 :
956 :2007/01/15(月) 21:19:31
>>958 ありがとうございます。申し訳ありませんが、まだよく分かりません。
・enumで書いたコード
・const static int で書いたコード
・opreator() をオーバーロードしたコード
それぞれどのようなコードがマクロ展開後に生成されるのでしょうか?
962 :
956 :2007/01/15(月) 21:22:56
>>959-960 すみません、リロードし忘れていました。
VC6ですか。疑問が解けました。ありがとうございます。
しかし、961はまだ分かりません。
enumはコンパイル時に定数に展開される opreator() は定数を返すだけのコードが生成される それが実行時に数珠繋ぎに呼ばれる
もちろん向こうのスレに書いてあるとおり、 それをコンパイラがコンパイル時に定数展開する最適化を行う可能性はある。
965 :
956 :2007/01/15(月) 22:00:59
>>963-964 ありがとうございます。
もし最適化されなかったら、実行時にsum<1>() 〜 sum<100>()のすべてのイン
スタンスが生成、実行されるということでしょうか?
また、const static int の場合はどうでしょうか?
>>965 >すべてのインスタンスが生成、実行されるということでしょうか?
最適化切ってもそんなことはないと思うが、可能性は否定できない。
>また、const static int の場合はどうでしょうか?
同じことだ。
enumと同じということだな。
968 :
956 :2007/01/15(月) 23:54:07
>>966-967 ありがとうございます。operator() は処理系依存ということですね。
const static int は、enum と違って引数がコンパイル時に決まっている(整
数リテラルである)必要はないので、もしかしたらoperator()同様に実行時解
決されてしまう可能性もあるのかと考えていました。
実際には、コンパイル時に解決されるということですね。
この辺の挙動は、自分の手元の本では全然分かりませんでした。
やはり「プログラミング言語C++第3版」が必要なのかもしれません。
http://www.amazon.co.jp/dp/475611895X
クラス内のstatic const修飾されたものと名前空間内(一見名前空間の外に見える部分も含む)のconst修飾されたものは、 コンパイル時定数となる。その証拠に、配列の要素数に指定できたりテンプレート引数に指定できたりする。 逆にoperator ()はそういうところで使えないことからもコンパイル時定数でないということが伺える。
970 :
956 :2007/01/16(火) 00:34:37
>>969 なるほど、
struct Hoge {
static const double d = cos(1);
};
これはエラーになるようです。
しかし、
namespace Hoo {
static const double d = cos(1);
}
これはGCC3.4.3では通ってしまいました。VC++ 2005では通りませんでした。
GCCの独自拡張かもしれません。
この挙動を抑制する方法を知りたいのですが、分かりませんでした。
971 :
956 :2007/01/16(火) 00:46:18
static const double d1 = cos(1.0);
int i1[(int)d1];
こういうコードも、VC++だと通りませんが、GCCだとコンパイルを通ってしまいます。
原因は、GCCは配列に可変長引数が使えるからのようです。
http://portable-c.jugem.jp/?eid=23 こういう独自拡張はできるだけ抑制したいのですが、やはり方法が見つかりません。
>>970 静的constメンバ変数のクラス内初期化が可能なのは整数型のみ。
よって前者がコンパイルできないのは当たり前。
後者はVC++でオーバーロードが解決できていないだけ。std::cos(1.0)で試せ。
>>971 -可変長引数
+可変長配列
g++ -pedantic
gcc -ansi
975 :
956 :2007/01/16(火) 03:22:47
>>973 ありがとうございます。いろいろ勘違いしていたようです。
-pedantic はうまく行きました。
//こちらはどちらのコンパイラでもコンパイルが通らない。
struct Hoge {
static const int i = (int) (10*cos(1.0));
};
//こちらはどちらのコンパイラでも通る。
namespace hoge {
static const int i = (int) (10*cos(1.0));
}
不思議なのは、後半のコードは、
>>969 さんが
> 名前空間内(一見名前空間の外に見える部分も含む)のconst修飾されたものは、
> コンパイル時定数となる。
とおっしゃっていることと、一致しないように見えることです。
>>974 -ansi では、以下の行がエラーになりませんでした。
int i[(int) (10*cos(1.0))];
976 :
956 :2007/01/16(火) 03:28:18
補足ですが、前半のコードのエラーは、以下のようになります。 VC++ → error C2057: 定数式が必要です。 GCC → error: ‘double cos(double)’ cannot appear in a constant-expression error: floating-point literal cannot appear in a constant-expression error: a function call cannot appear in a constant-expression 確かに static constant int はコンパイル時定数のようです。
969には「定数式で初期化されているもの」という条件が抜けているような気がする。
// 設定 MCI_SET_PARMS set; set.dwTimeFormat = MCI_FORMAT_TMSF; mciSendCommand( deviceID, MCI_SET, MCI_SET_TIME_FORMAT | MCI_WAIT, (DWORD)&set ); // トラックの長さ調べる MCI_STATUS_PARMS status; status.dwItem = MCI_STATUS_LENGTH; status.dwTrack = 1; mciSendCommand( deviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD)&status ); // 再生する MCI_PLAY_PARMS play; play.dwFrom = MCI_MAKE_TMSF( 1, 0, 0, 0 ); play.dwTo = MCI_MAKE_TMSF( 1, MCI_MSF_MINUTE(status.dwReturn), MCI_MSF_SECOND(status.dwReturn), MCI_MSF_FRAME(status.dwReturn) ); mciSendCommand( deviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD)&play ); としてるのですが、 曲の長さは2分なのに、なぜか1秒くらいしか、再生されません どうしたらいいでしょうか
vector(型不定)* を受け取る関数を作ろうとして template <class T> void Func(std::vector<T> *pvec) { 〜略〜 } main() { std::vector<int> vec; Func<int>(&vec); } とやってみたんですが、上手くいきません。 こういうテンプレート型を受け取る関数って どう書けば良いのでしょうか?
>>980 リンカが「未解決の外部シンボル」というエラーを吐きます。
書き忘れてましたが、VC7使用です。
Funcの実装をヘッダ内に書いてないんだろ
>>982 そのとうりです。
テンプレート関数って全部ヘッダで記述しないとダメなんですか(汗
VCはexportをサポートしてないからな
そんなことより、
>>978 をどうにかしてくれ〜〜(泣)
あつかましいにも程がある
>>979 万全を期して、アロケータの分もテンプレート引数にしておけ。
template <class T, class A>
void Func(std::vector<T, A> *pvec)
もっと万全を期してイテレータ受け取ったほうが良くね?
989 :
質問1(続き) :2007/01/17(水) 21:07:52
ソースを次に書きます。 /* 派生クラスで純粋仮想関数をオーバーライドするプログラム */ #include <iostream> #include <string> using namespace std; // basepair抽象クラスの定義 class basepair { // デフォルトコンストラクタの使用を禁止する basepair() {} protected://@ A //public://@ B // データメンバ string key, value; // 引数をとるコンストラクタ basepair(const char *pstrkey, const char *pstrval) : key(pstrkey), value(pstrval) {} // getvalue()メンバ関数を定義する const char *getvalue() { return value.c_str(); } // getkey()メンバ関数を定義する const char *getkey() { return key.c_str(); } // keycomp()純粋仮想関数を宣言する virtual int keycomp(basepair &rp) = 0; // valcomp()純粋仮想関数を宣言する virtual int valcomp(basepair &rp) = 0; // getpairvalue()純粋仮想関数を宣言する virtual const char *getpairvalue(const char *pstrkey) const = 0; // getpairkey()純粋仮想関数を宣言する virtual const char *getpairkey(const char *pstrval) const = 0; }; //(以下に続く)
990 :
質問1(続き) :2007/01/17(水) 21:08:32
// mypair派生クラスの定義 class mypair : public basepair { public: // 引数をとるコンストラクタ mypair(const char *pstrkey, const char *pstrval) : basepair(pstrkey, pstrval) {} // keycomp()純粋仮想関数に独自の実装を行う virtual int keycomp(basepair &rp) { return strcmp(key.c_str(), (rp).getkey());// A A エラー箇所40行目 // return strcmp(key.c_str(), static_cast<mypair &>(rp).getkey());// A B } // valcomp()純粋仮想関数に独自の実装を行う virtual int valcomp(basepair &rp) { return strcmp(value.c_str(), (rp).getvalue());// B A エラー箇所45行目 // return strcmp(value.c_str(), static_cast<mypair &>(rp).getvalue());// B B } // getpairvalue()純粋仮想関数に独自の実装を行う virtual const char *getpairvalue(const char *pstrkey) const { if (key == pstrkey) return value.c_str(); else return NULL; } // getpairkey()純粋仮想関数に独自の実装を行う virtual const char *getpairkey(const char *pstrval) const { if (value == pstrval) return key.c_str(); else return NULL; } }; //(以下に続く)
991 :
質問1(続き) :2007/01/17(水) 21:09:16
int main() { // mypairクラス型の配列を作成する mypair mp[] = { mypair("358-0015", "さいたまけんいるましにほんぎ"), mypair("500-8165", "ぎふけんぎふしおいまつちょう"), mypair("272-0034", "ちばけんいちかわしいちかわ"), mypair("060-0000", "ほっかいどうさっぽろしちゅうおうく"), mypair("670-0974", "ひょうごけんひめじしいいだ"), mypair("770-0874", "とくしまけんとくしましみなみおきのす") }; if ( mp[5].keycomp(mp[1]) ) { cout << "mp[5]とmp[1]のKeyは異なる\n"; } else { cout << "mp[5]とmp[1]のKeyは同じ\n"; } if ( mp[5].keycomp(mp[5]) ) { cout << "mp[5]とmp[5]のKeyは異なる\n"; } else { cout << "mp[5]とmp[5]のKeyは同じ\n"; } getchar(); return 0; }
992 :
質問1(続き) :2007/01/17(水) 21:13:35
上記のソースで↓のようなエラーが出ます。 d:\abstract2bad\abstract2bad\abstract2bad.cpp(40) : error C2248: 'basepair::getkey' : protected メンバ (クラス 'basepair' で宣言されている) にアクセスできません。 d:\abstract2bad\abstract2bad\abstract2bad.cpp(20) : 'basepair::getkey' の宣言を確認してください。 d:\abstract2bad\abstract2bad\abstract2bad.cpp(7) : 'basepair' の宣言を確認してください。 d:\abstract2bad\abstract2bad\abstract2bad.cpp(45) : error C2248: 'basepair::getvalue' : protected メンバ (クラス 'basepair' で宣言されている) にアクセスできません。 d:\abstract2bad\abstract2bad\abstract2bad.cpp(18) : 'basepair::getvalue' の宣言を確認してください。 d:\abstract2bad\abstract2bad\abstract2bad.cpp(7) : 'basepair' の宣言を確認してください。 (上のprotected:のをpublic:にすれば勿論問題はないのですがprotectedの ままで行う場合) コンパイルを通すにはA、Bで、rpはキャストすればいい(それぞれ、A→B)ようですが、 これって、static_castがベストでしょうか? dynamicだと問題があるでしょうか?
>>992 basepairはmypairから見てprotectedだが、引数rpから見たら
見えないのでアクセスできない。
従ってキャストは論理的に正しくない。publicにすべき。
しかもstatic_castではなく、dynamic_castにすべきだと思う。
キャストするならダウンキャストに当たるからdynamic_castだな。 無理矢理感が否めないけど。
ふーん。こういう場合はKoenigの自動照合が働かないのか。 rpはbasepair型なので、basepairの定義からも探されると 思っていたけど違うんだな。
あれ?次スレなくね?
あ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。