はきだめC/C++下級者 ..
[2ch|▼Menu]
39:デフォルトの名無しさん
06/09/01 05:02:26
char *list[num]は、ポインタの配列だが、配列の中身(=各ポインタの値)は不定。
C99とGCC以外では、配列の大きさは「定数」として、コンパイル時に決まってなければいけない。
あらかじめわからない場合は動的に確保する。(何も考えずにvectorを使うのも可)

40:デフォルトの名無しさん
06/09/01 07:48:28
>>39
アドバイスありがとうございます。
vector使って書いてみました。
vectorとstringで、文字数と行数が動的できたと思うんですが、
これで大丈夫でしょうか?ちょっと心配です。

int main()
{
std::ifstream fin("hoge.txt");
if(!fin){
printf("エラー");
return -1;
}
std::vector<std::string> list;
std::string s;
while(!fin.eof()){
getline(fin,s);
list.push_back(s);
}
for(int j=0; j<list.size(); j++){
printf("%s\n",list[j]);
}
fin.close();
return 0;
}


41:デフォルトの名無しさん
06/09/01 08:46:05
listという名前のvector...

42:デフォルトの名無しさん
06/09/01 09:25:52
「大丈夫でしょうか?」って・・・実行はしてみたの?

43:デフォルトの名無しさん
06/09/01 09:46:35
そりゃ一応動くらしきもの書いて、期待の動きはしてるようだが
はたして重大なバグが潜んでいないか心配なので添削お願いできますか
ということだろ。なんでみんなギスギスしてんの?

44:デフォルトの名無しさん
06/09/01 10:53:29
はきだめだから

45:デフォルトの名無しさん
06/09/01 11:16:17
だよな

46:デフォルトの名無しさん
06/09/01 18:55:48
まあとりあえず
・while (!fin.eof()) {} というやり方は大抵望み通りの動作にはならない
・printfにstringをそのまま渡しても大抵望みどおりの動作にはならない
とだけ

47:デフォルトの名無しさん
06/09/01 21:39:21
これで十分だろう。
while (getline(fin, s)) {
    list.push_back(s); 
} 

48:デフォルトの名無しさん
06/09/01 22:41:15
>>46
c_str()無いですね。
正常に動いてたっぽいんですが、違うソース
貼り付けてしまったのかもしれません。
while (!fin.eof()) {} は良くないですか。
奥が深いです。
難しいので今後の課題にさせてください。

>>47
ありがとうございます。
while (getline(fin, s))というのもできるんですね。
こちらに変えてみます。

49:デフォルトの名無しさん
06/09/01 23:19:17
while (!feof()) 系のやり方の駄目具合は、
最終行に改行だけの行(空行)がないファイルや
最後に改行がないファイルを扱ってみるとわかる。
なぜそうなるかは、feof()の仕組みを考えながら動きを追ってみるとよい。
もちろん、fin.eof()でも同じ。

50:デフォルトの名無しさん
06/09/01 23:29:51
Cのfeof()が立つのは、ファイルを読んだ後。
              ~~~~~~~~~~~~~~~~~~~~~~
BASICとは違うのです。

51:デフォルトの名無しさん
06/09/02 00:13:19
クララが立つのはいつ?

52:デフォルトの名無しさん
06/09/02 00:27:24
においのいい草を食わせた後

53:デフォルトの名無しさん
06/09/03 01:29:21
>>49
>>50
詳しくありがとうございます。
こういうのって、経験して覚えていくんでしょうか。
覚えることがいっぱいあって大変です。

54:デフォルトの名無しさん
06/09/04 05:53:30
すごい簡単なことなんですが、ifの条件ってintだと、
0はfalseでそれ以外はtrueっていうことでよかったでしょうか。
-10~10までやってみました。
自分で関数作るときに-1をfalseにしてたんですが、
ほかの人がみたら変に思われますか?

#include <stdio.h>
for(int i = -10; i<10 ; i++){
if(i){
printf("%dはtrue\n",i);
}else{
printf("%dはfalse\n",i);
}

}

55:デフォルトの名無しさん
06/09/04 05:59:34
確認画面見ようと思ったら
書き込まれてしまいました。

コード、段落とかint main()とか抜けててすみません。

56:デフォルトの名無しさん
06/09/04 06:09:48
>>54
> すごい簡単なことなんですが、ifの条件ってintだと、
> 0はfalseでそれ以外はtrueっていうことでよかったでしょうか。
良い。

> 自分で関数作るときに-1をfalseにしてたんですが、
> ほかの人がみたら変に思われますか?
非負値を返す関数のエラーとして負値を返す事はある。
getchar の EOF とか。
真偽値しか返さない場合は、偽の場合 0 を返すのが当然。
真の方に関しては、何を返すかは case by case だが、
普通は 1 を返したのでいい。
is 系関数とか、真の時 1 以外の値も返す実装の場合もあるけど、
これは高速化の為にそうしてるだけ。
まあどちらにしろ、非 0 を返すのが当然。
C++ なら普通は bool 型にして true/false を返すけど。

57:デフォルトの名無しさん
06/09/04 06:29:01
さっそく、お返事ありがとうございます。

勉強始めたばかりなんですが、本でエラーのとき
return -1っていうのがあったような気がして、
-1にしてたんですが、if文書いてて「あれ」っと思いました。

いろんな種類のエラーを返す複数のエラー処理を
してたのも知れません。

0が偽で1が真ですか。了解しました。

58:デフォルトの名無しさん
06/09/04 09:44:59
>57
「エラーを返す」と「偽を返す」の違いを考えてみよう

59:デフォルトの名無しさん
06/09/04 21:24:03
エラーの内容が複数ある場合は、
0 を正常として、他の値をエラーとするね。

60:デフォルトの名無しさん
06/09/04 21:31:23
俺は0をエラー、1を正常にして、エラー番号をポインタでもらった引数に入れる。

61:デフォルトの名無しさん
06/09/04 21:41:19
そういう実装も見るね。

62:デフォルトの名無しさん
06/09/04 23:23:19
UNIX系で 0=OK、 1、2、3、4=エラーって見かける


