【初心者歓迎】C/C++室 Ver.44【環境依存OK】
389 :
デフォルトの名無しさん :
2007/11/19(月) 13:32:34 #include <stdio.h> #include <string.h> char s[] = "This is a pen. That is an apple."; void main(void) { char check[256],str[256]; int i; printf("This is a pen. That is an apple.\n\n"); gets(str); for(i=0;str[i]==s[i];i++) { check[i]=strcmp(str[i],s[i]); if (check[i]==0) {printf("ok");} else {printf("ng");}}} 初期化した文字列と入力した文字列strに対しThis is〜がstrで始まっているかどうかを 判定するプログラムですが、check[i]=strcmp(str[i],s[i]);にてエラーが出ます。 教えてください(例えばThis→OK,Th→OK,Thos→NG.....)
390 :
デフォルトの名無しさん :2007/11/19(月) 14:05:06
#include <stdio.h> char s[] = "This is a pen. That is an apple."; int main(void) { char check[256],str[256]; int i,checker; printf("This is a pen. That is an apple.\n\n"); gets(str); for(i=0;str[i]!='\0';i++) if(str[i]==s[i]) { checker=1; } else { checker=0; break; } if(checker==0) { printf("NG!その文字列から始まっていません。\n"); } else { printf("OK!その文字列から始まっています。\n"); } } これでいけた
strcmp って string を compare するんだよな…
lexicographical_compare アルゴリズムについて教えてください。 この関数はlexicographical_compare(s1, s2); とした場合、辞書順でs1がs2より前にあるときにtrueを返し、 そうでないときfalseを返すため、文字列の一致は判定できない と思います。 この関数を使って二つの文字列(string)が等しいことを判定するためには lexicographical_compare(s1, s2); //false (s1はs2の前にはない) lexicographical_compare(s2, s1); //false (s2はs1の前にはない) がともにfalseを返すことを確認しなければいけないのでしょうか?
equal とか使えなかったっけ?
394 :
392 :2007/11/19(月) 15:47:44
実はEffective STLで大文字、小文字を区別しない比較 方法として以下のコードがあるのですが、これでは一致を 判定できないのでは?と思ったんです。 bool ciStringCompare(const string &s1, const string &s2) { return lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), ciCharLess); } // 1文字の比較 bool ciCharLess(char c1, char c2) { return tolower(static_cast<unsigned char>(c1)) < tolower(static_cast<unsigend char>(c2)); }
>>394 言いたいことがわからん。大文字小文字区別しないならその範囲で
しか一致は判定できないのでは?そんだけじゃないの?
396 :
392 :2007/11/19(月) 17:03:12
>>395 上記のプログラムでいうと
lexicographical_compareでは一方の文字列が他方のものより
辞書順で前にあるかないかは判定できますが、一致は判定
できないのでは?という意味です。
たとえば、ciStringCompareで二つのstringが一致
するかどうかを判定できるなら
ciStringCompare("ABC", "abc");
はtrueを返すと思ったのですが、呼び出している
lexicographical_compareの仕様ではfalseになります
よね?結局文字列の一致は判定できないのではないかと。
ソース Effective STL 第35項
398 :
デフォルトの名無しさん :2007/11/19(月) 18:01:30
CPUとかメモリを良いものに交換したらコンパイルは速くなりますか? また、どの部分に依存してますか?
399 :
デフォルトの名無しさん :2007/11/19(月) 18:09:15
>>398 CPU,メモリも大事だけど、HDDが高速な方がいい。
ヘッダやライブラリ等がIDE接続のフラッシュメモリにあるとコンパイルは早い。
たぶんね。
コンパイラにもよるが、マルチコアやマルチCPUだと複数ファイルいっぺんに コンパイルするやつもある。
401 :
デフォルトの名無しさん :2007/11/19(月) 18:31:19
各バスも太い方がいい?
メモリ(の容量は)マジ大事 スワップが発生したらかなりの速度低下になるし、逆にパフォーマンス改善としては一番コストパフォーマンスがいいかも 最初から2Gとか積んでたらほとんど変わらないだろうがね ちなみにクロック速度は殆ど関係ないと思うけど、実際はどうなんだろう
403 :
392 :2007/11/19(月) 18:54:25
>>397 正誤表確認してませんでした。
ありがとうございました。すっきりしました。
>>388 thisを返すoperator &をメンバとして定義すれば可能なはず。
誰がやるかそんなもん、って程度のことだが。
>>368 すいません、t.Attachのところなんですけど、_bstr_tにAttachという
メソッドが見あたらなかったんですが…。
何かをインクルードすればいいのでしょうか?
AttachといえばCComPtr
>>406 CComPtr< _bstr_t > t;
とかって…。
違う気がする。
すみません!教えてください!
>>368 そのままではコンパイラ通らないので…。
CComBSTR? あてずっぽうだけど
VC++EpressEdition2005でOpenGL使って
キューブ状態のものにLogo.bmpをテクスチャで貼り付けてクルクル回したスクリーンセーバを作りたいと考えました
OMEGA POINT - プログラミング(OpenGL,数学,画像処理,Win32API, C++) -
http://omega-point.ddo.jp/programming/opengl/index.html の上から2コ目のzipファイルが使えそうだったのでホイホイ弄ってたら画像の読み込みで壁にぶつかりました
現在はキューブがクルクル回っているところですが、画像は読み込めてません
MFC使ってないのでBitmap定義が使えないみたいなんです ( ; ; )
ResouceFilesにはLogo.bmp(256*256)を登録してあるのでどうにかして触る方法がありませんか?
何かを勘違いしてる場合は指摘してくださいー
Win32APIでLoadBitmapかLoadResource使えばいいと思うが
413 :
デフォルトの名無しさん :2007/11/20(火) 20:51:20
openするファイル名を変数にしたいのですが 例えば char File_Name[30]; fout.open(File_Name,ios::out); とした場合、File_Nameに文章を詰め込む(File_Name="Function_Name") みたいなことはできますか? いや、できないことはなさげだけど、string型が詰められないとなると手がない…
日本語でしゃべれよ
string型なんてものがあるのはもっと上級言語だよ。 Cでは char Filename[] と char * Filename は同じモノ つまりFilename[]="name"としてれば
>>415 >Cでは char Filename[] と char * Filename は同じモノ
違う。前者はあくまで配列で、後者はポインタ。
関数の仮引数としてなら同義だ。
void func(char Filename[]);
void func(char *Filename);
>>413 どうしてもというならstrcpyでも使えば?
stringのc_str使えばいいとは思うけど。
string File_Name;
fout.open(File_Name.c_str(),ios::out);
420 :
419 :2007/11/20(火) 21:54:23
訂正 string File_Name("Function_Name");
char * mystrcpy( char * buf, char * src ) { strcpy( buf, src ): return src; }
初心者歓迎のスレだけど、普通は質問者の方だよな、初心者は。
釣堀はここですね?
水の干上がった釣り堀で喚いてるだけだけどな
425 :
デフォルトの名無しさん :2007/11/20(火) 23:21:45
配列とポインタの実質の違いは、実体がどこにあるかだけだろ
ほう
>>425 別に配列じゃなくてもポインタ使うけど。
初々しい。C言語の初級と中級の中間ってとこだろうな。
実体とか意識しだしたら大方中級な感じがする。 ここまで理解できてたらこれから先も呑み込めて行けそうじゃね? 間違いを受け止める心があればだけど・・・
Linux環境 daemonを作りたいときに、 #include <stdlib.h> int daemon(int nochdir, int noclose); 呼ぶのと、 #include <sys/types.h> #include <unistd.h> pid_t fork(void); を2回呼ぶのって、実用上何か大きな違いはありますか?
daemonは中でfork呼んでるだろう。
>>432 じゃあ、fork()しかない環境ではforkを2回にして、
daemon()がある環境ではdaemon()使っとけって感じですかね。
おまいらみんな死んでしまえ。forkするなぼけが と、djb教授がお怒りです(嘘
436 :
デフォルトの名無しさん :2007/11/22(木) 12:04:21
fstreamで書式付きで出力できますか
437 :
デフォルトの名無しさん :2007/11/22(木) 12:06:31
解決しました fprintf(fp , )は出来ないですけどsprintfでchar配列に入れて出力すれば出来ますね
438 :
デフォルトの名無しさん :2007/11/22(木) 12:50:29
マイクロソフトのwindowsの継承とかの情報はどこで手に入れられるんですか? 機能の上位機能についてです
439 :
438 :2007/11/22(木) 13:11:03
2500メガのMSDNライブラリにのってますか? うちのパソコン鈍いので保存に二日かかりそうなんですが あとこれってテキストファイルやhtmlに変換できますか
>>436 <<演算子とマニピュレータ使えばできるんじゃない?
>>438 MFCのこと?
>>439 MSDNライブラリの各記事の実体はHTML。
ただし、複数ファイルをまとめて圧縮した形で格納されている。
ms-help:で始まるURLを使えばIEからも見れる。
組み込み型の一時オブジェクトは値を変更できない。 ++0; がエラーなのと同じ。
参照以外を返す関数の戻り値は右辺値(3.10.5)で 前置++の対象は変更可能な左辺値じゃない許されない(5.3.2) から? 規格書買っちゃったけどイマイチ読みかたがわからねぇや
445 :
442 :2007/11/23(金) 05:44:47
>>443 ,444
なるほど。
ありがとうございました。
int foo() { return 0; } ++foo(); // エラー
なんとなく書いてみた #include <stdio.h> int *get_number(void){ static int number[2]={0,999}; return number; } int main(void){ printf("%d\n", ++*get_number()); printf("%d\n", ++*get_number()); printf("%d\n", (*get_number())++); printf("%d\n", (*get_number())++); printf("%d\n", *get_number()+1); printf("%d\n", *(get_number()+1)); return 0; }
>>448 なんとなく書いてみただけからスルーしてもらっておkです
#include <stdio.h>
typedef void (*func_t)(void);
typedef func_t (*func2_t)(void);
void hello(void){printf("Hello\n");}
func_t hello_func(void){return hello;}
func2_t hello_func_func(void){return hello_func;}
int main(void){
hello_func_func()()();
return 0;
}
ここはお前の日記帳j(ry
処理Aと処理Bがあって、 Aは1秒ごとに、Bは5秒ごとに呼ばれるものとします。 この1秒と5秒はおおよそで良いので、sleepで止めます。 このAとBを並行して実行させたいとき、 普通はマルチスレッドにするものですか? Linuxです。
おおよそでいいならA5回ごとにB呼べば?
453 :
451 :2007/11/23(金) 17:16:07
>>452 そこまでは「およそ」じゃないんです。
リアルタイム性は要らない程度の意味でした。
設定秒数を渡して5秒とか1秒ってのは変わりうるので。
んじゃ、sleepで1秒待つループを作って、設定秒数ごとにそれぞれを呼ぶと。
for (unsigned cnt; ;) { sleep(1); ++cnt; if (cnt % intervalA == 0) A(); if (cnt % intervalB == 0) B(); }
456 :
451 :2007/11/23(金) 18:00:21
>>454-455 それだと、usleepなんかにして1秒の倍数じゃないときに駄目なんで。
ひとつの処理にどれくらいの時間がかかるかと、 どれくらいの誤差まで許されるかが問題だな
>>456 だからなんなんだw
455のソースをms単位に変更するだけじゃないか
ns単位(ry
まあ、マルチスレッド使えるんなら使うのが素直な気はする。
すいません。 いきなりスコープ解決演算子を二つ続けて、関数を呼び出す意味が分からないのですが、 普通は [クラス名] :: [関数名]() のようにして、どのクラスのメソッドを呼び出しているか 指定する為に使うんですよね? 誰かクラス名が無い場合の意味を教えてください
わからないままでいいんじゃないかなぁ そこらへんは趣味の世界だし
>>461 そのクラスに属していない、グローバルネームスペースの関数を呼び出すことを明示するために使う。
MFCのソースはその典型。
>>461 どこのクラスにも名前空間にも属していない名前を明示的に指定したいときに使う。
void f(); //(1)
class Hoge
{
void f(); //(2)
void g()
{
::f(); //(1)を呼ぶ
f(); //(2)を呼ぶ
this->f(); //(2)を呼ぶ
}
};
>>462-
>>464 ありがとうございます
なくても良かったんですね^^;
聞いて本当によかった。もうすぐ発狂するところでした。
>>465 分かっているとは思うけど、「なくても良い」ではないよ。
>>464 の(1)を呼ぶ例のように、場面によっては必要だからね。
('∀`)そうだと思ってました本当です。
無くてもいい場面も多いけどな
簡単な使い捨てコードなら namespace 気にしないでもいいと思う。 かったるいし。
471 :
デフォルトの名無しさん :2007/11/24(土) 22:04:08
質問です。 Visual Studio .NET 2005 C++ の WIN32 プロジェクトで、 TRACE("hogehoge="+hogehoge) のように、自分用デバッグログを出力ウィンドウかどこかに出したいのですが、方法がわかりません。 標準出力に出力してもどこにも出力されていません(と思う) どなたかご教授お願いいたします。
>>471 基本はOutputDebugString。ただし引数は文字列の一つのみ。
CRTのデバッグルーチンも悪くないが、引数が真面目過ぎて多少面倒。
void dbgprintf (LPCTSTR fmt, ...)
みたいなのを自分で用意しておくのが無難じゃないかな。
質問です。
C言語を使って構文解析ソフトCaboChaを使いたいのですが
ttp://chasen.org/~taku/software/cabocha/libcabocha.html ↑このサイトの通りに以下のプログラムを実行してみたのですが
Undefined symbol: cabocha_destroy_
Undefined symbol: cabocha_new_
Undefined symbol: cabocha_sparse_tostr_
↑このようなエラーが表示されてうまくできません。
どなたかわかるかたいらっしゃいませんか?
〜実行したプログラム〜
#include <cabocha.h>
#include <stdio.h>
int main (int argc, char **argv)
{
cabocha_t *c;
char p[1024] = "太郎は次郎が持っている本を花子に渡した。";
c = cabocha_new(argc, argv);
printf ("INPUT: %s\n", p);
printf ("RESULT:\n%s", cabocha_sparse_tostr(c, p));
cabocha_destroy(c);
return 0;
}
474 :
デフォルトの名無しさん :2007/11/24(土) 22:54:04
csvファイルを読み込み、各データをint型の変数に代入するプログラムを作りました。 以下がソースです。 ifstream fin; TCHAR line[252]; LPTSTR buff[3]; int result[64][3]; stringstream ss; fin.open(_T("temp.csv")); if(!fin.is_open()) // 開いていなければ、FALSEを返す { return FALSE; } int i = 0; while (!fin.eof()){ fin.getline(&line[0],sizeof(line)); buff[0] = strtok(line,","); buff[1] = strtok(NULL,","); buff[2] = strtok(NULL,","); ss.str(""); //stringstreamをクリア ss << buff[0] << _T(" ") << buff[1] << _T(" ") << buff[2]; ss >> result[i][0] >> result[i][1] >> result[i][2]; //カウンタ i++; } fin.close();
475 :
デフォルトの名無しさん :2007/11/24(土) 22:54:37
csvファイルの中身は以下のような並びになっています。 2,2,49, 2,4,0, ... 2,46,27 2,48,0 fin.close()のひとつ前の行でブレークポイントを入れると「アクセス違反」のエラーがでます。 i++の行でブレークポイントを入れると、i=0のときはうまくresult配列にデータが入ってくれますが、 i=1以降は、何も代入されないようです。 これを直す方法をご教授くださいませんか。 なお、今回のcsvファイルにはint型に代入するデータしかありませんが、 以下のような文字交じりのcsvファイルも使用したいので、string型の変数に代入する予定です。 36,1,1,3,Orange,50,長崎 24,1,2,2,Red,50,静岡 ... ↑のプログラムがうまくいっていたら、stringstreamから>>演算子でstring型の変数に代入するつもりでしたが、 stringに代入するにあたって、何か注意するべき点がありましたら、ご教授ください
477 :
471 :2007/11/24(土) 23:17:36
>>472 さん
お答いただいてありがとうございます。
OutputDebugString("hoge");
でコンパイルすると、
error C2664: 'OutputDebugStringW' : 1 番目の引数を 'const char [5]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照)
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
とコンパイルエラーにになり(昔はでなかったような)、そこで
const char a[] = "hoge";
OutputDebugString((LPCWSTR)a);
とやってみたところ、コンパイルは通り、実行もできるのですが、残念ながらあいかわらずどこに"hoge"が出力されるのかわかりませんでした。
何か良い方法がありましたらお願いします。
OutputDebugString(_T("hoge")); の方が好みだなー
480 :
471 :2007/11/25(日) 00:00:46
>>478 さん
OutputDebugStringA !!目から鱗ありがとうございます!!!
コンソールにも出したかったのですが、これは一応自己解決しましたのでご報告。
FILE *stream;
if (!::AttachConsole(ATTACH_PARENT_PROCESS)) { //XP以降はアタッチ
::AllocConsole(); //無理な場合は新たに開く
}
freopen_s(&stream, "CON", "r", stdin); // 標準入力の割り当て
freopen_s(&stream, "CON", "w", stdout); // 標準出力の割り当て
cout << "hoge" << endl;
::FreeConsole(); //アタッチ解放
以上です、ありがとうございました!
イベントログに出力しちゃいなYO!
482 :
473 :2007/11/25(日) 01:26:22
483 :
デフォルトの名無しさん :2007/11/25(日) 13:11:04
if ("a" < "b") cout << "ok" << endl; else cout << "ng" << endl; この場合はokと表示されるのですが if ("aa" < "bb") cout << "ok" << endl; else cout << "ng" << endl; この場合はngと表示されます。 aのほうが文字コードが小さいのでokと表示されることを期待しているのですが なぜこうなってしまうのでしょうか?
文字列リテラルを不等号で大小比較比較しても、それはただ文字列リテラルの値(=アドレス値)の 大小を比較しているだけだよ。 文字順の比較をしたければ strcmp などを使え。 上記の意味が分からなければ、まずはちゃんとした入門書などを読んだほうがいい。
string
>>483 それは文字列が格納されているメモリアドレスを比較してるだけ
文字列の内容を比較したいなら strcmp を使え
>>483 つ[ std::string("aa") < std::string("bb")]
構造体を色んなソースで使いまわしたいのですが上手くいきません。 共通ヘッダ: typedef struct TAG TYPE_NAME; TYPE_NAME nantoka1; ソースA: struct TAG { int a; int b; }; ソースB: nantoka1 = { 3, 5 } こんな風にしてみたんですが、ソースBは 'TAG' を認識してくれません。 どうすればいいでしょうか
>>488 共通ヘッダ:
struct TAG { int a; int b; };
extern struct TAG nantoka1;
ソースA:
いらない。
ソースB:
struct TAG nantoka1 = {3, 5}
リンクが絡まりそうなヘッダだな。 nantoka1が必要なソースでexternするようにした方がいいと思う。
491 :
488 :2007/11/25(日) 17:05:02
489さんのやり方でやってみたら上手くいきました。ありがとうございます。
ねーねー 連結リストの先頭のHeadをポインタで宣言しないのはどうして? ポインタで宣言したほうが構造体分無駄にならなくなくない?
boost初心者です。 以下がVC+2005ではコンパイル・実行できますが、Linux g++ 4.0ではコンパイル できません。エラーコードはテンプレートだらけでよくわかりません。 何が違うのでしょうか? #include <iostream> #include <boost/bind.hpp> using namespace std; using namespace boost; int someKeisan(int n1, int n2) { return n1 * n2; } int main() { cout << bind(someKeisan, _1, 10)(6) << endl; return 0; }
>>492 ポインタで宣言できるなら、そうすればいいんじゃないか?
むしろ、先頭用の構造体を持ってる実装のほうが珍しいと思うが。
>>494 そうなの?
Googleとかで引っかかるサイトだと普通に宣言してるのが多いから
そういうもんかと思ってたよ
何にしてもありがとう
疑問が一つ解けたよ
>>493 Cygwinでg++ 4.1.1だけどコンパイルできたよ。
>>495 「連結リスト」でググって一番上にあるサイトからポインタで実装してるぞw
その次のはダミー作ってたけど。
>>496 ヘッダーも存在してるし、
実装が未熟なんですかね?
ちなみに OS : Fedora Core 4 g++ 4.0.0でデフォルトのものを使ってます。
>>499 boostを入れてないってことないか?
>>500 functionやtokenizerは動作しますんで
boostは入ってると思います。
/usr/include/boostにhppファイルはあります。
うちのFedora7でもだめだった。
>>495 先頭要素が必ず存在するようにしたほうがコードを簡略化できるケースもあるから
あえてポインタではなく構造体を使用するということもあるよ。
よほど大きな構造体でない限り、高々1個を省略することは大きな意味はないから。
>>502 そうですか。
tr1/functionalヘッダとtr1::placeholdersを指定しても
ダメでした。
VC++で我慢します。
505 :
502 :2007/11/26(月) 01:38:50
気になったんで試してみた。同じ g++でも環境によって違うみたい。FreeBSDでは成功した。 以下結果と環境だけ。エラーメッセージは長いので省きます。 [FreeBSD 6.2R : コンパイル成功] >GNU C++ version 3.4.6 [FreeBSD] 20060305 (i386-undermydesk-freebsd) > compiled by GNU C version 3.4.6 [FreeBSD] 20060305. >GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 [ Fedora7 : コンパイル失敗 ] >GNU C++ version 4.1.2 20070925 (Red Hat 4.1.2-27) (i386-redhat-linux) > compiled by GNU C version 4.1.2 20070925 (Red Hat 4.1.2-27). >GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=129178 [ Cygwin : コンパイル失敗 ] >GNU C++ version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) (i686-pc-cygwin) > compiled by GNU C version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125). >GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 コンパイル失敗した二つは同じエラーが出てる。 >a.cpp:13: error: no match for call to ‘(boost::_bi::bind_t<int, int (*)(int, int), boost::_bi::list2<boost::arg<1>, boost::_bi::value<int> > >) (int)’
506 :
503 :2007/11/26(月) 01:49:36
boostのversionの問題かも。 以下boost/version.hpp 内の定義比較。 [FreeBSD 6.2R] >#define BOOST_VERSION 103401 >#define BOOST_LIB_VERSION "1_34_1" [Fedora7][Cygwin] >#define BOOST_VERSION 103301 >#define BOOST_LIB_VERSION "1_33_1" コンパイル成功したFreeBSDだけ、1_34_1 だ
507 :
502 :2007/11/26(月) 01:51:57
上ネーム欄間違い、503じゃなくて502。 これがboostのバージョンが原因なら、boostバージョンアップで解決するかもね。
cout << bind(&someKeisan, _1, 10)(6) << endl; にしたらどう?
509 :
502 :2007/11/26(月) 02:19:41
Cygwin に boost 1_34 入れてみたら、コンパイル通った。
なんか修正されたんだな。リリースノートどこにあるんだろ・・・。
とりあえずすっきりした。これで寝れる。
>>508 だめ。
VS2005スレで聞いたほうがよいのか迷いましたが、まずはこちらで質問させてください VS2005でC++を使って組んでいるのですが、「関数宣言はされているものの実態が存在しない」というリンクエラーが大量に出て困っています。 (私の言う関数とは、クラスの関数。つまりメソッドです) 自分で作ったのなら当然実体も定義するのですが、これは他人のソースで、さらにその人は「とりあえずヘッダに必要そうな関数をかたっぱしから宣言しておく」人のようです。 実体が存在しない関数に関しては「一度も呼び出した無い」そうで、コンパイルオプションだかで「一度も呼び出してない関数は、宣言もろとも無視する」ことができる(そうやって実行ファイルを作りテストした)そうなのですが、どうすればよいのでしょうか? (残念ながら、そのソースを書いた人自身に質問することができないのです)
まさかデフォルトコンストラクタ?
>>511-513 すいません、自己解決しました
>>510 は友人の悩みをヒアリングして私が(私の体験っぽく)書き込んだのですが、511の指摘で「確かに警告ならわかるんだけどなぁ」と思い私自身でソースを調べてみました。
単に友人が渡されてるlibファイルを組み込んでいないだけの話でした(ちなみにその関数はちゃんと呼び出されていました。呼び出されていたからこそ警告ではなくエラーとなっていました)
お騒がせしてすいませんでした
>>514 そんなミスは誰でもよくやることですから気にしなくてよいのですよ。
と、ご友人にはお伝えください。
boostを1.3.4にバージョンアップしたら コンパイル・実行できました。
すみません、くだらない質問なのですが これまでマクロとか使ったことがなくて…教えてください。 #define IX(i,j) ((i)+(N+2)*(j)) と書かれていて 1次元の配列ポインタに x[IX(i,j)] こう書かれていた場合、どこをアクセスしてるのでしょうか。 また #define SWAP(x0,x) {float * tmp=x0;x0=x;x=tmp;} これも意味がわかっていません。 おねがいします、助けてください
>>517 落ち着いて展開すれば大丈夫。
x[ IX( i, j ) ]→x[ i + N + 2 * j ]
一次元配列を二次元配列のように扱う時に使ったりするかな?
SWAPのほうは単純に2つの値(float *)を入れ替えてるだけ。
SWAP( fp1, fp2 );とかけば
{ float * tmp = fp1; fp1 = fp2; fp2 = tmp; }
ありがとうございます(;; ものすごい優しく応えてくれて、なんかほんとに涙出てきました。 >一次元配列を二次元配列のように扱う時に使ったりするかな? まさしくその通りです。 1次元配列の i+N+2*j ということですね。 {1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2} の場合 2段目の6にアクセスしたいとき N=4だから IX(1,1) = 1+4+2*1 = 6 つまり、前から6番目の6にアクセスできますね! ありがとうございます。。。ほんとようやくわかりました(;; SWAPの方は、入る値は float * 型じゃないとダメ、ですよね? これに1次元の配列ポインタが入ると、配列そのものが入れ替わる、ということですよね? ほんと、、、わからなくて、悶々として、誰にも聞けなかったので 本当に助かりました。ありがとうございました(;;
>>519 >これに1次元の配列ポインタが入ると、配列そのものが入れ替わる、ということですよね
単に変な文章になっているだけかもしれないけど、配列そのものが入れ替わるのではなく、
ポインタが指しているものが入れ替わるだけだよ。
int a[100], b[100];
int *p = a;
int *q = b;
SWAP(a, b); // コンパイルエラー
SWAP(p, q); // pがbを指し、qがaを指すようになる。a, bの実体は何も変わらない。
最大で2000ほどの双方向リストがあるのですが これを高速にソートするにはどういった方法があるのでしょうか? 頻繁にソートが呼び出されるのでバブルソートでいいものなのかどうなのか判断つきません
マージソートとかクイックソートとか 頻繁の程度にもよるし、どの程度の遅さまで許容されるかにもよるし、 実際やってみて遅くなければ別にいいんじゃね?
だからって、バブルソートなんか実装したら間抜けだけどな。
頻繁にソートする必要があるのなら、常にソート済みの状態にしておくべき。
マージソートでいってみようと思います ありがとうございました
普通に STL のソートじゃダメなの?
Cなのかもしれないし、C++コンパイラは使えるけどSTLがないのかもしれない。
mapのキーに構造体を利用してデータを格納しているのですが、 []を使用した際に想定した動きをしてくれません。 下記がそのソースです。 #include <iostream> #include <map> #include <string> // キー struct StaffKey { int section; std::string code; }; bool operator <(const StaffKey& lhs, const StaffKey& rhs) { return lhs.section < rhs.section || lhs.code < rhs.code; } // データ struct StaffData { std::string name; }; // キーとデータを紐付ける typedef std::map<StaffKey, StaffData> StaffMap; void insert(StaffMap& staffs, int sect, const char* cd, const char* nm) { StaffKey key = {sect, cd}; StaffData& data = staffs[key]; data.name = nm; }
530 :
529 :2007/11/28(水) 00:49:27
int main() { StaffMap staffs; insert(staffs, 1, "ab123", "Taro"); insert(staffs, 2, "ab123", "Jiro"); insert(staffs, 1, "ab111", "Hanako"); insert(staffs, 1, "ab133", "Ken"); for (StaffMap::iterator it = staffs.begin(); it != staffs.end(); ++it) { const StaffKey& key = it->first; const StaffData& data = it->second; std::cout << key.section << "," << key.code << ":" << data.name << std::endl; } std::cout << std::endl; for (StaffMap::iterator it = staffs.begin(); it != staffs.end(); ++it) { const StaffKey& key = it->first; const StaffData& data = staffs[key]; std::cout << key.section << "," << key.code << ":" << data.name << std::endl; } }
531 :
529 :2007/11/28(水) 00:50:28
---------------- 実行結果 ---------------- 1,ab111:Hanako 1,ab123:Taro 1,ab133:Ken 2,ab123:Jiro 1,ab111:Hanako 1,ab123:Taro 1,ab133: 2,ab123:Jiro はじめにイテレータを用いて全件のダンプを出力しています。 次に、[]を使ってデータを取得&出力しているのですが、 一部のデータのみ値が取得できない状態に陥っています(ab133:Kenのデータ) 独学で勉強しており他の人に聞くことが出来ないため、どこがおかしいのか全く判りません。 どうか助力をお願いします 長々とすみません。 なお、環境はLinux + GCC4.1.2です。
>>531 allocator が無いからじゃないかな?(綴り怪しいけど)
>>529 > bool operator <(const StaffKey& lhs, const StaffKey& rhs) {
> return lhs.section < rhs.section || lhs.code < rhs.code;
> }
これが順序付けになってないっぽい。
↓これでいいかな?
if (lhs.section < rhs.section) return true; else if (rhs.section < lhs.section) return false;
return lhs.code < rhs.code;
534 :
529 :2007/11/28(水) 01:11:31
>>532 mapのテンプレート引数にstd::allocator<StaffKey> を追加してみましたが変わらずでした。
(見よう見まねに意味判らずやってます)
>>533 出来ました!!
||だとショートサーキットが有効になるので大丈夫だろうと思って深く考えていませんでしたが
やはり単純なミスだったんですね。。。
助かりました。どうもありがとうございました
そもそも StaffKey::section の比較で両者とも同じだった(順序付けできなかった)場合に、 という仕様とは完全に異なるからな。
536 :
529 :2007/11/28(水) 01:27:07
右辺値のsectionと左辺値のsectionが等しかった場合の考慮がされていなかった ってことですよね? だから正しく順序付けが出来ず、key指定時にデータの特定が出来なかった。
a.i.u.e.oとかa->i->u->e->o(以下果てしなく続く)のような ながーい構造体とかポインタの参照は コンピュータ内部では一つ一つ計算してたぐり寄せているのでしょうか? 仮にそうだとして10万くらい続いているとしたら 終わりのx->y->z ←こいつのポインタを持っておけば無駄が省けるのでしょうか?
省ける 持っておけるなら。
>>538 やはりそうでしたか
これでまた一つ疑問が解けました
ありがとうございました
a.b.cの形は、オフセット計算だけで、コンパイル時に確定してるから無意味だよ。 a->b->cは間接参照で、実行時に中身を追うから、bに相当するポインタをtmpとして持つ意味があるけど。 もちろんこれはC/C++の話で、 他言語だとCの->に相当する部分で.を使用するから別の話になるし 配列として宣言して、あえて->を使う場合なんかはあてはまらないけどね。
541 :
デフォルトの名無しさん :2007/11/28(水) 09:31:45
一時的に特定のキーボードのキー入力を受け付けなくする方法か関数を教えてください
我慢する
キーボードクラッシャーにお願いする 天皇陛下万歳
キーを外してしまうのは確かに有効だな
ああ、おれもPOWERキーとかWINキーとかは外してるな。
546 :
デフォルトの名無しさん :2007/11/28(水) 12:01:54
>>546 bccで他にWinAPIを呼ぶプログラムを書いたことは?
それがあるならそれを参考に見直してみればいい。
そうでないなら、そういうサンプルを探せばいい。
>>541 Ctrl + Alt Dlt を無視したいとかそういうアプリではどうにもならない割り込みのあれかな?
>>546 >bcc32 a
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
test.cpp:
警告 W8004 a.cpp 13: 'hComm' に代入した値は使われていない(関数 main() )
Turbo Incremental Link 5.66 Copyright (c) 1997-2002 Borland
BCB6だけどエラーが出ない
>>541 WindowsならCtrl+Alt+Deleteとかの特殊なの以外はキーフックで殺せる
550 :
546 :2007/11/28(水) 12:42:20
>>547 ありがとうございます.
APIプログラミングの経験はないです.
C言語とAPIでシリアルポートにアクセスしているプログラムのソースは
見つかったんですが,どこが違うのかわかりません.
他に必要な処理があるのかと思ったんですが,
私の力ではそのプログラムのなかからそれを見つけることができませんでした….
>>549 ありがとうございます.
私も今TurboC++で試してみたんですが,
同じ警告しかでませんでした.
うーん.なんででしょう.
551 :
546 :2007/11/28(水) 12:45:20
>>550 に対する補記
Turbo C++ でならコンパイルできたということです.
bcc55だと他にインクルードする必要があったりしてね。
>>546 #include <windows.h> だけのソースもコンパイルできなかったりする?
554 :
546 :2007/11/28(水) 12:51:48
>>552 550で書いているソースがインクルードしていたものを
一応すべてインクルードしてみたんですが,だめでした….
>>553 コンパイルできなかったです.
>>554 bcc5.5.1で
>>546 のソースコンパイルできたよ
ファイルが壊れてるかもしれんから、再インストールしてみ
>>554 そりゃなんかおかしいね
bcc再インストールしてみた方がいいかもしんない
557 :
546 :2007/11/28(水) 13:20:32
再インストールをしてみたら,無事にコンパイルできました! お騒がせしました.みなさん本当にありがとうございました!
すいません、仮想関数とか継承とかで頭がこんがらがってきたので教えてください 仮想関数を含むオリジナルクラスを継承したクラスのインスタンスをnewしてそのポインタを オリジナルクラスにキャストしてもう一度もとのクラスにキャストし直したもどした場合は 正常に動作するのですが、オリジナルクラスに仮想関数が含まれない場合はコンパイラエラーが出ます、 これは仮想関数を含むオリジナルクラスのインスタンスの場合だけそのクラスを継承したポインタにキャストできるということなのでしょうか? この場合、オリジナルクラスのインスタンスには継承先の情報が無いと思うのですがどこから持ってきてるのでしょうか? ついでにもうひとつお願いします newでインスタンスを作成した場合deleteしなければ、プログラム終了まで有効なのでしょうか? 例えば関数の中でnewを行いクラスのポインタを変数に格納してそれを関数の引数として戻してnewを行った関数の外で使用しても 最後にdeleteさえすれば大丈夫なのでしょうか? 乱文失礼しましたが、よろしくお願いします。
>仮想関数を含むオリジナルクラスのインスタンスの場合だけそのクラスを継承したポインタにキャストできる dynamic_castの話なら、そのとおり。仮想関数を持たないクラスには働かない。 継承先の情報はインスタンスが隠し持ってる仮想関数テーブルに入ってる。 そもそもそれがなきゃ仮想関数の呼び先を解決できない。 deleteしなければプログラム終了まで有効。その続きのも大丈夫。 deleteし忘れてどんどんnewしてるとそのうちメモリを食い尽くすから要注意。
>>559 回答、ありがとうございます。
これでやっと先にすすめそうです。
最近deleteがdelegateに見えてしょうがないんだがもうダメなのか?
だめだね。あの手の便利すぎる機能はプログラマの脳を破壊する。
本物のプログラマは○○を使わない 【○○にはお好きな(またはお嫌いな)単語をお入れください】
本物のプログラマはコンドームを使わない
本物のプログラマは有給を使わない
すいません、もうひとつお願いします。 関数内で仮想関数を含むオリジナルクラスを継承したクラスのインスタンスをnewでつくりそのポインタを オリジナルクラスにキャストして関数の引数として返し、そのポインタをもう一度継承後のクラスにキャストした場合、 オリジナルクラスに存在しない継承後のクラスが持っているメンバ変数の値が維持されているのを確認できたのですが この部分の値もずっと保持されるであってますか?
- 本物のプログラマは有給を使わない + 本物のプログラマは有給を使えない
>>566 合ってる
ポインタをいくらキャストしてもインスタンスの実際のクラスが変わったりはしない
本物のプログラマは言葉を使わない
>>566 それはダウンキャストと言うのは知ってるね
dynamic_castは何をしようとするのかプログラマが知ってる限り
問題はない
どうでもいいけど(いや、よくないけど)関数が返す物は引数じゃないんじゃね?
3つほど質問させてください ・C++にはキャストがいくつかありますが、それぞれの役割がよく分かりません。詳説願います。 ・inline関数についてですが、同一ソース中でないとinline展開されえないですか? ・演算子オーバーロードにおいて左オペランドに自作関数をとる演算子等を定義する場合、 通常のメンバ関数のような形式で定義するのと通常のグローバル関数のような形式で定義するのにはどのような違いがありますか? bool Foo::operator +(Foo rhs)とbool operator +(Foo lhs,Foo rhs)みたいなののことです よろしくお願いします
>>574 オブジェクト間最適化機能のあるコンパイラなら、別のコンパイル単位にある関数でも
インライン展開され得る。
■キャスト 詳説せず、厳密さも気にせず簡単にまとめるとこんな感じ。 ・const の付け外し→const_cast ・標準変換、およびその逆変換→static_cast ・安全な downcast や crosscast→dynamic_cast ・A→B→Aで戻る以外は実装依存→reinterpret_cast ■inline 同一ソースって何? 規格上は基本的に同一翻訳単位に inline 関数の定義がないと駄目だし(ただし定義前に呼び出しがあってもOKと書いてあった)、翻訳単位間で定義が一致する必要がある。 最適化としての inline 化なら最近は >576 らしい。Exceptional C++ Style にもそんなことが書いてあった。 ■演算子オーバーロード ×自作関数 ○自作クラス だとして、メンバ関数にすると第 1 引数がその自作クラスの場合に限定される。 例えば、Foo() + 1 はどちらでも実現可能だけど、 1 + Foo() はメンバ関数で実現することができない。
ごめん。 >左オペランドに って明示してあった。 その場合は、operator+() が class Foo が定義されている namespace 内で定義されている限りはほとんど変わらないと思う。 もちろんメンバに対するアクセス制限は異なるけど。
質問があります。 C言語(linux gcc)にて、テキストファイルの指定した一行を読み込んだ後に、 その行を削除する処理を行いたいのですが、何か手立てはありませんでしょうか? 無理言って申し訳ないのですが、別ファイルに指定行以外をコピーした後ファイルのリネームを行う、 もしくはメモリにファイル内容を確保し、指定行以外をファイルに上書きすると言う手法以外で 何か解決手段をご教授いただければと思います・・・。 よろしくお願いします。
削除するってことは、その削除した部分を埋めるように後ろのデータをずらしてくるってことだ つまり、それをやればよい
後ろのデータを前にずらしながら書き込んで、最後にファイルサイズを小さくするのを忘れないでね。
そうは言うがな大佐、メモリに読み込まずにどうやってずらすというのだ。
一文字ずつ読んでシーク位置を一定数戻して書くを繰り返す それでは時間がかかるので適当なバッファを用意してある程度まとめて読んでまとめて書く て定石はさておいて メモリに読み込まずにずらす方法を考えようか アセンブラでレジスタだけ使ってどうにかならんかね
今までの常識を打ち破る画期的なファイルシステムを創造すればよくね? 例えば、ブロック単位で読み書きするのではなく 1バイトごとにリスト構造にして持つとか。
テキストファイルやめてデータベースにすればいいとおもうよ
そのファイルをメモリにマップしてmemmove
VC++ 6.0 WinXP ともに ProEditionで開発しています。 DLLを作成し、そのDLLの関数にCWnd型(MFCのやつです)のポインタを渡そうと思って、次のようなコードを書いてみましたが、 上手く渡りません。問題としてはCWnd::m_hWndの値が変わってしまうというものです。 以下にコードをあげます。 //DLL void CTestClass::TestFunc(CWnd* pWnd) { TRACE(_T("TestFunc 0x%08x \n"), pWnd->m_hWnd); } //EXE void CTestDialog::OnOK() { CTestClass test; TRACE(_T("OnOK 0x%08x \n"), m_hWnd); test.TestFunc(this); } このようにして、処理を行うと出力されるm_hWndの値が変わってしまいます。 理由をご存知の方がいらっしゃいましたら、教えてください。 よろしくお願いします。
CTestDialogで新しくm_hWndメンバ変数を作っちゃったとか?
C言語で最後がNULLで終わっている双方向リストを マージソートするにはどうすればいいのでしょうか? 普通のマージソートなら出来るのですが 双方向の場合どうすればいいのか解りません;;
逆向きのリンクを気にせず、単方向リストとして扱いながらソートする その後、ソートしたリストを順方向に辿りながら、逆向きのリンクを張りなおす
>>591 おおー、その発送はありませんでした
無事できましたありがとう^^
テキストがUNICODEなら、削除する文字を、 ZERO-WIDTH系の文字に置換しとけばよくね?
>>589 回答ありがとうございます。ですが、それは違いました。
それぞれ見ているMFCが、DLL->DLL版MFCで EXE->スタティクリンクしたMFCで違う、みたいな話ではない?
TRACE(_T("TestFunc 0x%08x 0x%08x \n"), pWnd->m_hWnd, &(pWnd->m_hWnd)); TRACE(_T("OnOK 0x%08x 0x%08x \n"), this->m_hWnd, &(this->m_hWnd)); とりあえずDLL,EXE両方が同じアドレスを参照出来ているかを確かめてみようか。
VC6で開発しています。 あるISequentialStreamのオブジェクトstreamにデータが入っていて、Readメソッドで vector< char > buf; buf.reserve( MAX ); for ( 読み終わるまでループ ) { buf.resize( buf.size() + size ); stream.Read( &buf[ 0 ], size, read ); } のように、size単位でデータをバッファに格納しようとしています。 データのサイズは1KB〜130MBほど、MAXは余裕をもって150MB、sizeは1MBです。 このstreamはあるライブラリ(Soap Toolkit 3.0)で提供されているもので、内部の実装は どうなってるかわかりません。 上記でデータ自体は取ってこれるんですが、非常に時間がかかってしまいます。 3GHz、2GメモリのPCで3分とか…。 メモリに格納するだけでこんなに時間がかかる訳ないと思うんですが、Readのやり方が 間違っているのでしょうか? sizeが1MBなのは、小さいサイズのデータの方がほとんどで100MBクラスはまれである ということと、 buf.resize( MAX ); stream.Read( &buf[ 0 ], MAX - 1, read ); のように、一回で全部読み込もうとしたときに、Readの返値のHRESULTが不明なエラーを 示す値を返し、readが0になるという現象が起きるのが理由です。 この原因もわかってないです。 ISequentialStreamとかは使ったことないので、どう使うのが正しいのかよく分からない状況です。 教えていただけると助かります。よろしくお願いします。
>3GHz、2GメモリのPCで3分とか…。 そんなものだよ。正常。
ストリームが読み取るデータを用意するのに時間がかかっているんじゃないの?
>>595 ,596
sizeof(CWnd)を出力してみて、違う値が出てきたので、色々確認した結果、
>>595 さんの言う通りの話でした。
ありがとうございます。
9,6,4,7,12,14,1,11,10,15,3,5,8,13,2を小さいものから順に並び替える関数です。 0 #include<stdio.h> 1 void quicksort(int x[],int n){ 2 int m; 3 int *pa=x+2. *pz=x+n 4 if(n==2){ 5 if(x[1]>x[2])m=x[1],x[1]x[2],x[2]=m; 6 return; 7 } 8 while(pa<pz){ 9 while(pa<=x+n && *pa<x[1])pa++; 10 while(pz>=x+2 && *pz>=x[1])pz--; 11 if(pa<pz)m=*pa, *pa++=*pz, *pz--=m; 12 } 13 if(pa>x+2)m=x[1],x[1]=*(--pa),:pa=m; 14 if(pa-x>2)quicksort(x,pa-1-x); 15 if(x+n-pz>1)quicksort(pz.x+n-pz); 16 } これの8〜12行目の部分は、9行目で前から数列の6,4,7,12まで進み、 10行目で後ろから2まで進み、12と2を交換するという意味であってますか?
再発明やめてqsortを使えばいい
何かと思えば行番号か
604 :
デフォルトの名無しさん :2007/11/30(金) 23:54:11
今日からC言語の勉強を開始しようと思っていますが、初心者でも使いやすい コンパイラーあれば、教えて頂けないでしょうか? ちなみにVisual C++ 2005 Express Edition持ってます、使えますでしょうか?
それで充分。
うむ
607 :
デフォルトの名無しさん :2007/12/01(土) 00:03:29
早速使ってみました。 とりあえずコピペで、ちゃんとコンパイルできるか見てみましたが、 エラーなにがおかしいですか? // test.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int i; for(i = 0; i < 10; i++) printf("i = %d\n", i); printf("end.\n"); return 0; }
日本語でおk
609 :
デフォルトの名無しさん :2007/12/01(土) 00:14:15
>>608 すまなかった
Visual C++ 2005 Express Editionのプロジェクトを開けて、コード記入する欄が
できたので、上のように試しにコードを貼り付けして デバッグというボタン押したら、
エラーになりました。コードのどこがおかしいのでしょうか
エラー内容書かない理由は? stdio.hをincludeしてないからだと思うけど
611 :
デフォルトの名無しさん :2007/12/01(土) 00:34:17
ありがとうございます。 #include"stdio.h"と入力すればよろしいでしょうか
コード書く前に基本的な勉強しろ
また「エラーになりました」か。 死んでほしいな、こういうヤツ。
614 :
デフォルトの名無しさん :2007/12/01(土) 03:28:40
関数 kansu()があるとします はじめにkansu_init()を使ってデータを生成したとしてkansu()でも使えるようにするにはどうしたらいいですか? グローバル変数にして使いたいのですが
組み合わせnCr=n!/r!(n-r)!を計算するプログラムでポインタを使って値を返さないものを作らなきゃいけません。 void (int x, int *pt) { int i; i = 0; *pt = 1; while (i < x) { ++i; *pr = *pt * i; } printf("factorial called, %3d!=%12ld\n", x, *pt); } 最初の定義をこんな風につくったんですがダメなとこを指摘してください。
616 :
614 :2007/12/01(土) 03:31:05
関数内でグローバル変数を定義することは出来ませんか?
>>615 >void (int x, int *pt)
関数の名前がない
>>616 関数の外でグローバル変数を定義すればいいじゃん
何か問題があるのか?
618 :
614 :2007/12/01(土) 03:37:00
>>616 そもそもグローバル変数が何かをわかってないだろ。
620 :
615 :2007/12/01(土) 03:43:09
>>617 void factorial(int x, int *pt);
こうですか
Visual C++ 8 で Win アプリを作りながら勉強しようと思ってるんですが、 Cの標準ライブラリの関数を使おうとしたら色々とエラーが出てきました。 で、MSDNを読んでみたら、 1. 標準関数の strlen とかは危険だから _strnlen_l みたいなVCの独自関数を使え。 2. WinAPI は char の時代は終わったから TCHAR や _tcs 系の関数を使え。 ってことが書いてありました。 警告を減らせば char 型やCの標準関数も使えるみたいですが、 このままVC独自色に染まってしまった方が良いのでしょうか?
622 :
デフォルトの名無しさん :2007/12/01(土) 04:10:05
counter=i; for (counter=i ;counter<=i+9;counter++) {・・・ for文が苦手です。この一文はどういうふうに解釈してよいか わかりません。解説して頂けないでしょうか
for( 式1; 式2; 式3 ) { 文 } は 式1 while( 式2 ) { 文 式3 } と殆ど同じ。 こうすればわかるか? counter=i; while( counter <= i+9 ) { /* 何か */ counter++; }
実行してみればいいじゃん、どうなるか
625 :
デフォルトの名無しさん :2007/12/01(土) 04:25:29
>>621 なるべく標準的にしたいなら標準で
速度を優先したいならWindows APIなどで
>>621 なぜstrlenが危険といわれるのか?scanfやprintf、strcpyなどもそう
なぜcharを使用しなくなったのか?
それをちゃんと知っておいたほうがいい。
VC色に染まってもいいが、VC以外で開発するときに代替案がすぐに
浮かぶようであれば問題ないと思う。
標準準拠を目標にして自作するのもいいし、危険とされる関数を
ラッピングして安全なものを作るのでもいい(←この時はpragmaで警告抑制)
MSDNの売り文句そのままですが、 標準関数は関数の方でバッファサイズをチェックしてなかったり文字列が '\0' で終了していないと止まらなかったりで危険。 VC 版は必ずバッファサイズと最大長を指定させていて、文字列が長すぎたりする時は途中で打ち切ってくれるので安全。 ってことですよね。 char は...Win9x は内部的に char 型だったけど最近のXPとかは内部的に UNICODE だから? 一緒に買ってきた教科書には当然のごとく _strnlen_l とか何にも載っていないんですが、 VC流で勉強しても教科書探しとか他の人との情報交換とかの妨げにならないか心配です。
安全なバッファサイズと最大長はどこからやってくるのか問い詰めたい
size_t strlen (const char * str){ const char *eos = str; while( *eos++ ) ; return( eos - str - 1 ); } koeeeee!!!
size_t strnlen(const char *str, size_t maxsize) { size_t n; for (n = 0; n < maxsize && *str; n++, str++); return n; } よs
引数に渡すバッファサイズはバッファの確保時点で決まるはずだし、 打ち切って欲しい長さはやりたいことやプログラムの仕様によって決まるはず。 例えば文字列が100文字未満か100文字以上かで分岐させたいとき、 strlen だと'\0'が見つかるまで暴走を続けるが strnlen_lなら「とりあえず100文字目までに'\0'はなかった」と帰ってきてくれる。 それ以外の場合でも「これ以上長いのは怪しいから扱いません」って断れるはず。
それが安全だと思い込むことの方がよっぽど危険なんだが。
それは詭弁
普通のstrlenと最大バッファ長指定のstrlenどっちがより安全かと言う話で しかもその為のコストは極僅かときたもんだ 少なくともその部分でのオーバーフローの可能性は無くなる まぁ大抵の人はこんなもの出る前から自作のセーフなライブラリ作って使ってたけどね
詭弁君をひさしぶりにみた
636 :
デフォルトの名無しさん :2007/12/01(土) 08:24:28
質問です。 123456.jpg 123.jpg このようファイル名の、数字のところだけを抜き出したいんです。 数字のところの長さは変わります。 そこでとりあえず、 char argnum[10]; hogeStrcpy(argv[1], argnum); void hogeStrcpy(char *origin, char *number){ int i; for(i = 0; origin[i] != '¥x2e'; i++){ number[i] = origin[i]; } } みたいなださださな物を書いてみたのですが、 引数の数字が短かかった場合、表示するとargnumにゴミが残ってしまいます。 なんとか数字だけをコピーしたいのですが、何か良い方法はないでしょうか?
>>636 atoi("123456.jpg")とかじゃなくて?
そうでないならsscanf("123456.jpg", "%[^.]", buf)って話かな。
思い込むもなにもstrlenとstrnlen_lどっちが安全ってstrnlen_lに決まってるべ。 strnlen_lが十分に安全じゃなかったとしても、strlenはそれ以上に危険なんだから。
>>638 atoi完全に存在を忘れてました。
ありがとうございます。
>>636 >引数の数字が短かかった場合、表示するとargnumにゴミが残ってしまいます。
文字列の長さがargnumの配列サイズ以下、ってことか?
argnumを初期化するか、hogeStrcpyの最後で'\0'を入れればいい。
642 :
636 :2007/12/01(土) 09:34:44
>>638 >>641 すいません。atoiでは駄目みたいです。
やりたいことは、
絶対パス
/usr/boku/graphic/123456.jpg
/usr/boku/graphic/1234.jpg
で渡される引数を、
/usr/boku/graphic/123456
/usr/boku/graphic/1234
で切り出して、
/usr/boku/graphic/123456hoge.jpg
/usr/boku/graphic/1234meso.jpg
みたいな感じで書き出したいんです。
/usr/boku/graphic/123456
/usr/boku/graphic/1234
の長さが変わるので、
配列argnum以下の長さだった場合、
argnumにゴミが残ってしまうんです。
で、別に文字列として表示する訳ではないので、
argnumを0で初期化したり、最後に'¥0'を入れたとしても、
/usr/boku/graphic/12345600hoge.jpgや
/usr/boku/graphic/12340000meso.jpg
みたいになるんじゃないかなと。
何か良い方法はないでしょうか?
>>642 "0"と'\0'は違う。
ヌルターミネートでぐぐれ
644 :
デフォルトの名無しさん :2007/12/01(土) 09:58:37
グラフィックを使うために、 Borland 用のGRWINをインストールしました。 #include <stdio.h> #include "GrWin.h" int main(){ GWinit(); GWopen(0); GWindow(-1,-1,1,1); GWline(-1,-1,1,1); } のプログラムのコンパイルが通りません。 Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 外部シンボル '_GWinit' が未解決(C:\BORLAND\PRG\GRWIN\DEBUG\MAIN.OBJ が参照) Error: 外部シンボル '_GWopen' が未解決(C:\BORLAND\PRG\GRWIN\DEBUG\MAIN.OBJ が参照) Error: 外部シンボル '_GWindow' が未解決(C:\BORLAND\PRG\GRWIN\DEBUG\MAIN.OBJ が参照) Error: 外部シンボル '_GWline' が未解決(C:\BORLAND\PRG\GRWIN\DEBUG\MAIN.OBJ が参照) ** error 1 ** deleting Debug\grwin.exe インストールがちゃんとできてないんでしょうか??
>>645 それはなんですか?Includeフォルダには grwin.hがインストールされてますが・・・・
647 :
636 :2007/12/01(土) 10:14:28
>>643 アルェー。
ビックリ。
出来てしまいました。
ヌルターミネートって何なんですか?
調べた限り、¥0との違いが良くわかんなかったです。
配列に文字列を代入した場合、0が続くと文字の終端になる?
1230000000005みたいな物だった場合もうまくいくのは何故ですか?
>>648 リンク先みたらわかりました!助かりました。
ありがとうございました
char *ch; int i; で定義したchar型のデータに変数を代入したいんですが、どうすればいいですか? pt = "ほげほげ"; はできるんですが、 ほげほげ i みたいに変数の値も代入するやりかたがわからないです
pt = "ほげほげ"; は ch = "ほげほげ"; でした
>>647 '0'は、0の文字コードをあらわします。(値としては0x30)
'\0'は、値として0をあらわします
文字列と言うのは、char型の配列であるので、
たとえば、"1230005"と言う文字列は、
31,32,33,30,30,30,35,0
と言う風に入っていると考えれば大体問題ないかと
ちなみに、 ""で括るのと、''で括るのでも意味が違うので、注意してください。
>>650 >char *ch;
これは、char型のポインタです。char変数のアドレスもしくは、
配列の先頭アドレスを入れるものです。
>ch = "ほげほげ";
これは、わかりやすく言うと、実行プログラム中に、
"ほげほげ"という文字列が確保されていて、
そこの先頭アドレスをchに代入しているだけのことです。
>ほげほげ i みたいに変数の値も代入するやりかたがわからないです
いまいちやりたいことがわからないのですが、
変数の値を文字列にして、ほげほげのあとに追加するのなら、
charの配列をある程度確保しておいて、そこに、ほげほげをコピーして、
その後ろに文字列に変換した数字をコピーすればいい。
なんにせよ、ポインタをきちんと理解しておいたほうがいいですよ。
>>653 文字列をグラフに印字する関数に、文字列を渡すんです。
char a[2] ;
a[0]='A';
a[1]=i;
として、iをfor文でまわして、A1 A2 A3みたいにしたいんですが、こうすると
Aのあとに変な記号が出てしまいます
>>654 文字列を充分理解してない
char a[3];
a[0] = 'A';
a[1] = i + '0';
a[2] = '\0';
>>655 なるほど
a[1]で、i+'0'としてるのはなぜですか?
>>656 は、
>>652 からアンカーをさかのぼっていっても良いし、
もしくは、ヌルターミネーターで調べても良い。
ああ、すまん。そっちか。
この場合は、
>>652 を参照なのは確かだが、ヌルターミネータは関係なかった。
>>656 文字コード表では文字0〜9の文字コードは連続してる。
'0'は整数0x30
'1'は整数0x31
'2'は整数0x32
・
・
・
'9'は整数0x39
>>659 なぜプラスしないといけないんでしょうか?
>>655 一般的にchar型に入れる文字コード上で、
数字を表す文字'0'〜'9'は連続した数値で表される
'0' = 48
'1' = 49
'2' = 50
(以下略)
だから、iが10進で一桁であれば、'0'+iで該当の文字コード(数値)が得られる
○ i=2の時に、2を'2'に変換
'0'+i = 48+2 = 50 = '2'
iが0〜9で無い場合(10以上とか負数とか)であれば
charの配列とitoaやsprintf辺りを使う。
char str[256];/* 全体で255文字まで保存出来る領域) */
char *ch;
int i;
ch = "hoge";
sprintf(str, "%s%d", ch, i);
「char str[256]」と「char *ch」の違いについては、また別途調べてみ。
>>661 分かりました。ありがとうございました。
663 :
デフォルトの名無しさん :2007/12/01(土) 14:25:24
例えば、1分経つと数字が一つずつ増え(1,2.3・・・) それを1時間ごとにその時間の数字の平均値を for文のループを使って計算させるには、どういう風に 書けばいいんだろう? もし、書けるとしたらこれは無限ループってことになるよね? 俺のイメージだとfor(i=0; i>=0; i++) {平均値を求めよ}
>>663 よく意味がわからないが最初は1個の数字、1分後には2個の数字さらに1分後は3個の数字
ってなるなら無限ループにならないでその数字の数のMAXとればいいだけじゃね?
>>661 iが10以上の時もできるようにしたんですが、
一番最後のiの時だけおかしいです。
666 :
665 :2007/12/01(土) 15:16:27
できました。すいません!
詰まらん質問ですが void Func() { return; } void Func() { } この二つの関数の実行速度は同じですか?
a=0; LABEL: if(a>10000)goto END; a++; goto LABEL: END: for(a=0;a<=10000;a++); の速度は同じですか?
最適化によってループが消えるかもしれないから何ともいえない
a=0;x=0; LABEL: if(a>10000)goto END; a++;x+=3: goto LABEL: END: printf("%d",x); x=0;for(a=0;a<=10000;a++);x+=3;printf("%d",x); はどうですか
コンパイラにとっては素直な書き方をした方が最適化しやすいと言われている
>>671 それは後者の方が速いと思う
なぜなら前者はループの中でx+=3してるが後者はループの中が空っぽ
x=0;for(a=0;a<=10000;a++)x+=3;printf("%d",x);はどうなりますか
知らん 実際にやって測ってみろ
他人様の手を煩わす前にやるべき事があるんじゃないのかと。
678 :
デフォルトの名無しさん :2007/12/01(土) 16:18:40
>>663 です 言葉足りなくてすいません。
例えば、1分ずつ時間が経つと数字も1増えるとしたら、
最初の1時間は 1〜60と数字が増えていきます。
これを時間ごと平均値を出すように命令したいので、60で割った計算をさせる
2時間目は数字は61〜120までなので、これらをすべて足して60で割る計算を
させる。
こんな感じの命令文作るとしたら、どんな文を作ったらよいか思ったのです。
で、もし、作ることができるなら、何時間後までやって下さいという命令文で
なければ、無限ループになるのではと思ったのです。
>>674 うちのコンパイラが生成したコードを見てみると
movl $LC0, (%esp)
movl $30003, %edx
movl %edx, 4(%esp)
call _printf
計算済みの答え30003が即値で渡されている
>>678 time関数で現在時刻を取得できるから、それを見て判断すればいいんじゃないか
681 :
デフォルトの名無しさん :2007/12/01(土) 16:32:35
ありがとうございます。 タイム関数というのまだ使ったことないのですが、どのような命令文 を作成して、1〜60を自動的に計算させることができるのでしょうか?
要求が曖昧なので具体的には書けないな。 1分に1回だけ1個ずつ出すの? 1分間のあいだ同じ数字をずーっと何個も出し続けるの?
ところで命令文って言い方に違和感を感じているんだが、スレ間違ってないよな?
684 :
デフォルトの名無しさん :2007/12/01(土) 16:43:45
1分目 1 2分目 2 ・ ・ 45分目 45 というふうに1分経つと、数字の方も1ずつ多くカウントされて 数字の方は1〜60をどんどん足し算して、 1時間ずつ経ったらら、その合計値を60で割って、平均値を出すということです わかりづらい質問してすいません。よろしくお願いします
685 :
デフォルトの名無しさん :2007/12/01(土) 16:46:05
スレ間違いしてないですよ。C言語の勉強始めたばかりで、for文の ことを考えていたのです。プログラム自体も初心者なので、専門用語 もよくわかりませんので、妥当そうな言葉使ってすいません
>>684 こんな感じかね
#include <stdio.h>
#include <time.h>
int main()
{
int i = 0, j = 0;
time_t t = time(NULL);
for (;;) {
i++;
while (difftime(time(NULL), t) < i * 60);
printf("%d分目 %d\n", i, i);
j += i;
if (i % 60 == 0) {
printf("1時間経った 平均%d\n", (j / 60));
j = 0;
}
}
}
687 :
デフォルトの名無しさん :2007/12/01(土) 17:06:55
おぉありがとうございます。まだプログラム慣れしてないので、複雑そうに 見えるが、頭で思っていたよりいろんな関数が必要なんですね。 whileが必要とは以外でした。for文ですべてできるかと思いました・・・ 熟読してみます。
688 :
デフォルトの名無しさん :2007/12/01(土) 17:08:04
C言語で使われてる関数を一覧できるサイトありますか?
標準関数ならあるよ
>>687 いやforとwhileは可換だからどっち使ってもいいんだけどね
書きやすいとか読みにくいとかその程度の問題だし
691 :
デフォルトの名無しさん :2007/12/01(土) 17:30:57
標準関数で良いのでサイトを教えて頂けないでしょうか?
694 :
デフォルトの名無しさん :2007/12/01(土) 19:12:41
C言語で型の前方参照ってどうやればいいでしょうか? やりたいことは typedef struct{ Fuga f; }Hoge; typedef struct{ Hoge h; }Fuga; ということがしたいのですが2行目で怒られます…よろしくお願いします
Fuga f; f.h.f.h.f.h.f.h.......? そんな無限ループみたいな構造体は作れません。
696 :
694 :2007/12/01(土) 19:45:02
うっ、そうなんですか。 C++ではできるのですがCではできないということですか? 2つのオブジェクト(データ)がお互いを指しているような構造は Cでは実現できないのでしょうか?
ポインタ使えば?
698 :
694 :2007/12/01(土) 19:58:49
ポインタでも結局怒られませんか? typedef struct{ Fuga* f; }Hoge; typedef struct{ Hoge* h; }Fuga;
>>694 は、指してるんじゃなくて含んでるんだよ
指すんなら出来る
typedef struct Fuga Fuga;
typedef struct Hoge Hoge;
struct Hoge{
Fuga *f;
};
struct Fuga{
Hoge *h;
};
>>696 > C++ではできるのですが
うそつくなヴォケ
701 :
694 :2007/12/01(土) 20:11:01
>>695 697 699
ありがとうございました。
私の初めの例が変でした。すみません。
699がまさにやりたかったことでした。重ね重ねありがとうございます。
702 :
694 :2007/12/01(土) 20:21:12
>>700 すみません
class Hoge;
class Fuga{
Hoge* h;
};
class Hoge{
Fuga* f;
};
ならできますよね?ということが言いたかったんです(ポインタなんですが)
つまり初めの例が変だったんです。
初心者歓迎ということで許してね♪
すまんが初心者以前は・・・いやなんでもない
> 初心者歓迎ということで許してね♪ なかなか面白いこと吐くじゃねーか
どこが笑いどころ?
> な > ま > 者
707 :
デフォルトの名無しさん :2007/12/01(土) 23:36:33
現在時刻を表示させるにはどうしたら良い?
>>707 #include <stdio.h>
#include <time.h>
int main()
{
time_t t = time(NULL);
struct tm *tm = gmtime(&t);
printf("%s",asctime(tm));
return 0;
}
VS2005です int ymd = 20071201; int y, m, d; y = 2007 m = 12 d = 1 のように年月日をそれぞれy m dに取得するいい方法はないですか?
y = ymd / 10000; m = ymd % 10000 / 100; d = ymd % 100; こうしたいの?
712 :
デフォルトの名無しさん :2007/12/02(日) 01:38:53
すみません>< 今日初めてプログラムを書きます 仮に {0,1,2,3,4,5,6,7,8,9} という配列が書き込まれているとし、 それが再生される段階でどこかが抜けてしまった場合、 例えば {0,1,2,4,5,6,7,8,9,0} となってしまうプログラムを書きたいんですが、 全然うまくいきません。 以下のものを書きました・・ ***************************************************************** #include<stdio.h> int main() { int i; int length = 10; //length of the sequence int start = 3; //start of asynchronous int Seq1[] = {0,1,2,3,4,5,6,7,8,9}; int Seq2[] = {0,0,0,0,0,0,0,0,0,0}; for(i = start; i < length; i++) { Seq2[i] = Seq1[i+1]; }; printf("%3d", Seq2[]); return(0); }
>>712 >Seq2[i] = Seq1[i+1];
iが9のとき、10番目にアクセスしてアウト。
ってか、何がやりたいのかさっぱり。
startが3だから3が抜けた配列を作りたいの?
for ( i = 0; i < length; i++ ) {
if ( Seq1[ i ] != start ) {
Seq2[ i ] = Seq1[ i ];
}
}
こういうことか?
>>712 >それが再生される段階でどこかが抜けてしまった場合
ここを詳しく
優しい人の集まるスレですね 俺なら日本語でおkとしか言えない
>>714 実はこのプログラムはですね、HDDのある特殊な媒体において、
「再生時に同期が外れて書き込まれている磁化パターンがヘッドで読めないところが出てくる」という現象を作りたいんです。
ABCDEF という系列を挙げると、左が過去です。A→B→C→・・・ という順でヘッドで再生されていくと考えてください。
そこで、どこかでヘッドと媒体の同期が取れなくて、読めないとこが出て、A→B→D→・・・ となる場合があるとしてます。
このプログラムは、ある既存のプログラムに追加したいものなのですが、
とりあえずプログラムを書いたことが無いので、このプログラム単体でビットのシフトを再現したいんです・・・
日本語おkですみません・・
抜きたい数字はランダムだとすると rd for(i = 0; i < NUM_MAX; i++) {
718 :
712 :2007/12/02(日) 02:37:49
>>717 ありがとう
実際は同期がはずれるのは当然ランダムだから、参考にさせてもらうよ
ところで、結果を表示する
printf("%3d", Seq2[]); っておかしいでしょうか?
適当に書いてたらこれがあると構文エラーになって出力できない・・・・orz
俺アホすぎ・・
こんなんでいいのかどうかわからんけど void main () { srand( (unsigned int)time(NULL) ); int i; const int length = 20; int index = 0; int Seq1[length]; int Seq2[length]; for( i = 0; i < length; i++ ){ Seq1[i] = i; Seq2[i] = 0; } // 抜けた数字 int out = rand() % length; for( i = 0; i < length; i++ ){ if( out != i ){ Seq2[index] = Seq1[i]; index++; } } printf( "抜けた数字:%d\n", out ); for(i = 0; i < length; i++) printf("%d ", Seq2[i]); printf("\n"); }
720 :
712 :2007/12/02(日) 03:17:19
>>719 ありがとう
でもムズイぜ・・・('A`)
struct point{ int x;//X座標 int y;//Y座標 }; int main(void) { struct Point A[1000],B[1000]; 線分A[i]B[i]とA[j]B[j]が交差するか判定していくプログラムで 単に二重for文で一個ずつ判定していくんじゃなくて(n-1)^2/2回の判定で済むようなプログラムの書き方を ご教授願いたいのですが
単純に for 文で1個ずつ判定していけば n(n-1) / 2 回の判定で行けるんじゃないの?
>>721 for(i=0;i<n;++i){
for(j=i+1;j<n;++j){
//処理
}
}
こういうこと?
多分n(n-1)/2だが。
nC2=n(n-1)/2 (n-1)^2/2回じゃ全て網羅しきれない
この場合n=1000で 一回目…A[0]B[0]に対して残り全部の照合1000-1回 二回目…A[1]B[1]に対してA[0]B[0]を除いた1000-2回 ・ ・ ・ 1000回目…A[1000]B[1000]に対して0回 for文は使わないという意味じゃなくて for(i=0;i<n:i++){ for(j=0;j<n:j++){ と単にするだけじゃなくてもっと効率よくするという意味です。 分かり辛くてすいません。
726 :
636 :2007/12/02(日) 15:44:54
すません質問です。 皆様のお陰で、文字列の抜き出し、結合は出来るようになりました。 今度は、抜き出した文字列の分離をしたいんですが、そんな関数有りますでしょうか? 具体的には argv[1] = "/usr/boku/graphics/1234.jpg から、"/usr/boku/graphics/1234"を抜き出して hoge[40] = "/usr/boku/graphics/1234" meso[] = "ero.jpg" strcat(hoge, meso); でhoge[40] = "/usr/boku/guraphics/1234ero.jpg" にすることは出来たんです。 それでこんどはまた、 hoge[40] = "/usr/boku/guraphics/1234ero.jpg" から"/usr/boku/graphics/1234"を抜き出して、 masaru [] = "eroero.jpg" strcat(hoge, meso) でhoge[40] = "/usr/boku/guraphics/1234eroero.jpg" にしたいんです。 抜き出す時点で、 hoge[40] = "/usr/boku/graphics/1234" hoge1[40] strcpy(hoge1, hoge); で後は、strcpyでhoge1を使い回せば良い気もするんですが、もっと良い方法はないでしょうか?
>725 それは >723 な気がするが。 もうちょっと工夫するなら ・A[i].x <= B[i].x となるように必要があれば A[i] と B[i] を交換 ・A[i].x で昇順ソート しておけば、B[i].x < A[j].x になった時点で内側の j のループを break できるので、短い線分が広い範囲にばらばら存在してるケースでは比較回数が削れると思う。 まじめにやるんだったら平面走査法になると思うけどいい参考ページがちょっと見つからなかった……
>726 hoge[40] = "/usr/boku/graphics/1234" になってる時点で、 char *begin = hoge + strlen(hoge); しておいて、 strcpy(begin, masaru);
729 :
636 :2007/12/02(日) 16:29:19
>>728 なるほど。
こんなことが出来たのは感激。さすがC言語って感じ。
char *begin = hoge + strlen(hoge);
で*beginにhoge[40] = "/usr/boku/graphics/1234"以降の空白の配列のポインタを代入して、
strcpy(begin, masaru);で結果として、/usr/boku/graphics/1234eroero.jpgが出来ると。
char masaru[] = "ero.jpg";
char meso[] ="eroero.jpg";
char hoge[40] = "/usr/boku/graphics/1234" ;
int i = strlen(hoge);
char *begin = hoge + i;
strcpy(begin, masaru);
printf("%s¥n",hoge);
begin = hoge + i;
strcpy(begin, meso);
printf("%s¥n",hoge);
これだったら、確かに"/usr/boku/graphics/1234"が使い回せますね。
でも、こんなプログラム書いたらコメントしてないと後で何してるのかわからなくなりそう。
>>726 >hoge[40] = "/usr/boku/guraphics/1234ero.jpg"
>から"/usr/boku/graphics/1234"を抜き出して、
ディレクトリ変わってるのはtypoよな?
>今度は、抜き出した文字列の分離をしたいんですが、そんな関数有りますでしょうか?
ない
具体的なコードの流れとか関数の切り分け方とか
分からんとどうするのが良いとか何とも言えないけど、
個人的な好みだと、
hoge[40] = "/usr/boku/graphics/1234" の段階でstrcatは使わずに
hoge1[40]、hoge2[40]を用意してそれぞれ
sprintf(hoge1, "%s%s", hoge, meso);
sprintf(hoge2, "%s%s", hoge, masaru);
とすると思う。
どうしても切り出す必要があるなら、前提条件が揃えばstrstrを使うとか
hoge[strlen(hoge)-strlen(meso)] = '\0'とか、まぁ色々あると思うけど。
731 :
730 :2007/12/02(日) 16:42:12
うぇwww質問主の返事の方が早かったw でしゃばってすんまへん
732 :
636 :2007/12/02(日) 16:45:39
>>730 いえいえ、そんな。
本当にありがとうございます。
ここの人達はめっちゃ紳士だから大好きだ。
>めっちゃ紳士 失礼な!
734 :
デフォルトの名無しさん :2007/12/02(日) 17:49:49
Visual C++ 2005 Express EditionをC言語のコンパイラーとして 使いたいけど そのまま打ち込めばちゃんとコンパイルされますか?
いいえ、正しい手順に則って打ち込まないとコンパイルしてくれません
736 :
デフォルトの名無しさん :2007/12/02(日) 18:44:08
735さん ありがとうございます。 わざわざ他のをインストールしてやるより楽でいいかなと思ったですが、 C言語とどういう点で違うかわかりますか? 初歩的なレベルのC言語をやる程度です
厳密にCとC++を区別する必要がないなら今は気にしなくていいよ。 参考書等を頼りに勉強して、不明点が出てきたらまた聞きに来るといい。
とりあえず拡張子を.cにすればコンパイラがよしなにはからってくれるんじゃね?
マクロを全く同じ名前/内容の関数に置き換えたいのですが、 そういうことってできますか?
例えば?
741 :
デフォルトの名無しさん :2007/12/02(日) 20:25:58
>>739 ケースバイケース。
Cの場合、使われてる場所で引数の型が異なると無理。
C++だと、テンプレートにすれば大概OK。
引数の型が一緒なら、どっちでもできるはず。
## を使ってるマクロなら駄目そうだ。
#define func(f,x) f(x) int foo(int x){ return x+1; } int main(){ return func(foo,-1); }
typedef int (*p_func)(int); int func(p_func f,int x){ return f(x); } int foo(int x){ return x+1; } int main(){ return func(f,-1); }
int main(){ return func(f,-1); } ↓ int main(){ return func(foo,-1); }
746 :
デフォルトの名無しさん :2007/12/02(日) 23:31:04
BCC Developerで多倍長精度の計算をするgmpライブラリは使えますか?
int *aとint* aの違いって何ですか?
見た感じが違う
スペースの空き方が違う
int *a; //アスタリスクが修飾するのは型ではなく変数名の方だと言う事を確り分かっている普通の書き方 int* a; //「型が変化するのに修飾対象が変数名だなんておかしい」と現実に目を向けない人可哀相な人がよくする書き方。
またそんな燃料投下しなくても・・・ 別にどっちだっていいよ、プロジェクト等ならコーディング規約に沿えばいい。 個人なら自分がいいと思うほうにすればいい。 何でこの話題で荒れるか知りたければCFAQとか見ればいい。
前者はC、後者はC++でよく見かける。
じゃ、int*a がBestなのですね。 有難うございました。
両方くっつけるのは全然見ない
int * a;
新しいなw まぁ俺も「int * a」派だから似たようなもんかw
LPINT a;
そいつぁ#defineの臭いがするぜ
テンプレートを考えたら int* を型として扱ってるから * は int 寄りだろうな。
結論は、貴方が Cをしているなら: int *a C++をしているなら: int* a どちらか不明な場合は: int * a ちょうど初心者なら: int*a と書くのが良いと思われます。
常に int *a がいいと思うけどな まぁ好みでどうぞ
int* *a みたいなw
C++の場合、使い込んでいくうちに、 ポインタは「イテレータと呼ばれる型」の一形態で、ポインタのデリファレンスはoperator*の一形態、 という意識がどんどん支配的なっていく。 昔ながらの下位概念側から比較的新しい上位概念を見る、のではなく、その逆の見方になる。 イテレータやスマートポインタを自作したりすると、特に。 そういう意識の中で int *a; という書き方を見ると、ちょいと異物感があるというか、 自分の「C++スタイルの深まり」との協調性に欠けていると感じる、ってのはあるかな。 もちろん、こんなのは小さなこと・・・っていうか、極端にいえば単なる「気分」の話であって、 実際には読み書き両面において、あらゆる書き方に慣れているべきなわけだけど。 結論:どっちでもいい。ただ、どんなスタイルであれ、それなりに理由があって生まれているから、 語り出すと長いしウザいw
ポインタを返す関数の例: T* f() T *f() dotch? A: pointer<T> f() よs(ry
int* と書いて問題になる場面ってあまりないけどね。 ショートコード大好きな人には大問題なのかもしれないけど。
問題は二つ以上の変数を同時に宣言したいときだよな
そこでD言語ですよ
変数を宣言する場合は、文法に沿って int *hoge 型を表すだけの場合は、文法に沿って int*
769 :
デフォルトの名無しさん :2007/12/03(月) 15:15:56
ICカードに情報を書き込むプログラムを作成しています。
もともとのサンプルプログラムに指定した情報を書き込めるようにしようと以下のプログラムを加えました。
以下実際に自分が加筆した部分を含んだソースコードのURLと自分で加筆した部分です。
ソースコード:
ttp://www.uploda.org/uporg1141577.zip.html 以下実際に書き込んだ部分
/*----------------加筆部分ここから----------------*/
//自分で書き込むデータを指定する場合
unsigned char write_block_data[16];
//gets()の引用数、\0+1のサイズを設定
char str[80];
char strlen;
size_t len;
fprintf(stdout,"書き込むデータの入力(16バイト以下)");
gets(str);
//16バイト以上を入力してしまった場合
while(len = strlen(str)>16){
fprintf(stdout,"文字数が多すぎます。もう一度入力してください。");
gets(str);
}
//i文字目がNULLにならない間一文字ずつ入力
for(int i=0;str[i]!='\0';i=i+1)
write_block_data[i] = str[i];
//文字数が少ない間
while(i < 16)
//文字数が少ない場合はゴミを表示しないようにする。
write_block_data[i++] = ' ';
input_write_block_without_encryption.block_data = write_block_data;
/*----------------加筆部分ここまで----------------*/
770 :
769 :2007/12/03(月) 15:18:31
>>769 です。
そのあとコンパイルをしたら
1>sample_09.cpp
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(77) : warning C4996: 'gets' が古い形式として宣言されました。
1> c:\program files\microsoft visual studio 8\vc\include\stdio.h(270) : 'gets' の宣言を確認してください。
1> メッセージ: 'This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(79) : error C2064: 1 引数を取り込む関数には評価されません。
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(79) : fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します。
1>ビルドログは "file://c:\Documents and Settings\ユーザー1\My Documents\Visual Studio 2005\Projects\felica\felica\Debug\BuildLog.htm" に保存されました。
と表示されました。
error C2064: 1 引数を取り込む関数には評価されません。
というものの対処法をぐぐっても意味がわからないのでどうやって解決していいのかもわかりません。
もしよろしければこれらのエラーの解決方法を教えていただけないでしょうか。
環境は
Windows XP Professional SP2
Microsoft Visual C++ 2005 Express Edition
です。
よろしくお願いします。
長文失礼しました。
>>770 原因は寧ろこれ。
>char strlen;
つーか、突っ込みどころ多すぎだろ。
// 加筆部分はこれでいいよ unsigned char write_block_data[17]; char str[sizeof(write_block_data + 1]; fprintf(stdout, "..."); fgets(str, sizeof(str), stdin); char * p = strchr(str, '\n'); if (p) * p = '\0'; sprintf(write_block_data, "%16.16s", str); // 最後の一行コピペすんのめんどくせ
775 :
769 :2007/12/03(月) 15:37:25
>>769 です。
レスありがとうございます。
>>771 先頭につけてもエラーはかわりませんでした。
>>772 char strlenというものをつけないでやってみたのですが、そのときは
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(80) : error C3861: 'strlen': 識別子が見つかりませんでした
というエラーが出てしまいました。
>>773 fgetsですか。
getsとかいてある部分をfgetsになおせばいいのでしょうか。
776 :
769 :2007/12/03(月) 15:40:02
>>774 最後の一行は
input_write_block_without_encryption.block_data = write_block_data;
ですよね?
F5を押してコンパイルしたら
1>sample_09.cpp
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(94) : error C2143: 構文エラー : ')' が ']' の前にありません。
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(97) : error C3861: 'strchr': 識別子が見つかりませんでした
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(99) : error C2664: 'sprintf' : 1 番目の引数を 'unsigned char [17]' から 'char *' に変換できません。(新しい機能 ; ヘルプを参照)
1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(119) : error C3861: 'print_vrctor': 識別子が見つかりませんでした
というエラーが出てきました。
777 :
769 :2007/12/03(月) 15:43:51
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(94) : error C2143: 構文エラー : ')' が ']' の前にありません。 というのは char str[sizeof(write_block_data + 1]; を char str[sizeof(write_block_data + 1)]; に変更したらエラーがなくなりました。 識別子が見つかりませんというエラーは例えばintやcharの宣言が必要という意味なのでしょうか。
code plz.
779 :
769 :2007/12/03(月) 15:50:55
>>777 char str[sizeof(write_block_data) + 1]
781 :
769 :2007/12/03(月) 15:54:53
これって C++ か…限りなく C に近いコードだな。
783 :
769 :2007/12/03(月) 16:07:19
>>782 C言語だと思っていたのですが*.cppファイルだからC++なんじゃないのかと思ってますw
といってもサンプルプログラムの入っていたフォルダの名前がCになっていたのでC言語だとは思うのですが・・・。
784 :
769 :2007/12/03(月) 16:22:12
ファイルの先頭を //#include "stdafx.h" #include <cstdio> #include <cstdlib> #include <conio.h> #include <cstring> #include "felica.h" としてみたらエラーが2つになりました。 1>コンパイルしています... 1>sample_09.cpp 1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(99) : error C2664: 'sprintf' : 1 番目の引数を 'unsigned char [17]' から 'char *' に変換できません。(新しい機能 ; ヘルプを参照) 1> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(119) : error C3861: 'print_vrctor': 識別子が見つかりませんでした
reinterpret_cast<char *>(write_block_data)
786 :
769 :2007/12/03(月) 16:29:56
>>785 unsigned char write_block_data[17];
char str[sizeof(write_block_data) + 1];
reinterpret_cast<char *>(write_block_data);
fprintf(stdout, "...");
fgets(str, sizeof(str), stdin);
char * p = strchr(str, '\n');
if (p) * p = '\0';
sprintf(write_block_data, "%16.16s", str);
input_write_block_without_encryption.block_data = write_block_data;
と設定してみました。
でもエラーメッセージがかわらないです。。。
なんでエラーが出たところで対処しようと思わないのだろう……
>>786 reinterpret_cast<char *>(write_block_data);
はおかしいだろ。
sprintf(reinterpret_cast<char *>(write_block_data), "%16.16s", str);
789 :
769 :2007/12/03(月) 16:39:35
>>787 エラーが出たから検索をしてみてはいるのですがまったくわからなくて。
すみません。
790 :
769 :2007/12/03(月) 16:42:40
>>788 アドバイスありがとうございます。
早速直してみたところエラーがひとつになりました。
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(122) : error C3861: 'print_vrctor': 識別子が見つかりませんでした
というエラー文です。
識別子が見つからないのというのは単にintやcharなどの宣言がないと言うことなのかと思ったのですがどうやら違うようでした。
>>790 変数だか関数だか知らんがprint_vrctorという識別子を持つ何かが定義
されてないとコンパイラがメッセージ出してるだろ。
勝手な予想だがキーボードの位置からして
print_vector
の間違いか?
マジで書いているんだったらとんでもない間抜けだな。 -- print_vrctor("書き込みデータ:",write_block_data,sizeof(write_block_data)); -- void print_vector(char* title, unsigned char* vector, int length); --
793 :
769 :2007/12/03(月) 16:52:59
>>790 たしかにそうなのかもしれません。
print_vrctorをprint_vector
に訂正してみました。
そうしたら
1>------ ビルド開始: プロジェクト: felica, 構成: Debug Win32 ------
1>コンパイルしています...
1>sample_09.cpp
1>c:\documents and settings\ユーザー1\デスクトップ\rfid_system\sdk.for.felica.sample.code+header\c\sample_09.cpp(102) : warning C4996: 'sprintf' が古い形式として宣言されました。
1> c:\program files\microsoft visual studio 8\vc\include\stdio.h(345) : 'sprintf' の宣言を確認してください。
1> メッセージ: 'This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'
1>マニフェストをリソースにコンパイルしています...
1>リンクしています...
1>sample_09.obj : error LNK2019: 未解決の外部シンボル __imp__dispose_library が関数 _main で参照されました。
1>sample_09.obj : error LNK2019: 未解決の外部シンボル __imp__close_reader_writer が関数 _main で参照されました。
794 :
769 :2007/12/03(月) 16:54:03
(
>>793 の続きです)
1>sample_09.obj : error LNK2019: 未解決の外部シンボル __imp__read_block_without_encryption が関数 _main で参照されました。
1>sample_09.obj : error LNK2019: 未解決の外部シンボル __imp__write_block_without_encryption が関数 _main で参照されました。
1>sample_09.obj : error LNK2019: 未解決の外部シンボル __imp__polling_and_get_card_information が関数 _main で参照されました。
1>sample_09.obj : error LNK2019: 未解決の外部シンボル __imp__open_reader_writer_auto が関数 _main で参照されました。
1>sample_09.obj : error LNK2019: 未解決の外部シンボル __imp__initialize_library が関数 _main で参照されました。
1>sample_09.obj : error LNK2019: 未解決の外部シンボル __imp__get_last_error_types が関数 "void __cdecl error_routine(void)" (?error_routine@@YAXXZ) で参照されました。
1>C:\Documents and Settings\ユーザー1\My Documents\Visual Studio 2005\Projects\felica\Debug\felica.exe : fatal error LNK1120: 外部参照 8 が未解決です。
1>ビルドログは "file://c:\Documents and Settings\ユーザー1\My Documents\Visual Studio 2005\Projects\felica\felica\Debug\BuildLog.htm" に保存されました。
1>felica - エラー 9、警告 1
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========
というエラーが出てきました。
>>792 すみません。本気で書いてましたorz タイピングミスはしないように見直しているつもりなのですが・・・。
いきなりfelicaとか使わんで、もうちょい勉強してからのほうがいいような…
スタティックリンクライブラリファイル(*.lib)をリンクしる
797 :
769 :2007/12/03(月) 17:01:31
>>795 はい、でも卒業研究で作成中のプログラムの一部として使用していまして。
どうしてもこの部分が必要になってまして・・・。
自分なりに頑張って他のパーツの作成は、できたのですがどうしてもこれだけができなくてorz
>>796 *.libをリンク??
*.libを持っていないので作成する必要がありますよね。
>>779 のURLにうpしたファイルがすべてなのでちょっとわからないです。
すみません。。。
sdkかなにか持ってるんじゃないの? それにlibが入ってるか、ソースが入ってるならそれをビルドすればいい
799 :
769 :2007/12/03(月) 17:13:45
はい。SDK for FeliCaというソフトウェアです。 CD-ROMにlibraryというフォルダがあります。 その中に felica.lib felica_for_vb.lib rw.lib というファイルがあります。 これをMicrosoft Visual C++ 2005 Express Editionを使って ファイル→開く→ファイルでfelica.libを指定して開いてみようとしたら "C:\(略)\felica.lib"に対応するエディタはありません。 このファイルの種類(lib)のアプリケーションがインストールされていることを確認してください。 という警告が表示されてしまい表示できないですorz
なあ、これって釣りだよな?
うん
802 :
769 :2007/12/03(月) 17:18:06
>>800 釣りじゃないです。釣りとまで思われるようですみません。
>>799 その問題解決能力ではこれから厳しいぞ
とりあえず、今までのレスからlibやらリンクやらのキーワードがあるんだからぐぐろうよ
数時間試行錯誤して駄目だったら再び質問するくらいの根気でがんばれ
>>802 じゃあまずはC言語の勉強から始めたら?
>>802 真面目に答えてやりたいが、VC++は(というかIDEは)使ったことないので完璧に予測で答えてみる。
多分、以下のどれかだ。
・プロジェクトにlibファイルを追加する
・「プロジェクトで使用するlibファイル」みたいなところに追加する
・ビルド時にlibファイルを指定する
まあ、メニューからそれっぽいの探して試してみろよ。
それくらいできるだろ
卒研ということは情報系の学生なんかな。 コンパイル、リンクとか少なくとも作業としてわかってるのかしらん。
うちのアホ大学(偏差値55くらい)の院生は、Cのポインタが理解できてなかった。 それでも一部上場のSIへ入社していった。入社後の本人&指導役が大変そうだ。 今の中堅以下の情報系学部ってそんなもんじゃないだろうか。
大丈夫 立派なパワポマスターに成長するさ
何故あんなに凝ったプレゼンをするのかパワーポインタを理解できません
>>808 そうそう、かの人はパワポと発表は上手だった。
彼は絶対、営業職の方が成功すると思ったなぁ。
まぁ既に営業系のSEに配置換えになってるかもしれないけどw
この程度のレベルで卒業研究とは… 何しに大学行ってたんだい?
812 :
769 :2007/12/03(月) 17:36:34
皆さんレスありがとうございます。
>>803 もう少し試行錯誤してみます。
>>805 よくわかりませんが色々試してみます。
追加してみることはできたけど変なエラーが出てしまったので恐らく追加の仕方が間違っているのだと思うのでもう少し探してみます。
>>806 はい、情報系です。正直よくわかりませんorz
>>811 毎日それなりにプログラミングはやっていたつもりなのですが4年間まったくわからなくて・・・。
ま、毎日?!
あまり判りやすい嘘は付かない方が良い・・・毎日ってw
>>812 根本的にプログラミングに向いてないね。
そこまで理解できてないのってのはいっそ文系脳では? 何故に情報学部に行った?
>>815 文系を人外の生物みたいに言うな!
文系と理系の違いは興味の方向性みたいなもんだ
できるかできないかは別問題
まぁプログラミングはホント人を選ぶ、ってか向き不向きがハッキリ出るからね。 うっかり情報系に入っちゃった人は、就職で心機一転、情報系以外の職種に就いた方がいいね。 学部で流れて就職するときっと後々後悔する。
学生と接することが多いが、769 さんみたいな学生は結構今は多い ような気がする。「一流大学」でも結構よくいる。情報が簡単に 見つかるのでついつい情報集め命で対処療法になってしまう。 一二冊で良いから本を初めから最後まで読んで、系統的に理解すれば 最終的には大分楽なんだけどね(情報系に限らず)。
情報学部に入ってるのに、情報におぼれてるのか? いったい何を得に行ってるのやら。 学費もったいねぇ。 とりあえず入れたところがたまたま 情報学部ってところなんだろうな。
IT業界で出世するのは文系。人外なんてとんでもない まぁ文系理系にかかわらずまれにいるけどな
821 :
769 :2007/12/03(月) 18:32:33
>>769 です。
皆様のお力添えでようやくライブラリの問題は解決しました。
少しプログラム上の問題が出ているので考えてみます。
>>814 一応毎日やってました。プログラミング演習という実習が再履修一度だけというのもあったので。
forやif文を書くレベルで落ちて再履修しましたorz
どんだけ低レベルなんだよwwww 独習Cとか買って最低限勉強しておいたほうがいいかもね
C++ cookbookおすすめ! makeとかbjamの使い方も載ってる 特にbjam、C++使うならこれを使わない手は無いぜ?
824 :
769 :2007/12/03(月) 19:11:46
数学や英語は好きで大学入ってから資格をとれたりしましたがプログラミングだけはどうしてもわからなくてorz
>>824 慣れだ。
あときちんと本を読んで実際にコーディングをすることをお勧めする。
IT業界にいくつもりなら会社に入れば嫌でも覚える。
プログラミングもできない、なんちゃってSEも多いけど。
情報収集には英語は必須だからきちんと勉強しておいたほうがいい。
語学の習得に比べたらプログラムなんてなんてことはない。
数学の弱いプログラマにはレベル低い奴が多いから勉強しとけ。
DSPとかいじるなら数学のセンスは必須。
画像扱うなら最低限、三角関数の定積分と二次元空間での図形の回転くらいできてて欲しいと思う今日子の頃。
827 :
769 :2007/12/03(月) 19:41:57
>>825 貴重なアドバイスありがとうございます。
C言語の初歩から家で就職まで勉強します。
SEではなく一応コンサル配属らしいけど親会社が外資系メーカーなのでIT業界には変わりないと思うので頑張ります。
英語はずっと勉強してます。院生に英語の文献読まされてよく和訳依頼されるのでw
数学ももっとやっときます。大学の教養レベルまで大抵わかってるつもりなのでプログラミングにも応用できるよう頑張ります。
new演算子を型ごとにオーバーロードすることはできるでしょうか?
>>828 new演算子はオーバーロードできない。
operator newならできる。
>>829 それnew演算子w
いや、言いたいことはわからなくもないけどさ。
>>828 クラスなら可能。
非侵入的にはできないと思う。
>>829 operator newとnew演算子の違いが判らないのですが?
832 :
828 :2007/12/03(月) 20:42:07
ありがとうございます クラスのメンバにすると解決しました
>>830 new演算子とoperator new()は明確に違う。
new演算子は
1. operator new()でメモリ確保する。
2. コンストラクタで初期化する。
この動作を変えることはできない。そういう意味でオーバーロード不可能。
ただし、1. の動作を再定義することはできる。
おれはこう理解している。
演算子関数のことを言おうとしてるんだよな、きっと。
835 :
デフォルトの名無しさん :2007/12/04(火) 00:29:00
double型のNコの配列Arrayを動的確保し、後のどっかで値が入って、 その後いろんな処理を経た後、マイナス値があればエラーを返して終了、 というものの場合、以下の「⇒」の箇所でアボートします。 他のうまくいっているプログラムと同じように書いたつもりなんですが、 ループの中でdeleteするのがいけないんでしょうか。 double* Array = NULL; Array = new double[ N ]; // この後なんやかんやで値が入る for( int i = 0; i < N; i++ ) { if( Array[i] < 0.0 ) { ⇒ delete [] Array; // ここでアボート Array = NULL; }
836 :
デフォルトの名無しさん :2007/12/04(火) 00:34:54
例えば y=2x のように簡単な比例の計算をさせるには どのように書いたらよろしいでしょうか。 よろしくお願いします
>>835 配列Arrayの複数の要素が負だったら、複数回deleteしてるんじゃね?
>>836 int f(int x)
{
return 2 * x;
}
>>835 簡単に言えばi==0の時点でArray[i]にマイナス値が入ってたら
その時点でif文内のdeleteが実行されてメモリ解放されても
引き続きi=1,2,3・・ってインデックスでアクセスし続ける訳だから・・・
まぁ、解ってのとおりループ内でdeleteしてるのがまずい。
840 :
835 :2007/12/04(火) 01:20:44
あ〜、ごめんなさい。うつしまつがえです。 ⇒ delete [] Array; // ここでアボート Array = NULL; retuen -1; // ここでエラーコードを返しているのです・・・ せっかく答えてくださったのにごめんなさい。
841 :
835 :2007/12/04(火) 01:22:28
再度ごめんなさいorz retuen ⇒ return です。 一個でもマイナス値があると、returnで抜けてるはずなんです・・
そういう場合は、動かないソースをコピペしたほうが良い。 ミスもあるし、関係ないと思って省いたところが原因だったりもする。
>>841 // この後なんやかんやで値が入る
Arrayの値を書き換えたりしてないよね?
俺はよくreturnをretrunと打っちゃうぜ。
845 :
841 :2007/12/04(火) 07:32:48
// この後なんやかんやで値が入る は、複雑な関数をいっぱい呼んでて、全体はコピペしきれません。 >>Arrayの値を書き換えたりしてないよね? いろんなところでしてます。値を書き換えてるところをもう一度、確認してみます。 おさわがせしますた
846 :
デフォルトの名無しさん :2007/12/04(火) 10:04:14
C言語使って移動平均線の計算することできますか?
移動平均線って株価のかね? 無論できるが、計算だけなら筆算でも電卓でも出来るだろうにw
指数平均も、単純平均も出来るよ
850 :
デフォルトの名無しさん :2007/12/04(火) 13:00:26
解答ありがとうございます。 勉強ついでに移動平均線を作ってみたいのでアドバイス頂けませんか?
何が分からないのかが分からないとアドバイスしようがない
大工道具で家は立てられますか?レベルの質問だよなこれは。
まず、紙と鉛筆で計算してみて、そのやり方をプログラムにすればよろし
エクセル使えよ
セックスで子供が作れますか?と同じだよ 受精できるのはIQ130の優秀などうみても精子
856 :
デフォルトの名無しさん :2007/12/04(火) 16:55:53
質問なのですが、 実行ファイルからどのコンパイラでコンパイルしたか判別することは可能なのでしょうか? たとえば、visual c++ .net 2003 アカデミックパッケージ でコンパイルした実行ファイルは、このパッケージのコンパイラで コンパイルされたという情報が含まれていたりするのでしょうか? また、gccでコンパイルしたのかvisual c++でコンパイルされたのか判別できるのでしょうか?
実行ファイルの形式があるんじゃね? ELF PE よくわかんね。
>>856 同じ環境でもコンパイラによってリンクするモジュールが若干違うので
埋め込まれたシンボルからコンパイラを推測することは可能。
例えば、同じLinux上でgccとiccでコンパイルした場合を較べると、
後者には前者に存在しない__intel_cpu_indicatorなんてシンボルが埋まっている。
しかし、IDEのパッケージの違いまでは判らないと思うが。
859 :
デフォルトの名無しさん :2007/12/04(火) 17:29:55
CとかC++とかC#とか言うけど、どう違うんですか? 全部C言語なんじゃないんですか?
C#は全くの別物。 C++はCのオブジェクト指向拡張に過ぎない。
>>859 騙されるな。C++もCをベースにしてはいるが最早別の言語だ。
CをインクリメントしたのがC++で 半音上げたのがC#だ
C#の文法はキモイな。ごちゃ混ぜ感丸出しだ。
C#はCと名乗ってはいるものの実際はJavaとVBの合いの子みたいな感じ。
どっちかというとJavaとObjectPascalじゃないか?
866 :
デフォルトの名無しさん :2007/12/04(火) 18:33:47
質問です #define TEST_PRINT( ... ) printf( __VA_ARGS__ ) とやると、...の部分で error C2010: '.' : マクロの仮引数リスト内に予期せぬ文字列があります。 と出ます。 これは、どうやったら予期してくれるんでしょうか?
配列の定義でしてプログラムを組んでいるのですが int N=100; int a[N]; でNの値を100から500000ぐらいに変えると、コンパイルはできるのですが実行画面に Documents and Setting\ユーザー名\デスクトップ>ファイル名 Press any key to exit (Input "c" to Continue) と出てしまい実行結果が出力されません。どうしたらよいでしょうか。 Cpadを使っています。ただのメモリー不足でしょうか。配列の要素数が多ければ多いほど信頼性のあるデータが得られるので、できるだけNの値を大きくしたいのです。
>>865 C++Builderのコンポーネント作ってたレベルだからあれだが
DelphiとC#の似てる部分はVCLとFrameworkぐらいで
文法はずいぶん違うよ〜
>>867 空白が入っていないところにデータをおくんだ 保存するんだ
#include <vector>
using namespace std;
main(){
int N=100;
vector< int > a;
a.resize[N];
}
とやると巨大配列が作成できる たんなるintでは制限がきつい
制限はスタックサイズね
>>871 ありがとうございます。
検索してみたら他にも色々対応していないのも分かり参考になりました。
>>867 でかい配列を作るときはnew(ただのCならmalloc)を使って作るんだ。
int a[N]; では一時変数用の領域(あんまり広くない)に確保されちゃうから。
newやmallocで確保した領域は、使い終わったらdelete(ただのCならfree)すること。
で、メモリ管理の面倒さを感じ始めたら
>>869 が教えてくれたvectorにGOだ。
(以上、かなり乱暴な説明をしてるので使う前にちゃんと勉強してね。)
>>869 詳しく解説して下さってありがとうございます。
Victorっていうのを使った後はfor文の中で
b[i]=a[i];
のように使えるのでしょうか。
>>863 どうもありがとうございます。今日はパソコン室閉まっちゃったので試せませんが明日試してみます。
はじめはwin32APIスレで相談したけど よく考えたらこちら向きな気がするので質問です マルチ気味で申し訳ないです スプライト処理をしたいのですがマスクしてBitBltする以外に方法はあるのでしょうか やはりdirectXをりようしたほうが手っ取り早いのですか?
878 :
デフォルトの名無しさん :2007/12/04(火) 23:15:06
BCC Developerをお使いになっている方にお聞きしたいのですが、メイク機能を使ってもなぜかexeファイルになりません。この場合はどうしたらよろしいのでしょうか? すごく簡単なことだと思うのですが、C言語を始めたばかりでまだあまり分かっていないので、どうかよろしくお願いします。
>>878 C言語というかプログラム自体も経験少なそうだね。
エラーが出て作ることができないのか、それ以外なのか、
エラーが出ているならどういうエラーが出ているのかを書いた方が応えやすい。
質問の仕方から勉強した方がいい。
VC++2005のwindowsフォームアプリケーションでプログラムを書いてます。 textBox1などの値を変えるためにメンバ関数を作りたいのですが、それを呼び出そうとすると 「静的でないメンバ関数の呼び出しが正しくありません」 とエラーがでます。そこで関数にstaticをつけると 「左側がクラス、構造体、共用体、ジェネリック型へのポインタではありません。」 と出てしまいます。 分かることがあればヒントでいいのでお願いします
>>877 とりあえずC/C++にはあまり関係ない。
DirectXが手っ取り早いかどうかは人による。
>>880 class::メンバ関数で呼び出せないかな?
なにをしたいかよくわからないけど
>>882 ボタンをクリックしたときに呼び出される関数button1_Clickなどでは
textBox1->Text = "test";ということができるので、
外部からtextBox1の値を変えるのも同じようにそこに関数を作っていき、
それを呼び出せばいいと思っていたのですが・・・。
884 :
デフォルトの名無しさん :2007/12/05(水) 00:46:28
>>883 textBox1->Textってのがローカル変数というかメンバ変数じゃないんでないの?
>>884 そのメンバ変数を外部から見たいときはどうすればいいんでしょうか
886 :
デフォルトの名無しさん :2007/12/05(水) 01:05:24
>>884 パブリックにすればいいのでは・・・。
というか、textBox1ってもダイアログとか別のクラスのものですよね?
そういうのは
CTestDlg Dlg;
でまずクラスを作ってあげる?ことをしないと基本できませんよねたしか。
ファイルが開かれていて、閉じられていない間待つようにしたいのですが、fpには演算&&が定義できないようです どうすればいいですか while(fp&&fp.fail())Sleep(10);
よくわからんが fp != NULL
サンクス
乱数を使うプログラムを組んでいるのですが、毎回同じ結果になってしまいます。 教授には、「タイムスラングはやった?やってない?じゃあもういーや」というようなことを言われました。 具体的にはどうすればよいのでしょうか。
892 :
デフォルトの名無しさん :2007/12/05(水) 09:19:06
C++ Win32APIでスタンドアロンの一人用チャットを作っています。 入出力にエディットコントロールを1つずつ設置して、エンターキーが押されたら 入力エリアの内容を出力エリアに渡したいんですが、漢字変換の決定のエンターキーでも 反応してしまって、単語単位でしか打てません。 何かいい方法はないでしょうか。
893 :
892 :2007/12/05(水) 09:39:23
事故解決しました。
>>891 どうもありがとうございます。
頭にそれを付ければよいのですよね?
>>894 プログラム実行の最初に1回だけな。
乱数出力の関数を呼び出すたびに呼ぶんじゃないぞ。
896 :
892 :2007/12/05(水) 10:22:45
エンターキーの二連続入力を探知しようと思ったけど、冷静に考えてみたら英語入力だと使えなくなるのでだめでした。 正規表現で改行コードを監視し続ける方法も考えたけど、正規表現を使うのにライブラリが必要らしく諦めました。 どうすればいいんでしょうか。
何をどうやってんの? 普通そのreturnは区別できるけど。
>>896 なんで正規表現が要るのよ?
単純に文字列から"\r\n"を検索するだけだろ?
stringのfindか、Cならstrstrかなんかで。
899 :
892 :2007/12/05(水) 10:39:24
| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄| ←出力用エディットコントロール | .| (エンターキーが押されたら、ここに入力された文を出力したい) |________| ________ |あいうえお | ←入力用エディットコントロール(一行)  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ 今はこれでGetAsyncKeyState(VK_RETURN)でエンターキーの入力を監視して、trueなら GetWindowTextで入力内容を取得→SetWindowTextで出力をしようとしています。
IDOKひろったほうがいい気がするが
>>896 どうもありがとうございます。一行だけ加えればよいとのことで修正が楽そうでよかったです。本当にありがとうございました!
>>892 WM_IME_STARTCOMPOSITIONとENDCOMPOSITION拾ってその間のキー入力は無視
昨日、配列のことで質問した者ですが、 例えば巨大配列にa[i]にiをいれてa[i]を表示するというプログラムを作成する場合、 昨日の解説を元に以下のようなプログラムを作成したのですが、 #include<stdio.h> #include<stdlib.h> #include<iostream> #include<time.h> #include<vector> using namespace std; main(){ int N=1000000000; vector<int> a; a.resize[N]; int i,n; n=N; for(i=0;i<n;++i){ a[i]=i; } for(i=0;i<n;++i){ cout << a[i] << " "; } } 以下のようなエラーが出ました。 エラー E2235 練習.cpp 14: メンバー関数は呼び出すかそのアドレスをとらなければならない(関数 main() ) エラー E2062 練習.cpp 14: 無効な間接参照(関数 main() ) 根本的に間違って理解してしまっているような気がするので、どうかご指導をよろしくお願いします。
前のレスでも指摘されてたと思うが、 a.resize[N]; はおかしいだろ。a.resize(N);じゃないの? だが何故にresize? 最初からvector<int> a(N);じゃだめなのか? それに領域は確保せずにpush_back使えばいいだろ。 それとCのライブラリを使うのは控えたほうがよいと思う。 どうしても使う場合C++ヘッダcstdlibやctimeを使った ほうが良いと思う。
>>904 すいません
14行目となっているのは
a.resize[N];
の部分です。
>>905 いろいろなご指摘ありがとうございます。
昨日の指摘にそってプログラムを組んだつもりなのですが・・・。
なるほど、resizeでやる必要はないのですね。
>>905 push_backは遅い。せめてreserveしてからにしろ。
905さんの言うとおりにa.resize[N]の[]を()に変えたところ コンパイルはできたのですが、今度は実行画面に Abnormal program termination と表示されてしまいました。 うーん、なんじゃこりゃ。
-- #include<stdio.h> // 間違い。iostreamを使うなら不要 #include<stdlib.h> // 間違い。現時点では不要 #include<iostream> #include<time.h> // 間違い。現時点では不要 #include<vector> using namespace std; main(){ // 間違い。 int N=1000000000; vector<int> a; a.resize[N]; // 間違い。そもそも必要ない。 int i,n; // iはここで宣言すべきではない。nは存在意義がない。 n=N; for(i=0;i<n;++i){ a[i]=i; } for(i=0;i<n;++i){ // iteratorを使うほうがいい。 cout << a[i] << " "; } }
>>908 だってお前、int型を10億個っていったら、4GBのメモリが要るってことだぞ。
>int N=1000000000; そんなに大きな配列は32bit環境では作れない。
>>910 いいえ。メモリがないのが問題じゃありません。
じゃあアドレス空間
数字を減らしたらなんとかできました。ありがとうございました。 ただ練習ではできたのですが、本番の課題でコンパイルし、実行した結果、ウィンドウが出て来てアドレス系の警告がでて正しく動作しませんでした。 一度int a[N]で作ったソースはかなり長いものなので、あまり大体的には変えたくないのです。 もうすこし頑張ってみます。
916 :
892 :2007/12/05(水) 13:05:01
>>898 >>902 たぶん自分のソースの書き方が悪いんだと思うんですが、やってみてもエンターと同時に出力するか
表示されないかでした。ちょっと時間がないので明日あたり報告にきます。
卒論の時期だなあ( ´ー`)y--┛~~
思うように結果が出せず理解があやふやになり孤独と絶望に打ちひしがれる まさしく一人デスマだった 思い出したくもない
マ板に逝け
a[N][N] b[N][N] c[N][N] という2つの2次元配列を宣言したすると、その配列の領域のオーダーはどうなりますか? N^2ですか?
#include <stdio.h> #include <time.h> int main(void){ clock_t start, end; start = clock(); なんかの処理 end = clock(); printf("%5.2f\n", (double)(end-start)/CLOCKS_PER_SEC); return 0; } これをC++で書くとどうなりますか?
>>925 変えるのは、表示の部分だけですね。ありがとうございます
>>926 別に、C++でprintfを使ってはいけないという法はないがな
C++標準ライブラリで書くと<iostream>だな
入門篇からのマルチポストすいません。。。急ぎでしてどなたか部分的にでも回答お願いします WindowsXP SP2 VC++6.0で動くプログラムの 共有メモリについて質問があります。 複数プロセス間で参照する共有メモリとして、 メモリマップドファイルを検討しているのですが 以下の認識であっていますでしょうか ・mallocで動的に確保する場合に(3M確保を想定)発生する O/Sのページング作業がありませんか? (連続した物理メモリを取る為に、メモリの入れ替え作業が 必要になりファイルにメモリの内容を書いたりする事全般) ・メモリマップドファイルの確保、読み書きは普通のファイル より高速らしいですが、普通のメモリ確保とどう違いますか? ・メモリマップドファイルを確保したプロセスが解放せず死亡 した場合にファイルに書く事はできますか? ・そもそも、メモリを確保する際ページング作業をしない保障は WIndowsではできないのでしょうか? そうだとしたら、ディスクをFlashMemory等のRAMディスク にした場合高速にできますか? 当方、組み込み系システムの詳細設計レベルしかやったことがなく、 担当設計者のフォロー?で、代わりにWINDOWSで基本設計 しています。 時間的要件があるので、処理時間が特定できないのはマズいのですが・・
>>930 ・3MB程度なら、搭載メモリが512くらいあれば余程過労してない限り発生しない。
・メモリマップドファイルとはあたかもメモリの一部のように読み書きできるファイルのことである
・しらね
・できない。普通は備え付け補助記憶装置であるHDDの方が
外部から差し込んだFlashMemoryよりも距離的に近いし高速。
>>932 質問するならコンパイルエラーなのか実行時エラーなのか、あとエラーの内容も書いてくれ。
イテレータの宣言のところでコンパイルエラーが出るってわかってるのなら、
その辺の文法とか見直そうよ。
vector<int>::iterator ite;
934 :
892 :2007/12/06(木) 11:24:25
WM_IME_STARTCOMPOSITIONでMyflagをtrue、WM_IME_ENDCOMPOSITIONでMyflagをfalseにして case WM_LBUTTONUP: if(Myflag==false){ //Myflagは変換用アンダーバーが出ていたらtrue strText = (char *)malloc(256); GetWindowText(edit , strText , 256); SetWindowText(copy , strText); free(strText); } return 0; case WM_COMMAND: if(GetAsyncKeyState(VK_RETURN)&0x8000){ if(Myflag==false){ //Myflagは変換用アンダーバーが出ていたらtrue strText = (char *)malloc(256); GetWindowText(edit , strText , 256); SetWindowText(copy , strText); free(strText); } } return 0; こうすると、左クリックを押した時は期待通りに入力ウィンドウの内容を出力ウィンドウへコピーしてくれるんですが、 エンターキーを押した時は無反応です。 WM_COMMANDとGetAsyncKeyStateの相性が悪いんだろうと思ってメッセージループに同じ内容を書き込んでみたら、 今度は逆に変換決定のエンターキーで反応してしまってます。
case WM_KEYUP: if (wParam == VK_RETURN) { は?
IDOKでいいのに
spyかなんかでメッセージの流れ読めば、どういう手順でメッセージを処理すればよいか見えてくるはず
巨大配列のことを質問したものですが、 newやvectorを使って書き直したところ、メモリのアドレスがでてきてwrite出来ませんでしたやら、readできませんやら出てきました。原因の行はわかったのですが、他の行となんらかわりのない文です。これはもう初めからやり直すしかないですかね?
必要なサイズをちゃんと確保していないんだろ たとえば10000個しか確保していないのにa[10001]に代入しようとしたらエラーになる
そうだね、生まれ直して0からスタートするといいと思うよ。
ソースコードをあげてみれば分かるよ
vcでbluetoothのプログラミングをしたいのですが、vcでできるんでしょうか?
>bluetoothのプログラミング ってなんですか?
知らない人は反応しなくていいです。 vcでできるんでしょうか?>まともな方々
出来る。
Embedded開発か >bluetoothのプログラミング (笑)
環境がそろえばPCがらみのプログラムを作成する事は出来るんじゃね? どうやって環境をそろえるんですか? なんて聞く奴は環境をそろえる事は出来ないと思うけどな〜
自分で調べもしないで質問してるっぽいなw
n 個の石が環状に並んでいる.それぞれの石には番号がついており,最初は時計回りに順番に並べられている.番号は 0 から n-1 までの整数である. m 番の石を最初に取り除く.直前に除いた石から時計回りに石をたどって k 個目を取り除く作業を,残り 1個になるまで繰り返すとする. 標準入力から,n, m, k の 3つの整数値が与えられたとき,最後に残る石の番号を答えるプログラムを書きなさい. 普通の継子立てとおなじく考えてたら全然ダメでした。。。アドバイスお願いします。
宿題スレ池
>>948 ここで質問する==調べものをする
だからなw
>>949 どこで詰まってるのかよくわからんが、代数的に解かなくても
>m 番の石を最初に取り除く.直前に除いた石から時計回りに石をたどって k 個目を取り除く作業を,残り 1個になるまで繰り返す
この手順通りのことを実際にやるようなプログラムを作ればいいんでない?
0xFFFLの最後のLが意味わからんとです
Lを付けるとlong型 0L とか 4095L とか
>>949 継子立てでいけると思うけど、どうダメだった?
巨大配列の男ですが、ご指摘してくれたように、領域確保が要素数に対して少なかったという理由でした。 課題もなんとか終わりました。質問に対して答えてくれた方々、本当にどうもありがとうございました。
どこで聞けばいいのかわからないのでとりあえずここで。 配列のサイズってどこに格納されているんでしょうか? gcc -S でソースを眺めてみたところ特にサイズらしきデータが見当たらず、 sizeofした結果は即値で見つけやすかったんですが。 関係あるかどうかinfo scopeでは配列はサイズは表示されるのですが、 型と要素数では表示されないんですね。 スレ違いなら誘導よろ。
>>958 配列のサイズって格納されてるの? 俺はできるだけ
vector とか使って size わかるようにして使うようにしてるけど。
>>958 配列サイズメモリには残っていない
コンパイル中にだけ残っている
サイズ知りたければvector
配列サイズは、メモリには残っていない
>>958 の人気にshit
ただし、newで作った配列は、どこかにサイズ情報を持ってる。返されるアドレスの直前とか。
そうでないと、delete[]で正しく開放できないからね。
レスどうも。
スタック上の固定長配列はオフセットに化けてメモリ上には展開されないって感じでしょうか。
>>962 そういえば、delete[]はサイズ意識しますもんね。
今度newした配列見てみることにします。
new[]でも要素数を知る方法はプログラマが用意しない限りない。
>>933 すみません、ご指摘ありがとうございました。
966 :
282 :2007/12/07(金) 20:55:28
テキストファイルに他のプログラム用のコードを書くプログラムなのですが、 #include <iostream> #include <fstream> #include <sstream> using namespace std ; int main(){ stringstream ss; FILE *fp ; for ( int t = 0 ; t < 100 ; t++ ){ ss << "data" << t ; cout << ss.str() <<endl; if ((fp = fopen(ss.str().c_str(), "r" )) == NULL ) return 0 ; ss.str("");}} 上記の部分で、ファイルはresult0〜result99まで存在しているにもかかわらず result46でプログラムが終了します。 ifの判定ミス?だとは思うのですが、どうしてそうなるのかまったくわかりません。 コンパイラはborland C++です
答えはfcloseが無いから。
968 :
デフォルトの名無しさん :2007/12/07(金) 21:11:57
すいません初心者で基本的なことかもしれませんが、 知っている方がおられれば教えてください 10進数で11とかだと16進数でbになると思うのですが 4桁で000bと出力するにはどうすればよろしいでしょうか? よろしくお願いします。
うまくいきました。ありがとうございます。 ageたり、282とか間違ってるし答えも単純だし、終わってるな俺 orz
printf("%04x", 11);
971 :
デフォルトの名無しさん :2007/12/07(金) 21:20:01
>>970 すいません、ありがとうございます。
04の0が抜けてました。
ほんとうにありがとうございます。
非仮想インターフェースの使い方がいまいち解りません 多重継承時に処理のし忘れを防止するというのはわかるが それだけのためにラッパーを作るのはどうかなという気がしないわけでもないのですが…
使い方なんてわからなくてもいいんじゃない? 意味や意図がわかってれば public な仮想関数は2つの役目を担っているので public な非仮想関数と private な仮想関数に分けましょう ってことを意識すれば public な仮想関数は気持ちわるい そうやって1つのエンティティに1つの役目を負わすことを意識して シンプルで扱いやすい設計ができた経験があれば
>>972 気持ち悪いと思うならやめた方がいいと思う。
そもそもある設計手法が効果的に働くためには一定の条件が必要で、
>>972 のプログラムではNVI(Non Virtual Interface)が効果的に働かない部類のものかもしれない。
将来的に不具合が出てきたら変えればいい。
パターンは大事だけど、経験も大事。
すみません デルファイのようにGUIでプログラムできるC++はありますか ボーランドC++以外のやつ有りますか?
・VC(CLI + .net) ・WideStudio
ドットネットと、ボーランド以外ではWideStudioしかないってことで良いかな? なんか初めの二つは、SP2とドットネットのインストールが必須な上に作業中の動作が重いんだ 古いパソコンでもDelphi6のように動くC++が使いたいとおもった
あと、もっとも簡単にC++でネィティブwindowsアプリを開発するにはどうしたらいいかな? ATLやWTLが簡単なの? なんかこれでも難しいんだ・・・
MFC
wxWidgets
一番簡単なのは、MFCですか? wxWidgetsですか? WTLですか? ネイティブで簡単なのが良いです
>>982 釣りか?
一番なんてものは主観だ
全て使ってみて自分で選べ
詳しくないが結構 MFC 嫌う人多いね。 Win32API の方が良いといって使ってたりする。
だれかwindows APIのみを使って、windowsアプリを開発できるC++の開発環境を開発してもらえないだろうか?
Windows APIつかえばいいじゃん
標準入力からnを入力して、 A[n][n]の配列を宣言するにはどうしたらいいですか?
int n; scanf("%d",&n); int A[n][n];
int **A; A=new int*[N]; for(n=0;n<N;n++)A[n]=new int[N];
vector< vector<int> > A(10); for(int n=0;n<10;n++)A[n].resize(10);
993 :
989 :2007/12/08(土) 11:52:25
994 :
989 :2007/12/08(土) 11:53:33
$ cat a.c #include <stdio.h> int main() { int n; scanf("%d", &n); int A[n][n]; for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) A[i][j] = i * 10 + j; for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) printf("A[%d][%d]=%d\n", i, j, A[i][j]); return 0; } $ cc -std=c99 a.c $ ./a 3 A[0][0]=0 A[0][1]=1 A[0][2]=2 A[1][0]=10 A[1][1]=11 A[1][2]=12 A[2][0]=20 A[2][1]=21 A[2][2]=22
C99とかだろ?
>>992 > vector< vector<int> > A(10);
> for(int n=0;n<10;n++)A[n].resize(10);
10 ってなんだ?
cin>>n;
vector<vector<int> > A(n,vector<int>(n));
かな。
C99じゃないんだろ。
>>997 自分の環境も書かずに質問するからそうなる。
1000
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。