【初心者歓迎】C/C++室 Ver.50【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2008/02/28(木) 00:01:39ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.49【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1203478421/
【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
0153デフォルトの名無しさん
2008/03/02(日) 00:26:06実装依存としか。
0154デフォルトの名無しさん
2008/03/02(日) 00:27:31要するにあれは構造体の初期化だよね。
コンストラクタが無ければクラスだろうが
あのタイプの初期化ができることを利用しているという。
0155デフォルトの名無しさん
2008/03/02(日) 00:44:180157デフォルトの名無しさん
2008/03/02(日) 01:11:03キー入力があればそれに対応した動きをさせたいのですがどうすれば良いでしょうか?
getch()だと入力待ちカーソルが邪魔になってしまい、困ってます
0158デフォルトの名無しさん
2008/03/02(日) 01:11:07いや、必要ではない。
0159デフォルトの名無しさん
2008/03/02(日) 01:13:39別スレで環境依存だといわれたろ?
なぜ環境を書かない
0160157
2008/03/02(日) 01:17:190161デフォルトの名無しさん
2008/03/02(日) 02:15:30実装方法ですか。
マクロを使うというとこういう感じになるのでしょうか?
ErrorLogger(char* filename, int linenumber, const char* errmsg)
のようなロガークラスを用意して、
コンストラクタ内でエラー内容を記録させてしまうようにしておいて
#define THROW(msg , exception_type) ErrorLogger log(__FILE__ , __LINE__ , msg);\
throw exeption_type\
というようなマクロを組めばよいのでしょうか?
というか、初めてマクロを組んだのであってるかどうかも判りませんorz
0162デフォルトの名無しさん
2008/03/02(日) 02:55:52自己レスながらマクロ修正してみた
#define THROW(msg , exception_type) ErrorLogger log(__FILE__ , __LINE__ , msg); \
exception_type e;\
throw e\
これでだいじょうぶですかね?
0163デフォルトの名無しさん
2008/03/02(日) 02:58:56ErrorLogger をクラスにする意味がわからない。関数でいいだろ。
例外オブジェクトにデフォルトコンストラクタしか使えないのは無駄な制限。
マクロ名は動作を表すように LOG_AND_THROW() とかにしたほうがよくない?
あと、最後の \ が余計。
0164デフォルトの名無しさん
2008/03/02(日) 03:00:120165デフォルトの名無しさん
2008/03/02(日) 03:03:37__FILE__, __LINE__ は inline 関数だとマズイだろ。
0166デフォルトの名無しさん
2008/03/02(日) 11:18:51do { \
:LogAndThrow(#type, __FILE__, __LINE__); \
throw type(); \
} while(false)
void LogAndThrow
0167デフォルトの名無しさん
2008/03/02(日) 11:19:130168デフォルトの名無しさん
2008/03/02(日) 11:26:43#define LOG_THROW(type) \
do { \
LogAndThrow(#type); \
throw type(); \
} while(false)
void LogAndThrow(const char* type_name)
{
ErrorLogger log;
// ここでログをとる
}
#else
#define LOG_THROW(type) \
do { \
LogAndThrow(#type, __FILE__, __LINE__); \
throw type(); \
} while(false)
void LogAndThrow(const char* type_name, const char* file_name, int line)
{
ErrorLogger log;
// ここでログをとる
}
#endif
こんな感じ。
実際には関数の実装は .cpp 側に書くわけだけど。
THROW という名前は何かと使われている恐れがあるので止めた方がいい。
LOG_THROW って名前も、実際には何か接頭辞を付けた方がいいと思う。
0169デフォルトの名無しさん
2008/03/02(日) 11:30:390170デフォルトの名無しさん
2008/03/02(日) 11:31:380171デフォルトの名無しさん
2008/03/02(日) 13:09:310172デフォルトの名無しさん
2008/03/02(日) 13:10:281行ずつ読み込みたければ getline が使える。
0173デフォルトの名無しさん
2008/03/02(日) 13:16:15int a;
ifs >> a;
みたいにやってるんですが、
> 読み込んだ内容が改行を含むかどうかチェック。
はどうやればいいですか
0174デフォルトの名無しさん
2008/03/02(日) 13:18:17それは無理じゃないかな。
0175デフォルトの名無しさん
2008/03/02(日) 13:20:54じゃあ、一行ずつ読みたいなら、getline()でやるしかないですか?
0176デフォルトの名無しさん
2008/03/02(日) 13:25:32子クラスのオブジェクトから、func(1)を実行すると、
func(const char* ch)を呼んでしまうのですが、
親クラスのfunc(int i)を呼ぶにはどうすればいいのでしょうか?
/*****こんな感じ*****/
class Parent{
public: void func(int i);
};
class Child : public Parent{
public: void func(const char* ch);
};
/*******************/
0177デフォルトの名無しさん
2008/03/02(日) 13:29:35そうなる。
getline した後 istringstream に渡してやるとか。
0178デフォルトの名無しさん
2008/03/02(日) 13:39:57Child ch;
ch.Parent::func(1);
0179デフォルトの名無しさん
2008/03/02(日) 13:47:37子クラス Child の func() によって親クラス Parent の func() が隠蔽されている。普通にオーバーロードしたいなら
class Child : public Parent {
public:
using Parent::func;
void func(const char* ch);
};
とすることで Parent での func() も見えるようになる。
0181デフォルトの名無しさん
2008/03/02(日) 14:27:55{
class Test
{
private:
std::ostringstream oss;
public :
~Test() {std::cout << oss.str();}
template <typename T>
friend Test &operator <<(Test &, T t);
};
}
template<typename T>
temp::Test &operator<< (temp::Test& test, T t)
{
test.oss << t;
return test;
}
を、temp::Test() << 2;
と使うと、「operator << が曖昧です」というコンパイルエラーになります。
名前空間を使わないとコンパイルできるのですが、何が問題なのでしょうか
Win2k、VC2005です
0182デフォルトの名無しさん
2008/03/02(日) 14:32:37temp::Test 内で宣言してる friend 関数は temp 名前空間内に入る。
だから、今は temp::operator<< と operator<< の2つがある状態。
0183デフォルトの名無しさん
2008/03/02(日) 14:37:08なるほど、ありがとうございました!
0184デフォルトの名無しさん
2008/03/02(日) 14:39:32temp 名前空間内に入れた方がいいと思う。
0185デフォルトの名無しさん
2008/03/02(日) 14:50:17goto文使うのって邪道かな?
いつも使ってるんだが。
0186デフォルトの名無しさん
2008/03/02(日) 14:50:540187デフォルトの名無しさん
2008/03/02(日) 15:17:28使いたい衝動に駆られたことはある。
0188デフォルトの名無しさん
2008/03/02(日) 15:19:020189デフォルトの名無しさん
2008/03/02(日) 15:23:442重ループから抜ける必要があること自体があまりないよね。
0190デフォルトの名無しさん
2008/03/02(日) 15:24:490191デフォルトの名無しさん
2008/03/02(日) 15:36:50NULLを入れると何が安全なのでしょうか?
0192デフォルトの名無しさん
2008/03/02(日) 15:38:350193デフォルトの名無しさん
2008/03/02(日) 15:39:180194デフォルトの名無しさん
2008/03/02(日) 15:40:13NULL じゃない場合は偶然アクセスできるかもしれないが、
メモリ領域を壊したり変な値を取得したりしてしまう。
0195デフォルトの名無しさん
2008/03/02(日) 15:41:420196デフォルトの名無しさん
2008/03/02(日) 15:49:10keybd_eventみたいに
プログラムからキーボードを押したことにするのは
gccだと何か方法がありますか・・・?
0197デフォルトの名無しさん
2008/03/02(日) 16:12:32keybd_event は Windows API。gcc はいろんな環境向けがあるコンパイラ。
例えば Windows 上で gcc を使っているなら keybd_event になるわけだしやりたいことをもっと正確に書こう。
0198デフォルトの名無しさん
2008/03/02(日) 17:26:18デフォルトコンストラクタっていうのは、
1.引数なしで呼ばれるコンストラクタ
2.なにも記述してなくてもデフォルトで呼ばれるコンストラクタ
のいったいどっちのことなのですか?
1と2の違いは、例えば、引数なしのコンストラクタを
自分で定義したときに、それをデフォルトコンストラクタと
いうかどうかという違いになると思うのですが、、、
1と2の説明ともWEB上で見かけますが、
どちらがより正確なのでしょうか?
0199デフォルトの名無しさん
2008/03/02(日) 17:29:15自分で定義しようがデフォルトコンストラクタ。
0200デフォルトの名無しさん
2008/03/02(日) 17:34:41引数なしで呼ばれるというよりは引数なしで呼ぶことが可能なと
いったほうがいいかもな。デフォルト引数もあるから。
class Widget {
public:
Widget(int i = 0) {}
};
//例えば
Widget w; //このsyntaxがデフォルトコンストラクタを要求する。
//Widget::Widget(0)が呼ばれる。
0203196
2008/03/02(日) 18:15:40すみませんでした
OSはDebianでPDFかパワポのようなものを
C言語で操作したいのです
具体的には下キーかEnterキーをC言語で押したことにして
スライドを進めることを行いたいです
0205デフォルトの名無しさん
2008/03/02(日) 21:56:29[email protected] までお願いします!
0206デフォルトの名無しさん
2008/03/02(日) 22:02:14C言語の個人講習をして欲しい訳だな?しかも無料で!
そんな奇特な人は少ないが候補として
C言語を覚えたてで自分のために他人に説明する人がいるが
そんな人を探すくらいなら良書を買ったほうがいくぶんかマシ
C言語をマスターしていながら教えてくれる人がいるとしたら
リタイヤした人くらいだろうな
0207デフォルトの名無しさん
2008/03/02(日) 22:08:50cin >> tmp;
としたとき、改行だけが押されたことを知るにはどうすればいいですか?
0208デフォルトの名無しさん
2008/03/02(日) 22:16:47フォーマット入力はデフォルトでは空白類記号は読み込まれない。
0209デフォルトの名無しさん
2008/03/02(日) 23:29:59分割コンパイルの仕方がわからないのですが
わかりやすく解説したページはないでしょうか?
0210デフォルトの名無しさん
2008/03/02(日) 23:33:01gcc -c hoge2.c
gcc -c hoge3.c
gcc -c hoge4.c
gcc -o hoge hoge1.o hoge2.o hoge3.o hoge4.o
0211デフォルトの名無しさん
2008/03/02(日) 23:55:20Makefileでググれば、良いと思う。
0212デフォルトの名無しさん
2008/03/03(月) 00:35:02{
class Cls;
}
0213デフォルトの名無しさん
2008/03/03(月) 00:48:480214デフォルトの名無しさん
2008/03/03(月) 00:52:06やっぱ標準であるmakeは一通りやっとくべきかな?
0215デフォルトの名無しさん
2008/03/03(月) 01:14:07ありがとうございます。一応自分で書いてみましたが、まだうまく動きません。
noskipwsをした後、おかしくなります。
どうかよろしくお願いします。
std::string filename = "default_file.txt";
while (1) {
std::string tmp;
cout << "Input file name : (hit return to default: " << filename << ") ";
cin >> std::noskipws >> tmp; // 下の(1)でY以外で答えたとき、ここで入力を受け付けてくれない。
if (tmp.empty()) {
// リターンキーだけが押された場合に、ここのIF文に入る
tmp = filename;
}
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin >> std::skipws;
cout << "filename : " << tmp << " OK (Y|N) ? ";
std::string ans;
cin >> ans; // (1)
if (ans == "Y") {
filename = tmp;
break;
}
}
0216デフォルトの名無しさん
2008/03/03(月) 02:22:41_CRT_DOUBLE_DECと_LDSUPPORTとこの2つに囲まれた構造体などは何のために用意してるんですか?
0217デフォルトの名無しさん
2008/03/03(月) 02:31:37改行は読み込まないからgetlineがいい。
std::string filename = "default_file.txt";
while (1) {
std::string tmp;
std::cout << "Input file name : (hit return to default: " << filename << ") ";
std::getline(std::cin, tmp);
if (tmp.empty()) {
tmp = filename;
}
std::cout << "filename : " << tmp << " OK (Y|N) ? ";
std::string ans;
std::getline(std::cin, ans);
if (ans == "Y") {
filename = tmp;
break;
}
}
0218デフォルトの名無しさん
2008/03/03(月) 02:43:47GUIでMFCやVCL、Qtさわるくらいはあるが、
ゲーム以外でフルスクラッチで書き上げる人たちって
どういう人?
0219デフォルトの名無しさん
2008/03/03(月) 02:44:130220デフォルトの名無しさん
2008/03/03(月) 03:24:20抽象化なんて考えてる暇あったら別の仕事が
飛んでくるもんね。
0221デフォルトの名無しさん
2008/03/03(月) 03:25:010222デフォルトの名無しさん
2008/03/03(月) 03:50:360223デフォルトの名無しさん
2008/03/03(月) 03:57:120224デフォルトの名無しさん
2008/03/03(月) 03:58:370225デフォルトの名無しさん
2008/03/03(月) 03:59:03matlabを使うとこも多いけど。
0226デフォルトの名無しさん
2008/03/03(月) 04:00:200227デフォルトの名無しさん
2008/03/03(月) 04:01:140228デフォルトの名無しさん
2008/03/03(月) 04:05:58COBOLとか使うと思うんだ、経験則
0229デフォルトの名無しさん
2008/03/03(月) 04:51:56色々分かってきたのですが、getlineとcinとの併用のときにどう書くべきかわかりません。
#include <iostream>
using namespace std;
int main()
{
int a;
string s;
cout << "int: ";
cin >> a;
// cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "string: ";
getline(cin, s);
cout << "int: ";
cin >> a;
return 0;
}
上記のソースでコメントアウトしている箇所がありますが、コメントアウトしたままだと、
真ん中のstringの入力が、1つめのintの入力の改行を拾ってしまうせいで、とばされてしまいます。
そこで質問なのですが、ここにコメントアウトされている行をいれるのは正しいですか?
0230デフォルトの名無しさん
2008/03/03(月) 05:00:45コメントアウトした行を入れてもだめ。
cin >> a; で改行文字がバッファに残るため、それが次のgetlineで
読み取られてしまう。Cで言う所のscanf()とgets()を混在させた問題と同じ。
解決策はgetline(cin, s); をもう一つ付け足して改行文字を読み飛ばす。
もしくはgetline()に統一する。
0231デフォルトの名無しさん
2008/03/03(月) 05:37:290232デフォルトの名無しさん
2008/03/03(月) 05:42:58金融っていってもmatlab使ってるようなところは
複雑な数値計算やってるだろうからちょっと特殊だな。
車でもカーナビのように限られたリソースでGUI作るようなところは
使ってるだろうが、間違っても制御には使わんと思うんだが。
0233デフォルトの名無しさん
2008/03/03(月) 05:53:38ありがとうございます。
getline()とcinを混在させないのが一番いいと。でも、cinが便利なので、
基本的にはcinを使いつつ、cinだと改行を扱うのが不便なのでその時だけgetline()を
使う、という風になりそうです。(自分としては)
すると、
(1)getline()する前にバッファに改行が残っているか確認して、残っていれば消す。
(2)cinした後には改行を消しておく。
のどっちかになると思うのですが、今回は(1)の方法が分からなかったので、(2)で実装しました。
どっちにしても、cin関係はなんか使いにくい感じ。
0234デフォルトの名無しさん
2008/03/03(月) 06:03:00mmap でファイルを仮想メモリにマッピングしたとき、OSがファイル上のデータを
ブロック転送する、アプリがその領域に書き込むとOSがファイルにそれを反映すると
書いてあった。
mmapでマップされた領域に上のあるアドレスに代入したとき、
OSは代入されたことを知っているの?
代入演算子で値を放り込むことと、read write のシステムコールを使うのは
根本的に違いますよね?
0235デフォルトの名無しさん
2008/03/03(月) 06:03:27GEANTは4からC++だよ!
0236デフォルトの名無しさん
2008/03/03(月) 06:09:53C/C++の問題じゃないと思う
多分OSがマッピングした領域は書き込み不可の属性が付いており
書き込んだらCPUに割り込みがかかってそれを利用してファイルに反映してるか
そんな所だと思う
0237デフォルトの名無しさん
2008/03/03(月) 06:14:44失礼しました。
環境に依存する内容は避けたほうがよいですね。
0238デフォルトの名無しさん
2008/03/03(月) 06:52:21環境依存OKのスレだから問題ないんだけどC/C++よりも
linuxの話になるね
ちなみにWindowsの仮想メモリとメモリマップトファイルも似たような
機構で実現している
0239デフォルトの名無しさん
2008/03/03(月) 07:59:34こんなのを考えてみたのですが、こういう2分木辞書ってなんて
名前になるんでしょうか?
サフィックスツリー?(これよりもっと複雑なようですが)
typedef std::map<char, Node> Tree;
//char に単語の1文字が入る
struct Node {
Node *pChild; //次の文字ノード
int No; //登録番号、兼、非末端(-1)
}
単語がab,ba,ac,abcとあるなら、子ノードの繋がりが下記のようになる。
先頭 <a,-1> <b,-1>
/ \ /
<b,0> <c,3> <a,1>
/
<c,3>
0240デフォルトの名無しさん
2008/03/03(月) 08:01:07struct Node {
Tree *pChild;
int No;
}
0241デフォルトの名無しさん
2008/03/03(月) 09:10:06って演算はいったい何を行っているのでしょうか?
最初オフセット値を得ているのかと思ったんですが、ためしに出力しても、1が出力
されるだけです。
元ソースでは、これを引数にしてメンバ変数のオフセット値を得ているようですが…
0242デフォルトの名無しさん
2008/03/03(月) 09:11:38メンバポインタでぐぐれ
0243デフォルトの名無しさん
2008/03/03(月) 09:27:45ありがとうございます。おかげで理解できました。
メンバポインタからオフセット値を得るには、
&( static_cast<A*>(0)->*memPtr )
で仕様上問題ないでしょうか?
0244デフォルトの名無しさん
2008/03/03(月) 09:35:430245デフォルトの名無しさん
2008/03/03(月) 11:13:30実際には動くだろうけど、仕様上は良くないような
ちゃんとインスタンスを用意した方がいいんじゃない
0246デフォルトの名無しさん
2008/03/03(月) 11:30:26オフセットは POD 型に対しての offsetof でしか取れないよ。
素直にメンバポインタ通して参照しちゃダメなの?
0247デフォルトの名無しさん
2008/03/03(月) 12:07:59仕様上正しい。
以下はJosuttis本の記述の要約。
istream& istream::ignore(streamsize count, int delim)
This form ignores up to count characters until delim is extracted and discarded.
(ストリームから改行まで抽出されて捨てられる。)
ちなみにg++ 4.0では無問題だった。
0248デフォルトの名無しさん
2008/03/03(月) 12:50:21トライ木じゃねえの
0249デフォルトの名無しさん
2008/03/03(月) 15:03:37割り込みなんかかからない。
ページング機構を備えるどんなプロセッサでも(俺の知る限り)
プロセッサ自体に、書き込まれたかどうかのフラグ
(いわゆる、dirty bit と呼ばれるもの)をセットする機構がある。
例えばx86ならば、ページテーブルの該当ページを示すエントリ内にこれがある。
で、ファイルから読み込んだときにOSがこのフラグをリセットしておき
OSは、ページが不要になった時やsync要求が来たときにこのフラグを確認して
書き戻すか破棄するかを決定する。
0250デフォルトの名無しさん
2008/03/03(月) 15:09:16それみたいですね。
すっきりしました、感謝。
0251デフォルトの名無しさん
2008/03/03(月) 16:48:21仕様上ダメですか…違う方法を模索することにします。
0252デフォルトの名無しさん
2008/03/03(月) 20:58:31すみません。
read write のようなシステムコールを実行するとOSデバイスドライバが
あとは処理してくれますよね?
代入演算子を使ってmmapした領域に書き込むとき、
そのフラグもセットするようにgccが実行ファイルを生成してくれるのでしょうか?
でもそれだと操作するアドレスがどこなのかをプログラムソースには書かなくても実行ファイルの中では
毎回見ているということでよろしいのでしょうか?
■ このスレッドは過去ログ倉庫に格納されています