63:デフォルトの名無しさん
06/09/04 23:28:30
DirectX も D3D_OK(0) が正常で他がエラーとか。

64:デフォルトの名無しさん
06/09/04 23:30:30
質問です。
std::vector<std::vector<int> > array;

とある場合、clearをする場合は
array.clear();
を呼ぶだけでメモリは解放されるのですか?
それともループでまわしながら解放しなければいけませんか?

65:デフォルトの名無しさん
06/09/04 23:37:51
>>64
array.clear() でいいよ。ループは要らない。

66:64
06/09/04 23:54:11
>65

どうもありがとうございます。
助かりました。

67:デフォルトの名無しさん
06/09/05 00:04:00
ちょっとクラスについて質問です。

入門用の本とかを見ると、C++のクラスは
Javaで言うJavaBeansみたいな使い方ばかり書いてあるけど、
関数の塊のようなクラスは、普通作らないものなのでしょうか?

単純にヘッダをインクルードして関数を呼び出すものなのか、
それとも関数群をクラスにして、そこから呼び出したほうがいいのか。
悩んでおります。

68:デフォルトの名無しさん
06/09/05 00:09:48
>>67
クラスにするメリットがあるなら、そうすればいい。
Java とか関係無しに、それだけの話じゃないのか?

69:67
06/09/05 00:24:16
>>68
オブジェクト指向って言うから、オブジェクト的にしなきゃ
いけないのかなぁ、と思いまして。
好きにすりゃいい、ってことなんでしょうけど。

特にメリットもなく、関数全部クラスにしたようなプログラムは
クソソース扱いなんだろうかと思うと、夜も寝られません。

70:デフォルトの名無しさん
06/09/05 00:34:30
>>69
何のメリットも無いのに複雑度を上げるソースは糞ソースに違いない。

71:デフォルトの名無しさん
06/09/05 00:40:54
> 関数の塊のようなクラス
俺からすれば、これはJavaが普通の関数を持てない(全てクラス内に入れないといけない)から、
仕方なくやっているという風にしか見えない。

72:67
06/09/05 00:46:56
>>69
確かにそうッスね。
ライブラリとして、クラスにしてまとめるのも変?

>>71
あ、僕も最初はそう思ってたけど、だんだん麻痺して、
最初にクラスありきな頭になってたかも。

73:デフォルトの名無しさん
06/09/05 00:54:51
その関数群が共通となるデータを持たないのなら、クラスにする必要ないでしょ。
まぁ、共通のデータ構造を持っているならネームスペースに放り込んじゃえばいいしね。

74:デフォルトの名無しさん
06/09/05 08:13:31
あるフォルダのどんどん増えていく複数のテキストファイルを圧縮するって
いうアプリを作りたいのですが質問です。

複数のテキストファイルを選択して、zipなどで圧縮するというのは
できると思うんですが、新しく増えたテキストファイルを圧縮ファイルと
一緒にする方法を悩んでいます。
私の頭では、下記のような手順しかできそうにありません。
@圧縮したファイルをフォルダに解凍
A新しいファイルをそのフォルダにコピー
Bまとめて圧縮

ただ、この方法だと圧縮された容量の大きいファイルを
毎回、解凍、圧縮することになります。
それで、下記のようなようなことをしたいんですが
アドバイスをお願いできないでしょうか。

新しいファイルを圧縮して、それを圧縮ファイルに追加で
書き込むっていうことができれば、負担が少なくて良いかと
思っているんですがどうなんでしょうか。

また、圧縮ファイル内でもファイル名で区切れば、
全部解凍しないでも、そのファイル名での区間を
読み取って解凍すれば部分的に取り出すことができると思います。

えっと、圧縮するときも解凍するときも毎回丸々全部を
計算しないで、加えるところだけ圧縮、
読みたいところだけ解凍って言うことがしたいです。

75:デフォルトの名無しさん
06/09/05 08:16:28
>>74
やりたいことはわかった。あとは、何をやったらどんな問題が出たのかも書いてほしい。

76:デフォルトの名無しさん
06/09/05 08:18:11
>>74
使ってる圧縮フォーマットは何?
ライブラリ使って操作してるんなら、どのライブラリ?

77:デフォルトの名無しさん
06/09/05 08:25:14
>>75 それはもう書いてあるだろ。

78:デフォルトの名無しさん
06/09/05 08:38:15
>>75
>>76
すみません。実はこれから作ろうと思ってます。

ろくに調べないで質問してしまい
申し訳ございません。当方、初心者なのでこういうことが
実現可能かどうかわからず、それが知りたいということでした。
確かに、何が聞きたいのかわからない文章でした。
実現できそうということで、ひとつずつ調べて
書いてみます。
わからないことがあったら、また
よろしくお願いします。
時間掛かりそうですが、できたらコード書きます。

ありがとうございました。

79:デフォルトの名無しさん
06/09/05 08:45:23
共通アーカイブライブラリに行ってみたらどうだろう。

80:デフォルトの名無しさん
06/09/05 10:02:02
>77
m9プ

81:デフォルトの名無しさん
06/09/06 11:37:38
少なくとも、自前実装であれば、実現はできるだろう。
何かのライブラリ使うなら、マニュアルを百万回繰り返して読んでみてくれ。
俺なら、>>79の方法をとるが…。(でも、ZIPだけシェアウェアだったような希ガス…。)

うろ覚えですまんが、lzhだったら、全体のヘッダの後に、個数分の(ファイルごとのヘッダ+圧縮データ)が並んでるだけ。
だから、最後に単純にデータ付加すりゃヨロシ。

zipは知らないので、今、仕様を斜め読みしてみたが、最初のヘッダがなくて、個数分の(ファイルごとのヘッダ+圧縮データ)が並んで、
なんか、最後に変なデータ(ディレクトリツリーのデータ?)がついてるみたい。
(バイナリエディタで、zipファイルを覗いてみても、最後のあたりに、ファイル名のデータが入ってるね。)
まあ、それでも、たいした大きさじゃないので、どこかにデータ退避させれば、簡単にデータ付加できるだろ。


82:デフォルトの名無しさん
06/09/07 14:53:42
ファイルの読み込みの仕方を教えてください
PGM形式の画像を読み込みたいんですが、コメント行の読み飛ばしなどがよくわかりません。
どうやって読み込んだらいいのでしょうか?

83:デフォルトの名無しさん
06/09/07 15:01:05
>>82
つ[libpnm]

84:デフォルトの名無しさん
06/09/08 06:22:28
C++の資格って何かありますか?

85:デフォルトの名無しさん
06/09/08 07:46:02
>>82
pngじゃないのかよワロス
テキスト形式の画像フォーマットなんだ。おもしろい。
読み込み専用でいいなら、Susieのプラグインもあるみたいだね。

コメント行の最初は#になってるんだね。(改行は\n限定(\r\n不可)で。)
じゃ、最初1バイト読んで、分岐させて、次の行に逝けばいいじゃん。
ファイルから読んでるのか、メモリから読んでるのか、
また、テキスト読み込みには、何のクラス・関数使ってるのか分からんので、
これ以上は答えられない。

>>84
基本情報技術者・ソフトウェア開発技術者は持ってるので、
別の資格が欲しいってこと?


86:デフォルトの名無しさん
06/09/08 08:55:19
>>85

基本情報は取ったんだけど何とろうか迷ってる
さすがに今更サーティファイのCやJAVAなんて受ける気になれないしさ


87:デフォルトの名無しさん
06/09/08 09:14:14
資格より職務経歴

88:デフォルトの名無しさん
06/09/08 11:27:15
コールバックについて質問です。
手元の本3冊にも全く書いてないのですが
どのように書けばよいのでしょうか。

コールバック関数は普通の関数みたいなんですが、
呼び出す側の関数がどのように書くものなのかわかりませんでした。
下記は、pro2の引数がおかしいっていうエラーがでますが
呼び出した関数が実行されて、次にコールバック関数が実行、
"hello2hello"と出力されることを期待して書きました。

ネットで関数のポインタを渡すと呼ばれるって解説があったので、
ただ、priを引数に入れただけです。
これを動くようにしたいんですが、よろしくお願いします。
簡単に説明しているページなども歓迎です。

#include<stdio.h>
int pri(){
   char* str = "hello";
   printf("%s",str);
   return 1;
}
int pri2(pri){
   char* str = "hello2";
   printf("%s",str);
   return 1;
}

int main()
{
   pri2(pri);
   return 1;
}

89:デフォルトの名無しさん
06/09/08 11:35:19
>>88 URLリンク(www.google.co.jp)

90:デフォルトの名無しさん
06/09/08 13:09:32
>>89
関数ポインタで、ぐぐれば良かったですか。
見てみます。
ありがとうございました!


91:デフォルトの名無しさん
06/09/08 15:17:37
お世話になっております。
関数ポインタのページいくと、コールバック関数について
触れているページもありました。

自分で作った関数を引数にして渡せるAPI関数(なかのコードがわからないブラックボックスの)
なんか見かけるんですが、ちゃんとその関数は、返り血の型、引数の型と個数が
定義されていて関数の中でポインタで呼び出されてるんですね。
ただ単に、引数にコールバック関数の名前だけを入れると
実行されるわけでは無いんですね。
普通に考えてもそんな意味のわからないルール作らないですよね。

見かけてもいきなり関数名だけ、引数に入れているので今まで
意味がわかりませんでした。

と思ったのですが、こういう解釈でよかったでしょうか。

92:デフォルトの名無しさん
06/09/08 18:34:13
>>91
解釈と感想がごっちゃになっててよくわからん。
きっと君自身ごっちゃになっているのだろうね。
先ずは、他人にきちんと説明できるように整理してみたら?

93:デフォルトの名無しさん
06/09/09 14:09:42
環境
OS:windows2000
コンパイラ:Borland C++

プログラム中においてフォルダを作成して
その中にデータファイルの保存をしたいんですけど、
どうやればいいんですか?

94:デフォルトの名無しさん
06/09/09 15:06:52
つ[mkdir()]

95:93
06/09/09 17:31:20
>>94
#include<windows.h>

int main(void)
{
system("md test");
return 0;
}

これで実現することができました。
ただこれだとフォルダ名が固定になってしまいます。
そこでフォルダ名を決めれるようにするにはどうしたらよいのでしょうか?


96:デフォルトの名無しさん
06/09/09 18:26:21
>>95
mkdir()は使わんの?
どちらにしろユーザーから入力された文字列を渡せばいいじゃない。
めっちゃ基本中の基本だけど。

97:デフォルトの名無しさん
06/09/09 18:31:00
>>95
つ[sprintf()]
つ[boost::format()]
つ[_mkdir()]
つ[CreateDirectory()]
つーか、調べるってことはできんもんかね。

98:デフォルトの名無しさん
06/09/09 21:32:04
systemなんて恐ろしい関数をよく使う気に

99:デフォルトの名無しさん
06/09/10 14:20:44
まあ確かに普通はあまり使わんかな。
外で何されてもわかんないもんなー。

100:デフォルトの名無しさん
06/09/10 20:58:47
現在ポインタ及びリスト構造の学習中で
tagData * EraseNext(tagData *p);
こういう文を見かけたのですが、どういう意味かわかりません
tagdata * の”*”はどういう意味でしょうか?

101:デフォルトの名無しさん
06/09/10 21:18:35
>>100
仮引数と同じ、tagDataへのポインタ。としか言いようがない。

102:デフォルトの名無しさん
06/09/11 10:12:05
ポインタの学習中でその質問はないだろー

103:デフォルトの名無しさん
06/09/11 10:33:44
×学習中
○たった今学習を始めたところ

104:デフォルトの名無しさん
06/09/11 15:33:01
たとえば、(tagData* p)と、(tagData *p)を別物と思ってるとか。


105:デフォルトの名無しさん
06/09/11 17:51:29
初心者以前のレベルの質問なのでこちらにきました。
telnetのクライアントの送受信の並列処理(マルチスレッド)について質問です。

telnetクライアント並列処理(親スレッドは受信、子スレッドは送信)を
実装することは、どういうことができるようになることなのでしょうか?
受信と送信のスレッドが起動していて、受信も送信もどちらでもできて、
単純な"送信→受信"だけじゃなくて、
「接続が確立したらいきなり"受信だけ"とか"受信→送信"というのもできる」ように
なることをいうのでしょうか?

サーバーの場合は、親スレッドがアクセプトして、
子スレッドを作って処理をさせることによって、
「複数のクライアントを相手することができる」というのは勉強しました。

よろしくお願いします。

106:デフォルトの名無しさん
06/09/11 18:14:08
>>105
送信が連続している状況でも安定して受信できる。
telnetのプロトコルはチャットほど単純じゃないから敢えてそうすることもあるんでないかな?

107:デフォルトの名無しさん
06/09/11 21:15:07
>>106
ありがとうございます。
>送信が連続している状況でも安定して受信できる。
スレッドがたくさん作られるということでしょうか?

スレッドだとちょっと複雑で自分的に難しいので、マルチプロセスで考えさせてください。
以下かなり省略した物になりますがコードです。

if(pid>0){
 //親プロセス
  while(1){
   //受信処理
  }
 //シグナル送信、プロセス終了の処理
}

else if(pid=fork()){
 //子プロセス
  while(1){
   //入力と送信処理
  }
 //シグナル送信、プロセス終了の処理
}

サーバーの場合、たくさんのプロセスが作られることになると思いますが、
上記のコードの場合は、親と子2つしかプロセスが作られないことになりますでしょうか?
アプリケーションを起動すると"標準入力から送信"、"受信"この2つのプロセスが起動して同時にできるだけ。
送信を連続でした場合、受信は並列ではなく、送信した命令の順番どおり受信することになるでしょうか?

長文すみません。変なところあると思いますので
ご指摘ください。補足させていただきます。
よろしくお願いします。

108:デフォルトの名無しさん
06/09/12 01:46:54
>スレッドがたくさん作られるということでしょうか?
いいえ。

>上記のコードの場合は、親と子2つしかプロセスが作られないことになりますでしょうか?
はい。

>送信を連続でした場合、受信は並列ではなく、送信した命令の順番どおり受信することになるでしょうか?
サーバの御心次第です。

telnetプロトコルもそうだが、例えば標準入出力をみても必ずしも対になっていないことに注意。

109:デフォルトの名無しさん
06/09/12 08:23:15
>>108
ずばりの回答ありがとうございます。
すっきりできました。

110:デフォルトの名無しさん
06/09/22 03:42:09
pthread_createで複数スレッドを作ったときの
プロセス内のスレッドの数が知りたいんですが方法
ありますでしょうか。
よろしくお願いします。


111:デフォルトの名無しさん
06/09/24 01:24:23
linuxのfork+execについて質問です。
下記のコードは10回繰り返し、execvを繰り返して、
プロセスが生成できなかったときは、もう一度繰り返したいため
失敗したときに、i--;してます。
・このコードでエラーのときの処理できているか確認したいのですが、
 プロセス生成をわざと失敗するようにすることできるでしょうか?
・i--で繰り返しの処理はできてるでしょうか?

for(i=0;i<10;i++){

    //子プロセスの生成
    if((pid=fork())==0){
        execv(path,opt);
    }else if(pid>0){
        //親プロセス
    }else{
        //子プロセス生成失敗の時はiを一つ減らして繰り返し
        i--;
    }

}

112:デフォルトの名無しさん
06/09/24 03:10:28
>>111
実験してみたいだけならこんなマクロでも用意すればよろしかろ。
#define myFork(x) (fgetc(stdin) != (x) ? fork() : -1)
#んで、fork()の代わりにmyFork('\n')とでもすればいい。

113:デフォルトの名無しさん
06/09/24 07:36:29
>>112
関数のマクロ定義ってこういうふうに使えるんですね。
はじめてみました。
ど初心者なので感動しました。
どうやって勉強していけば、こういう感覚が身につくんだろう。。。

114:デフォルトの名無しさん
06/09/24 20:28:57
「勉強」しているうちは無理。

115:デフォルトの名無しさん
06/09/25 09:28:13
君は勉強をやめたの?

116:デフォルトの名無しさん
06/09/26 00:58:06
>>115
やってることは同じでも「勉強」だと認識してやってるようなうちは芽が出ないってこと。

117:デフォルトの名無しさん
06/09/26 09:10:23
なにその理屈w

118:デフォルトの名無しさん
06/09/26 12:04:37
勉強をやめてしまうことこそ芽がしぼむだろ普通に考えて。

119:デフォルトの名無しさん
06/09/26 12:09:54
日々是勉強

120:デフォルトの名無しさん
06/09/28 10:52:48
ファイルの排他制御をしたいのですが、open()関数を使って、
ファイルディスクリプタをflockの引数に入れてロックする方法はできました。
ディスクリプタではなくて、ストリームを使って排他モードで開きたいと思ってます。
コードです。
#include <fstream>
int main(){
using namespace std;
ifstream fin;
fin.open("filepath",ios::in, filebuf::sh_none);
return 0;
}
こんなエラーが出ます。
error: `sh_none' is not a member of `std::filebuf'

URLリンク(www.codeguru.com)
こういうページが見つかったので、filebuf.sh_noneにしてみましたが
だめでした。
買ったばかりのlinuxのパソコン壊れて、現在の環境はcygwinです。
・filebuf::sh_noneはどのようにすればよいでしょうか。
・排他制御は、他にスマートで簡単な方法ありますでしょうか。
よろしくお願いします。

121:デフォルトの名無しさん
06/09/28 11:49:22
filebuf.sh_noneなんて非標準だから使えないのは別に悪く無い。
正攻法ではファイルディスクプリタで読み書きするバッファクラスを自分で作れということになるのだが、まあ面倒。

122:デフォルトの名無しさん
06/09/28 14:42:23
>>121
お返事ありがとうございます。
>filebuf.sh_noneなんて非標準だから使えないのは別に悪く無い。
非標準とかそういうこともあるんですか。知りませんでした。
URLリンク(www.kumei.ne.jp)
有名そうなページでもfilebufってでてきたので、エラーがでるのは、
自分の書き方が変だと思いこんでました。

いろいろ検索してみると、ifstreamで排他モードはできない
と書いてある掲示板の書き込みもありました。
windowsだとライブラリあるんですが、linuxだとそういうの
簡単にできるの無いっぽいです。
boostもちょっと見てみたんですが良くわからないし、
自分のスキル的にopen+flockじゃないとだめのようです。

123:デフォルトの名無しさん
06/09/28 15:04:29
実はflock()は完全ではない罠。

124:デフォルトの名無しさん
06/09/29 00:01:02
>>123
flock調べたんですが、どういうところが完全じゃないんでしょうか?
cじゃなくてperlのページなんですが、自分でファイルのある無しの
関数作るよりも、flock使うほうがいいってあったんですが。

検索していたらこういうページを発見しました。
URLリンク(www.tietew.jp)
[io]fstream <=> fd
こういうことできるってことしか読み取れませんでしたが、
1、[io]fstream で開く、
2、[io]fstream => fdでディスクリプタ取得
3、flockでロック
4、[io]fstreamで操作
っていうことができないでしょうか。
ストリームとディスクリプタがどんなものかわかって無いので、
並行して操作できるのかどうかわかりませんが。
4番目の操作が、ストリームで操作できないと、
はじめからディスクリプタで開くしかないですよね。
読んでもわからないので、とりあえずやってみるしか無いでしょうか。

125:デフォルトの名無しさん
06/09/29 06:50:45
flock()は、flock()を使わないプロセスからのアクセスを制限できないんじゃないのか?
誰もがflock()使ってアクセスする保証があるなら問題ないが。

126:デフォルトの名無しさん
06/09/29 09:43:57
それを問題あると言っちゃうのか・・・。

127:デフォルトの名無しさん
06/09/29 11:25:46
>>125
>>126
お返事ありがとうございます。

>flock()は、flock()を使わないプロセスからのアクセスを制限できないんじゃないのか?
なんかひらめいたかもしれません。
はじめfdで開いてflockします。同じプロセスならそのままfstreamでファイルを
開いて操作できそうです。
違うプロセスでもflockを呼び出さなければfstreamでファイルを開いて
操作できそうですね。実験したらflockを呼び出さなければ待機しませんでした。
fstream.openって返り値ないので、ちゃんとオープン
してるのかわからないんですが。書き込みしてみて確認してみたいと思います。

なんかflockの仕組みがやっとわかってきました。
>>124みたいなややこしいこと考えなくてもよさそうです。

○自前のflockでも他のプロセスは同じ自前のflockを、
呼び出さないとだめなので、その点はシステムコールの
flockと同じということよろしかったでしょうか?

○必要なくなってしまいましたが、[io]fstream <=> fd
の関数はどれでどのような使い方かご教示
お願いできないでしょうか。
参考になるのかわからないですが
URLリンク(www.tietew.jp)
環境が対応していないのか、わかりませんせんがいろいろ
試しても動きませんでした。
よろしくお願いします。

128:デフォルトの名無しさん
06/10/01 13:49:36
Cで、ある一定時間内に入力がなければ
次の処理に移る、ということをしたいんですが
どのように書けばいいのでしょうか。

129:デフォルトの名無しさん
06/10/01 14:01:09
一定時間内に入力が無いってどういうこと?
関数内で、tm構造体からforかwhileで時間取ってはその時間の差分とって
条件満たせば、関数を抜け出すようにしてみれば?


130:デフォルトの名無しさん
06/10/01 14:15:22
キーボードからの入力のことです。
ずっと入力待ちなるんじゃなくてしばらくしたら飛ばしたいんです。
while(時間の条件){
scanfとか;    ←ここでずっと止まったりしないですかね?
}

131:デフォルトの名無しさん
06/10/01 14:24:45
標準Cでは無理だね。
「キーボードが押されたか」の検出は。

132:デフォルトの名無しさん
06/10/01 14:37:52
そうですか・・・。ありがとうございました。

133:デフォルトの名無しさん
06/10/01 14:48:47
標準Cでできないとはつまり、
WindowsならWindowsの関数、UnixならUnixの関数使えばできるよということ。

134:デフォルトの名無しさん
06/10/01 15:14:13
機種依存スレに行けばいいかも。
Windowsだったら思い切ってAPIスレへ。

135:デフォルトの名無しさん
06/10/02 01:13:41
夜遅くにすみません…

今、VC++でプログラミングしてるんですが、
ダイアログボックスから変数を持って行きたい時はどうすればいいですか?

例えば

ダイアログボックスで
次の数の二乗を算出します
とか書いてユーザに入力を求めて、そしてユーザが入力したら
その値を元に計算→出力
的な感じなんですが…

136:デフォルトの名無しさん
06/10/03 03:14:22
ヘルプを見ろ。それで全てが解決する。

137:デフォルトの名無しさん
06/10/04 22:20:22
class CDSig : public CDialog
{
// コンストラクション
public:
CDSig(CWnd* pParent = NULL); // 標準のコンストラクタ



以下略
------------------------------------

VCでダイアログを作成しクラスCDSigを作成したところ自動で上のようなクラスが
自動で作成されました。
標準でコンストラクタが出来ているようですが、自前でクラス内の変数を初期化する
コンストラクタを作成するにはどうしたらよいのでしょう?
名前CDSigの定義を追加すると
  error C2668: 'CDSig::CDSig' : オーバーロード関数の呼び出しを解決することができません。
と怒られます。

138:デフォルトの名無しさん
06/10/05 00:05:25
>>137
その「標準のコンストラクタ」の定義を変更しろ。

139:デフォルトの名無しさん
06/10/07 14:42:09
C++で
「変数aとbの符号が同じ場合」という条件を判断する関数があれば教えてください。
自分はif ( ( a < 0 ) == ( a < 0 ) ) と書いてるのですが、あまりに非効率な気がするので...


140:デフォルトの名無しさん
06/10/07 14:49:07
a*b > 0

141:139
06/10/07 14:53:15
>>139
スミマセン
変数a,bは有効数字15ケタなんです。書き忘れました。
それでも掛け算は避けた方がいいかな〜と思ってます。

142:デフォルトの名無しさん
06/10/07 15:22:13
>>141
有効数字15桁ってどんな型?
まぁ、何をもって効率とするかが未定義なのでそもそも答えようがないけど。

・コーディングの効率なら、テンプレート関数でそういう関数を一個作っておけばいい。
・実行効率なら、型ごとに大抵は符号ビットを持っているだろうからそれを見ればいい。

143:141
06/10/07 15:37:59
>>142
double型です。
符号ビットの見方を教えてください

144:デフォルトの名無しさん
06/10/07 15:41:46
IEEE754
変数(のbit)同士でxorでも取ったあと、
符号bitのみ見ればいいんじゃないかね。

145:141
06/10/07 16:00:07
1bitが符号判定に割り当てられてるのは勉強しましたが、
どうやって1bitを見ればいいのかさっぱりわかりません。
コードを書いてもらえませんか...

146:デフォルトの名無しさん
06/10/07 16:12:58
&

147:デフォルトの名無しさん
06/10/07 16:46:54
Wikipedia項目リンク

148:デフォルトの名無しさん
06/10/07 17:05:08
( a < 0 ) == ( b < 0 )
これが画像処理の1ピクセルごとに繰り返されるのなら
気になるかもしれんが、そうでもないならこれで十分。

double使ってるんだからそんなにシビアなものを組んでるとも
思えんし。シビアなところならdouble使うのをやめる工夫をして、
整数タイプでxorしたらいい。

もしどうしてもって言うなら>>146だけど、エンディアンには気を
つけてね。

149:デフォルトの名無しさん
06/10/07 17:12:14
つーか、パフォーマンスを期待しているならそんなところよりも他にやることが山ほどありそうだが。

150:141
06/10/07 17:20:38
>>146, 147, 148, 149
2000回ほどのループなので、計算負荷が高すぎて困っているというわけではないのですが
Cの先輩方はどのように書くのか知的好奇心から質問しました。
&も使えるように練習してみます。ありがとうございました。

151:デフォルトの名無しさん
06/10/07 17:27:28
ひとつだけアドバイスしておくが
おまえが小手先でごちゃごちゃやろうとしている方法よりも
単純な>>139のままのコードの方がが、最適化されて速くなっている可能性も十分ある。

とりあえず、何か小技を使おうとする前に
必ずアセンブラ出力を見て不満があるかどうかを判断すべき。

もちろん、それ以前に、そこまで速度を求める必要があるのか
あるいは他の部分で工夫すべき点がないのか、ということをよーーく考えるべきだが。

152:デフォルトの名無しさん
06/10/07 18:14:19
PXOR

153:デフォルトの名無しさん
06/10/08 12:42:50
( a < 0 ) == ( b < 0 )
何に使うのか知らないけど、これじゃ、ちゃんと動かない可能性ある罠。
a<0が、1返して、b<0が2返したら、!=になるし。
また、aかbのどちらかがゼロだったらどうする?(プラス扱いするならいいけど)

おいらなら、signって関数(符号に応じて-1,0,1を返す)を作って、
sign(a)==sign(b)って書く。
おそらく関数の中でif文使うから、実行効率は最悪だけど、
実行効率より、バグ鳥する時のコードの読みやすさ考えないと。

あと、どうしても効率最優先でも、何に使うのかが分からないと、最適な判別式は決められない。


154:デフォルトの名無しさん
06/10/08 12:47:33
pugya-

155:デフォルトの名無しさん
06/10/08 13:15:16
>>153
a < 0 が0か1であることは保証されている。

156:デフォルトの名無しさん
06/10/08 13:30:28
>>153
Cの比較演算の仕様を勉強しなおしてからお越しください。

157:デフォルトの名無しさん
06/10/08 14:36:37
0 か 1 になるのは C.質問者は C++ で聞いている.まあそれでも
The operands shall have arithmetic, enumeration or pointer type. The operators < (less than), > (greater
than), <= (less than or equal to), and >= (greater than or equal to) all yield false or true. The type of
the result is bool.
であって,bool 同士の == が正常に動くことも保証されてるから >>153 はアホ.

158:デフォルトの名無しさん
06/10/08 23:56:38
#include <string>
using std;;string;

struct A {
string a;
};

struct B {
string b;
B &operator=(const string &s){
b = s;
}
};

int main(void){
A a;
A aa = a; // xxx
B b;
B bb = b;
return 0;
}

---

質問なのですが、main()のxxxのところってまずいですよね?

159:デフォルトの名無しさん
06/10/08 23:59:42
別に。

160:デフォルトの名無しさん
06/10/09 00:00:15
間違えた。
B &operator=(const B &b0){
b = b0.b;
}

161:デフォルトの名無しさん
06/10/09 00:02:14
>>159
stringのメンバにポインタがないことは保障されているのですか?

162:デフォルトの名無しさん
06/10/09 00:09:21
>>161
stringはコピーコンストラクト可能かつ代入可能。
ポインタは含まれているが、コピー時は生ポインタを明け渡すわけじゃなくって
ポインタが指し示す内容をコピーする様に作られてる。
よって何の問題も無い。

163:デフォルトの名無しさん
06/10/09 00:15:33
A のデフォ代入演算子がmemcpy() だとまずいと思ったのですが。
つまり、デフォの実装が
A A::operator=(const A &a0){
memcpy(this, &a0, sizeof(A));

}

164:デフォルトの名無しさん
06/10/09 00:17:34
送信失敗、すみません。
デフォの実装が
A A::operator=(const A &a0){
memcpy(this, &a0, sizeof(A));
return *this;
}

これだと、メモリ二重開放にならないかと心配したわけです。

165:デフォルトの名無しさん
06/10/09 00:21:22
C++のクラス(=構造体)の代入処理は、各メンバの代入処理を行なう形になる。
たまたまPODメンバがまとまっていれば、memcpy()相当の実装をするかもしれない。

166:デフォルトの名無しさん
06/10/09 00:21:48
なるよ。
つーかそんな馬鹿な実装はしちゃいかん。
C++におけるmemcpyは純粋に生のバイナリデータ転送用で、メンバのコピー用じゃない。

余談だけど、thisがポインタなのはthis登場時にC++がまだ参照をサポートしてなかったからで、
thisがポインタであることを副作用的に使うコード(memcpyの引数にする、this[2]とか書く、エトセトラ)は
総じて何か勘違いしている傾向。
忌避したくらいで丁度いいぞ。

167:デフォルトの名無しさん
06/10/09 00:22:32
>>159,>>162 は間違い。自前で代入演算子をちゃんと定義してやらないと
>>163-164 で心配している通り memcpy な実装になってメモリリークする。

168:デフォルトの名無しさん
06/10/09 00:27:03
>memcpy な実装になってメモリリークする。

服脱いで正座してbasic_stringのコード読んで来い。
そんなになってたまるか。アホらしい。

169:デフォルトの名無しさん
06/10/09 00:29:57
>>168
コンパイラが
A A::operator=(const A &a0){
a = a0.a;
}
と解釈してくれるものなのでしょうか?

170:デフォルトの名無しさん
06/10/09 00:36:15
>>169
>165

171:デフォルトの名無しさん
06/10/09 00:37:51
158の場合では代入演算子ではなく、コピーコンストラクタが使われる。まあ話は変わらないが。

operator =が定義されていないときのデフォルトの実装は、
各メンバと基底クラスに代入演算子を使用したのと同じ動作をするということになっている。
また、コピーコンストラクタにも同じような規定が存在する。

162の言うとおりstd::stringが適切なコピーコンストラクタやoperator =を持っているため、
158/164の心配は杞憂だということになる。

172:デフォルトの名無しさん
06/10/09 00:38:56
ああ、ごめんみんなもう書いていたね。

173:デフォルトの名無しさん
06/10/09 00:41:26
>>168
それ全然問題の本質じゃないから。

174:デフォルトの名無しさん
06/10/09 00:43:06
>>171
>158の場合では代入演算子ではなく、コピーコンストラクタが使われる。
例が悪くてすみません、全くもってその通りでした。

>>165
これがFAでしたか。

皆様ありがとうございました。

175:153
06/10/09 00:44:02
>>155-157 そうだったのか。申し訳ない。


176:デフォルトの名無しさん
06/10/09 01:56:06
質問させてください。
ちょっと説明が下手でわかりにくいかもしれませんが、
ある関数の中で、引数の配列の長さを知ることはできるでしょうか?

例えば配列の平均を求める関数averageを作りたいとき
main関数内でa[100]とかb[80]とかを定義して、average関数に引き渡すとします。
(average(a)みたいな感じで)
このとき平均を求めるには当然、配列の要素の数が必要になるわけですが、
これをaverage関数内で求めることはできるのか?という質問です。

今は配列とともに要素の数もaverage関数に渡しているのですが、他に良い方法があったらご教授ください。

177:デフォルトの名無しさん
06/10/09 02:01:26
>>176
C++なら関数テンプレートにすればできんことはないよ。
多分↓こんな感じにすればおk
template<int array_size>
int average(const int array[array_size])
{
...
}

178:デフォルトの名無しさん
06/10/09 02:15:52
template <int N>
int average(int (&array)[N])

179:デフォルトの名無しさん
06/10/09 02:16:34
で、後は要素の数は

sizeof(array) / sizeof(array[0])

180:デフォルトの名無しさん
06/10/09 02:17:14
Nでもいいかもしれん。

181:デフォルトの名無しさん
06/10/09 02:22:05
Cなら要素数を別の引数で渡すこと以上の方法はないし、それが最も一般的だと思う。

C++なら177-178のように直接要素数をテンプレート引数にして配列への参照を引数にするのもいいが、
Boost.Rangeを使えばついでにstd::vectorなんかも渡せるようになってお得かもしれない。
ただしコードが難解になりやすいきらいがある。
#include <iostream>
#include <numeric>
#include <boost/range.hpp>

template<typename RandomAccessReadableRange>
typename boost::range_value<RandomAccessReadableRange>::type
average(RandomAccessReadableRange& r)
{
    typedef typename boost::range_value<RandomAccessReadableRange>::type value_type;
    return std::accumulate(boost::begin(r), boost::end(r), value_type()) / boost::size(r);
}

int main()
{
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::cout << average(arr) << std::endl;
}

182:176
06/10/09 12:05:08
なるほど…Cでは引数として渡すしかないんですね。
実はC++はまだ勉強してないんですが、これを機に勉強してみようと思います。
みなさんご丁寧にありがとうございました!

183:デフォルトの名無しさん
06/10/10 17:29:20
>>182
Cなら配列と要素数を構造体にまとめる方法もある。
配列の要素数を知りたいという問題の解決には全くなっていないが、多少管理が楽になる?

184:デフォルトの名無しさん
06/10/11 03:17:22
>>151がいいこといった。みんあ、よく聞いておけよ!

185:デフォルトの名無しさん
06/10/11 22:40:17
連想配列みたいなことをしたいのですが質問です。
以下コードです。
#include <stdio.h>
#include <string>
#include <vector>
int main(){
    std::vector<std::string> data;//連想配列を想定
    enum key_type {name,street,tel} _key;
    //name=val_name&street=val_street&tel=val_tel
    //この文字列を分割して、一番目のkeyとvalueを取り出す
    std::string key="name";
    std::string value="val_name";
    //連想配列と仮定して代入したいのですが、
    //'_STL::string' から 'key_type' へのキャストはできないというエラーがでます
    data[(key_type)key]=val_name;
    printf("%s",data[(type)key].c_str());
    return 0;
}
文字列を分割して取り出した、key値を列挙型の値にできれば
うまく連想配列に代入できるんですが、上のようなコードで
動くようにできないでしょうか。
よろしくお願いします。

186:デフォルトの名無しさん
06/10/11 22:47:07
訂正お願いします。
×data[(key_type)key]=val_name;
○data[(key_type)key]=value;

もうちょっとはっきり違う名前にすればよかったですが、
_keyは列挙型で、keyはstd::string型です。
よろしくお願いします。

187:デフォルトの名無しさん
06/10/11 22:55:28
>>185
key_typeのname, street, telなどといった列挙子は、
コンパイル時定数で、基本的に実行時に参照する方法はない。
C++は、どちらかというと何でも静的(コンパイル時)に解決するのが特徴。

どうしても実行時に文字列から列挙子を取り出したければ、
std::map<std::string, key_type>を使えば何とかなるだろうが、
だったら、初めからそのdataをstd::map<std::string, std::string>にすればいいだろということになるわけで。

188:デフォルトの名無しさん
06/10/11 22:57:01
std::map<std::string, std::string>

189:デフォルトの名無しさん
06/10/11 23:07:25
>>187
>>188
std::map検索してみました。
連想配列みたいなことができそうですね。
ありがとうございました。

190:デフォルトの名無しさん
06/10/11 23:11:07
まあvectorでも大きめに取っておいて、push_heap()などのアルゴリズムを
使って、中にはstd::pair<std::string, std::string>を入れておけばそこそこの
速度は出るが。

191:デフォルトの名無しさん
06/10/11 23:34:12
>>189
みたいな事じゃなくてそのまんま。

192:デフォルトの名無しさん
06/10/11 23:35:36
うわっごめん
std::search_heap()ってalgorithmにはないのね。
素直にstd::sort掛けてからstd::binary_search()使うしかないか。

193:デフォルトの名無しさん
06/10/11 23:40:22
Loki::AssocVectorという手もある。

194:デフォルトの名無しさん
06/10/12 00:11:20
>>193
それ良さそうだね。今std::mapと、std::pairをぶち込んだstd::vectorを
作って比較したら、std::mapの方がstd::vectorのstd::lowerbound()を
使ったバージョンより2倍速かった。自分の環境でですが。

195:デフォルトの名無しさん
06/10/12 07:01:35

for(double t=0;t<100;t+=0.1)
{
     /////
}
このようなforループで、変数tを増加させているのですが、
途中でtの値を出力すると、
10.000000000018849
のように、小さな誤差が蓄積しています。
割り算とかはではなく、単純な足し算のみしかしていないのですが、
このような誤差はどこから来るのでしょうか?



196:デフォルトの名無しさん
06/10/12 07:15:11
0.1 を有限桁数の二進数で厳密に表現することができないから。

それにしても誤差が大きいな。こっちだと 10 に対応するのは 9.9999999999999805。
理論的には 0.1 を有限桁数の二進数で表したときの誤差が 1e-16 くらいで、
これを 10/0.1 = 100 回くらい足すから 1e-14 くらいの誤差になるはずだけど。
こっちの結果はそれに適合してるんだけどなあ。

197:デフォルトの名無しさん
06/10/12 13:15:49
なにか誤差を蓄積しない方法はないでしょうか?
for(double t=0;t<1000;t+=1) 
{ 
     ///// 
} 
とかなら、誤差が蓄積しないのでしょうか?

198:デフォルトの名無しさん
06/10/12 15:13:38
>>197
基本的に浮動小数は誤差が入ると思え。
ループ回数が重要ならループ変数は必ず整数にするのが原則。

ただし、 >>197 の例だと(おそらく)誤差は全く出ない。
詳しくは浮動小数の表現(IEEE754方式)を調べるべし。

199:デフォルトの名無しさん
06/10/15 17:42:36
windowsのマルチスレッド、排他制御についてなのですが、
こちらでも良かったでしょうか。

スレッドA,B,Cがあるとします。
このA,B,CをCriticalSectionクリティカルセッションを使うと
他のスレッドが処理していたらお互いに待つことになると思います。
そうじゃなくって、
Aが処理しているときはB,Cはストップ
Bが処理しているときは他のスレッドは待たない
Cが処理しているときは他のスレッドは待たない
ということがしたいです。

クリティカルセッション使うと、B,Cが処理しているときも
他のスレッドが待つことになってしまいます。
Aの排他制御する区間に入るまでに、B,Cは区切りのいいところまで処理して(ループの最後など)
待機をさせるというイメージです。
Aのスレッドだけコードのイメージです。
void thread_A(void){
//いろんな処理
//B,Cを区切りのいいところで、待機させる命令
EnterCriticalSection(§ion);
//排他制御
LeaveCriticalSection(§ion);
//いろんな処理
}

説明がくどくてすみません。
そもそもクリティカルセッションの話じゃないんでしょうか。
よろしくお願いします。

200:デフォルトの名無しさん
06/10/15 18:03:24
1.マルチスレッドプログラミング相談室に行く
2.Win32API質問箱に行く
3.最高にド低脳な発言してください in ム板に行く

201:デフォルトの名無しさん
06/10/15 18:24:04
クリティカルセクションだし

202:デフォルトの名無しさん
06/10/15 18:25:50
セマフォでも使えば?

203:デフォルトの名無しさん
06/10/15 22:09:46
>>200
スレッドご紹介ありがとうございます。
前に専門スレいったことあるのですが、初心者スレ行けって
いわれたこがあったりしたので難しいです。(汗
移動しようと思いましたが回答いただけたので、
今回はすみませんがよろしくお願いします。

204:デフォルトの名無しさん
06/10/15 22:10:38
>>201,202
クリティカルセッションじゃダメですか。
セマフォじゃないのですが考えてみました。
グローバル変数flagを使います。
flagが1の時、スレッドAは実行、他B,Cは待機(Sleep)
flagが0の時、スレッドB,Cは実行、Aは実行しない(待機もしない)

void thread_A(void){
while(1){
//はじめにflagを立てる
flag=1;
//いろんな処理
//Aの処理が終わるので寝てたB,Cを起こすためflag=0
flag=0;
}
}

void thread_B(void){
while(1){
//はじめにflagをチェックして、値が1ならSleep
while(flag==1){Sleep(1000);}
//いろんな処理
}
}
//thread_Cも同様の内容です

これで実現できそうです。
セマフォについてですが、今回の処理に当てはめて考えるのが難しいのですが、
スレッドA,B,Cそれぞれ、どのような処理が必要かヒントいただけないでしょうか。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

4746日前に更新/249 KB
担当:undef