スレを勃てるまでもな ..
[2ch|▼Menu]
533:デフォルトの名無しさん
07/07/11 21:13:36
>>531
「scanf系」ってなんじゃらほい?

534:デフォルトの名無しさん
07/07/11 21:16:03
よくわからんが、sscanf()とかfscanf()とかじゃないの

535:デフォルトの名無しさん
07/07/11 21:21:18
一般的に、scanf()系のその他の関数の方は使い途あるんだけどご本尊が使いようが無くて困る。

536:デフォルトの名無しさん
07/07/11 21:48:03
>>535
fscanf()が使えるのならscanf()も使えるでしょ
scanf()は単にstdinに対するfscanf()なのだから

537:デフォルトの名無しさん
07/07/11 21:53:28
>>536
まぁ確かに、リダイレクトすれば使って使えなくも無いけどキー入力用としては使えないよね。

538:デフォルトの名無しさん
07/07/11 22:01:43
>>537
そんなことはないよ。
URLリンク(kansai2channeler.hp.infoseek.co.jp)
これは以前宿題スレに貼り付けた四則演算が出来るだけのオモチャ電卓だが、
数値を入力する時にscanf()を用いている。getchar()で数値であることを
確認してからungetc()し、改めてscanf()で読んでいるから基本的には安全だ。
scanf()を用いないとすれば実数の入力はずっと面倒になるよ。

539:デフォルトの名無しさん
07/07/11 22:06:04
それならfgets()+sscanf()で充分な気が。と思ったが……
あーそうか、入力を放置したまま、部分ごとに解析できるから使いようが無いわけでもないか。

540:デフォルトの名無しさん
07/07/11 22:08:09
そこまでするんだったら、fgets+sscanfのほうがすっきりすると思う。

そもそも俺はfscanfも使わないだろ派。
scanf系はsscanfと(使ったことないけど)vsscanfだけあればいい
と思っているということも影響しているだろうけど。

541:デフォルトの名無しさん
07/07/11 22:19:39
>>540
fgets()だと行長に恣意的な制限が生じるでしょ。
>>538のやり方だとgetchar()とscanf()しか使っていないから
そういう制限は無いよ。幾ら長い式でも扱える。
倍精度浮動小数点数を使っている以上、実数のサイズに制限はあるけどね。

他にいくつか例を挙げよう。↓はワードカウンタ
#include <stdio.h>
int main() {
    int cnt = 0;
    while (scanf("%*s") != EOF)
        ++cnt;
    printf("%d\n", cnt);
    return 0;
}

542:デフォルトの名無しさん
07/07/12 10:07:18
別に生じないけど、getchar()使ってscanf系を使わない選択肢もあるべ

543:デフォルトの名無しさん
07/07/12 14:03:08
>>542
scanf()使わずにgetchar()だけで数値を読み込む処理作ろうとしたら
少なくとも数行のコードは必要になる。別にやるのは自由だが、
scanf()のが楽で簡潔ではあるよ。

544:デフォルトの名無しさん
07/07/12 15:22:33
>>543
C標準ライブラリ関数しか使わず、なおかつ、自前の関数もダメ
なんていう縛りがあれば、そうかもしれん。

自前の関数が使える or 豊富なライブラリを活用してよい
となれば、使いにくいscanfを騙し騙し使わなくてもいいだろう。

545:デフォルトの名無しさん
07/07/12 16:54:15
>>544
別にクセが分かっていれば全然使いにくくないが。
ま、初心者に薦める気にはならんけどな。

546:デフォルトの名無しさん
07/07/12 17:10:08
組み込みじゃあ、余分な機能のついた肥大な関数は避けたいところではある
ってそもそも入ってないけど、デバッグ用にprintfだけは作ったなあ・・・

547:デフォルトの名無しさん
07/07/12 17:13:16
>>546
scanf()は確かにでかいな。
printf()も、作るとしてもフル機能はいらないでしょう。

548:デフォルトの名無しさん
07/07/12 18:03:08
どっかで見たprintfやscanfの実装では、使わない機能を細かく取り外せるようになってた。


549:デフォルトの名無しさん
07/07/12 22:28:32
sscanf()の%*[^\n]なんかは便利だからついつい使いたくなる。

550:デフォルトの名無しさん
07/07/12 22:36:03
>>549
そうそう、使い方を知ってればscanf()は非常に便利

551:デフォルトの名無しさん
07/07/14 03:24:26
割り込みシグナルについて教えてください

#include<stdio.h>
#include<signal.h>
#include<setjmp.h>
jmp_buf jmpBuf;
void s(){longjmp(jmpBuf, -1);}
int main(){
char buff[20];
signal(SIGALRM,s);
alarm(5);
   if(0==setjmp(jmpBuf)) {
      printf("A");
      fflush(stdout);
      gets(buff);
      alarm(0);
   }
   else {
      printf("B");
   }
}

これをコンパイルするとこのようなエラーが出てしまいます

'SIGALRM' : 定義されていない識別子です。
'alarm': 識別子が見つかりませんでした
'alarm': 識別子が見つかりませんでした

定義されて無いみたいなんですが・・・
どうやったらSIGALRMとalarm()を使えるようになるんでしょうか?

552:デフォルトの名無しさん
07/07/14 04:07:09
POSIXな環境に移行すりゃいいんじゃないかね。

553:デフォルトの名無しさん
07/07/14 08:43:07
>>551
#include <unistd.h>

554:デフォルトの名無しさん
07/07/15 03:03:07
>>552
ありがとうございます
でも出てきたサイトが英語だぁ・・・頑張ってみます

>>553
検索してくうちにそのヘッダを使ってるコードも見つけたんですが
borlandにはそのヘッダは無いみたいです

555:デフォルトの名無しさん
07/07/15 03:05:49
unistd = UNIX standard

556:デフォルトの名無しさん
07/07/15 11:00:46
ぶっちゃけ、>>551には自分がUNIX向けのプログラムを書いているという自覚がないのだろう。
一番簡単な選択肢は、Linuxを使うこと。

Windows上でPOSIX環境を提供する代物もあるが、
そういうのを使いこなす余裕はなさそうだからな。


557:デフォルトの名無しさん
07/07/15 11:20:27
>>551
Windowsではシステムコールにシグナルで割り込んで
中断させるという手法は使えない。
ANSI Cをサポートするコンパイラならsignal()関数は使えるはずだが、
仕様は非常に限定的だし、Unixのシグナルと同じものだとは思わないほうがよい。

Windowsで時間がかかる可能性のあるI/Oを中断したい場合は、
非同期I/O、スレッド、イベント、といったものを使う。

558:デフォルトの名無しさん
07/07/15 22:41:08
ずっと独学で勉強してたせいかdouble型をずっとドウブル型って読んでた
先週初めてダブル型だって知ったよ(|||´・ω・`)

559:デフォルトの名無しさん
07/07/15 22:46:37
>>558
俺はドウブレって読んでた。

560:デフォルトの名無しさん
07/07/15 22:51:07
charはキャラと読む人も居るが、
URLリンク(www.research.att.com)
によると、チャーが正しいようだね

561:デフォルトの名無しさん
07/07/16 00:11:15
この例だとネストは少ないけど、実際は5段6段のネストがあると考えてもらって

テンプレート使ったプログラミングで
typename Foo< typename Hoge<Hage>::type >::type foo;
とかやるのが面倒なんで
#define DECLARE(T,name) \
typename Foo< typename Hoge<T>::type >::type name
みたいなマクロ使うのってあり?


562:デフォルトの名無しさん
07/07/16 00:35:18
勝手にしてください

563:デフォルトの名無しさん
07/07/16 00:50:59
typedefすら面倒なのかよ

564:デフォルトの名無しさん
07/07/16 00:56:32
関数オブジェクトならメンバ宣言内でのtypedefが使えるんだけど
普通の汎用関数ならTがテンプレートパラメータの時typedef使えないんで
そういうときの為に考えたんですけど
そういう場合でもtypedefを使って簡潔にする方法あるんですかね?

565:デフォルトの名無しさん
07/07/16 02:04:58
ないならそれ用のメタ関数を作ればいい。
これを使いたい関数の直前にでも書いておけばよし。
template<typename T>
struct Shortcut
{
typedef typename Foo<typename Hoge<T>::type>::type foo;
};
こうすればShortcut<Hage>::typeと言う具合に1段に減る。

ついでに言うと俺様ライブラリ内だったら、
Boostみたいに名前空間detailにでも放り込めばいいかもしれない。
(ほかにろくな使い道がないなら)

566:デフォルトの名無しさん
07/07/17 10:39:33
クラスの中にクラスを定義できるけど、
関数の中に関数を定義するにはどうすればいいの。

その関数の中でしか使わない関数なので、
クラスの中のスコープに入れてしまいたい。

567:デフォルトの名無しさん
07/07/17 10:40:23
もとい

×クラスの中のスコープに入れてしまいたい。
○関数の中のスコープに入れてしまいたい。

568:デフォルトの名無しさん
07/07/17 10:42:20
>>567
関数内関数はできないので、精精同じソース内に入れるくらいが関の山。
呼ばれる関数をstaticにしておけば、事実上外部からは見えなくなるからね。

569:デフォルトの名無しさん
07/07/17 11:06:24
>>568
ありがとう。

呼ばれる関数を、呼ぶ関数の名前のnamaspaceに入れることにしました。


570:デフォルトの名無しさん
07/07/17 22:04:32
生スペースか

571:デフォルトの名無しさん
07/07/18 02:33:18
関数の中に構造体を定義してその中に関数を定義する。

572:566
07/07/18 03:15:23
>>571
目から鱗です。

まさにそれを、STLまわりで無自覚のうちにやってました。反省します。

573:デフォルトの名無しさん
07/07/18 22:54:54
>>524
結局ごまかしてる

574:デフォルトの名無しさん
07/07/22 19:56:30
newされた量が別の所で管理されていると言うことは、
void *p = (void*)new Hoge_t[hugahuga];
delete[]p;
でもちゃんとsizet(Hoge_t) * hugahugaバイトの領域が開放されるんですか?

575:デフォルトの名無しさん
07/07/22 20:06:59
うん

576:デフォルトの名無しさん
07/07/22 20:10:20
>>574
解放はされるけど、そのコードでは、Hoge_tがデストラクタを持っていた場合、
デストラクタが呼ばれないのがまずいという別問題も忘れないでね。

577:デフォルトの名無しさん
07/07/24 17:28:14
今までVC6をつかっていたのですが環境をVS2005 C++に変えました。
メモリアクセス違反を不正なポインタにアクセスして出した場合、いままでは

catch(...)

で例外を捕捉できていたのですが2005にしたらできなくなってしまいました
原因もしくは解決方法をご存じの方がいましたらお願いいたします。

処理としては不正なポインタからローカルの変数に代入しているだけです。
よろしくおねがいします

578:デフォルトの名無しさん
07/07/24 17:38:12
ディスプレイの任意のピクセルの色情報を取得したいんですけど
どんなことをすれば出来るんでしょうか
普通に入ってるwindows.hとかでも出来ますか?

画面丸々ビットマップに変換して〜
とかなら自分でも出来そうなんですけど、全然スマートじゃない気がするので

579:デフォルトの名無しさん
07/07/24 17:52:04
>>578
ディスプレイ=デスクトップとして、
デスクトップのDCを得る。 HDC hdc = GetDC(NULL);
HDCの任意の場所のピクセル情報を得る COLORREF rgb = GetPixel(hdc, x, y);

こんなんでどうか

580:デフォルトの名無しさん
07/07/24 17:59:54
>>579
おお、そんな便利な命令があったんですか
2,3時間ネットで調べて見てもダメだったんですが綺麗に解決しました。
ありがとうございます

581:デフォルトの名無しさん
07/07/24 19:23:04
>>577
コンパイラオプション/EHa使え

582:デフォルトの名無しさん
07/07/24 19:28:20
最近C初めたんですが
#include <string.h>
を入れるとコンパイルしても結果が得られないのですがなぜですか???
超初心な質問だと思いますが・・・
どなたか助言をお願いします

583:デフォルトの名無しさん
07/07/24 19:30:53
嗚呼、ぬるぽ

584:デフォルトの名無しさん
07/07/24 19:41:53
私も最近C初めたんですが
#include <string.h>
を入れるとコンパイルしても結果が得られますのですがなぜですか???
>>582は超初心な質問だと思いますが・・・
どなたか助言をお願いします

585:デフォルトの名無しさん
07/07/24 19:43:57
私も最近C初めたんですが
#include <string.h>
を入れるとコンパイルしても結果が得られないのですがなぜですか???
>>584も超初心な質問だと思いますが・・・
どなたか助言をお願いします

586:デフォルトの名無しさん
07/07/24 19:46:46
>>584
>>582が低脳だから


587:デフォルトの名無しさん
07/07/24 19:52:00
>>582
その「結果が得られない」というソースを張りたまえ。

588:デフォルトの名無しさん
07/07/24 19:56:25
ソースってなんでしょう???ウスターソースならウチにありますが・・・

589:582
07/07/24 19:58:19
なんだかよくわかりませんがもう一度コンパイルしたら
でてきました
どうもすいません

590:デフォルトの名無しさん
07/07/24 20:03:37
                           ____     
                         /_ノ  ヽ、_\    
   プギャアアアアアアアアアアアアアア     o゚((●)) ((●))゚o    
                      /::::::⌒(__人__)⌒::::: \ 
               (⌒)     |     |r┬-|     |  
           ,┌、-、!.~〈     |     | |  |     |   
            | | | |  __ヽ、   |     | |  |     |  
           レレ'、ノ‐´   ̄〉. \      `ー'     /   
            `ー---‐一' ̄                  

591:デフォルトの名無しさん
07/07/24 20:49:48
>>581

ありがとうございます。無事動作いたしました。
SEHというものを初めて知りましたが、便利ですね

592:デフォルトの名無しさん
07/07/27 08:19:12
連想配列を実現する関数のサンプルってどこかにありませんか?

593:デフォルトの名無しさん
07/07/27 08:22:35
>>592
std::map?

594:592
07/07/27 08:33:40
サンプルを自力で発見しました。
どうもお騒がせしました


595:デフォルトの名無しさん
07/07/27 08:34:27
>>593
C言語で連想配列を実現したかったんです。
舌足らずですみません。
で、こんなHPを見つけて事故解決しました。
URLリンク(ew-and-f.hp.infoseek.co.jp)

596:デフォルトの名無しさん
07/07/27 09:34:22
Cだとハッシュという言葉のが一般的だからなあ。

597:デフォルトの名無しさん
07/07/27 18:54:56
template <class T>
class foo
{
public:
T _data;
foo(const T& v){ _data = v; }
};
というクラスがあったとして

foo<int> foo1(4);
foo<double> foo2(2.5);

foo2 = foo1;
foo<double>foo3 = foo<int>(2);

という代入を実現したいのですがこれは可能でしょうか
テンプレートコンストラクタを作ろうとしたら当然無理でした

598:デフォルトの名無しさん
07/07/27 19:09:34
>>595
STLにあるのに、自分で作るの?

・・・たぶん学校の宿題なんだろうな・・・

599:デフォルトの名無しさん
07/07/27 19:14:03
事故解決したら危ない

600:デフォルトの名無しさん
07/07/27 19:36:30
>>598
C++じゃなくてCだそうだよ。

601:デフォルトの名無しさん
07/07/27 19:43:10
>>597
テンプレートのコンストラクタと代入演算子を用意するだけでは?
template<typename U>
foo(const foo<U>&);
template<typename U>
foo& operator =(const foo<U>&);

これとは関係ないが、コンストラクタでは代入ではなく初期化リスト使え。

602:デフォルトの名無しさん
07/07/27 20:09:03
>>597
あなたが実際にやろうとしていることは、

foo<double> foo_d = foo<int>(2) ;
ではなく、
double d = foo<int>(2) ;
だと思う。

とりあえず
operator T&() { return _data }
を用意すれば、コンパイラが持っているintからdoubleの変換が使われる。

603:デフォルトの名無しさん
07/07/27 20:11:17
ちなみに、
> テンプレートコンストラクタを作ろうとしたら当然無理でした
というのは、
template<class U>
foo(const foo<U>& u) { _data = u }
だったりしないか?

そりゃダメだ。
やはり、
double d = foo<int>(2)
をやろうとしている。

template<class U>
foo(const foo<U>& u) { _data = u._data }
でなければ。

604:デフォルトの名無しさん
07/07/28 00:50:15
>>601-603
回答ありがとうございます
解決できました

template <class U>
foo(const foo<U>& u)


605:デフォルトの名無しさん
07/07/28 00:54:31
途中送信してしまいました・・・

template <class U>
foo(const foo<U>& u)
{ _data = u._data; }

この形式でいけました
ちなみにクラステンプレートだとfoo<T>とfoo<U>とは
別のクラスになるようなので
_dataのゲッタを使って解決できました

ありがとうございました

606:デフォルトの名無しさん
07/07/28 02:44:33
>>605

>>597の通りなら、_dataはpublicだからgetterはいらないよ。
publicではない場合は・・・面倒くさいからgetterを使うか。

同じテンプレートのクラスどうしならいいけど、違っていたらダメだから、
副作用もあるけど、operator T&を用意したほうが便利だと思う。

607:デフォルトの名無しさん
07/07/28 07:50:35
ゲッタを用意するのとoperator T&を用意するのとでは、本質的には何も変わらないだろ。

608:デフォルトの名無しさん
07/07/28 07:55:49
getterを誰が呼ぶのか、getterを呼ぶコードを誰が書くのか、という点で違うと思う。


609:デフォルトの名無しさん
07/07/28 08:16:00
もうfriendにすればいいよ。
template<typename U>
friend class foo<U>;
auto_ptrとかshared_ptrもこんなことやってのかと思ったら、
getterあるから不要だった。

610:デフォルトの名無しさん
07/07/28 08:30:31
>>609
friendにしたところで、肝心のメンバ変数の名前が一致していないとダメだ。

ちなみにVC7.1では、そういうfriend宣言はできない・・・orz

611:デフォルトの名無しさん
07/07/28 14:11:55
Cで、ボタンを押すとファイルから1行ずつ読み取って描写するプログラムを作っています。
テキストの描写にはDrawTextを使っているのですが、うまくいかないので質問したいと思います。

例えば、長い文字列を描写した後、同じ場所に短い文字列を描写すると前の文字列の後ろの方が残ってしまうのです。
1回最小化してまた開くと、うまく表示されるのですが何が悪いのかよく分かりません。

こんな説明ですが、分かる方が居ましたらお願いします。



612:デフォルトの名無しさん
07/07/28 14:14:14
知らないけど、リフレッシュ

613:デフォルトの名無しさん
07/07/28 14:14:58
文字を書く前に、一旦後ろを真っ新に塗りつぶせばいい。

614:デフォルトの名無しさん
07/07/28 14:37:44
文字列に空白でもたくさんつけとけ。

615:デフォルトの名無しさん
07/07/28 14:39:42
あるいは自動で最小化→最大化とか

616:611
07/07/28 15:05:28
私の技術力の低さのせいで614さんと615さんの方法しか試せませんでしたが、なんとか解決できました。
提案して下さったみなさん、本当にありがとうございました!

617:デフォルトの名無しさん
07/07/28 18:18:44
えー
ちゃんと描画ハンドラを適切に実装しる

618:611
07/07/28 18:53:04
今までにコンソールアプリケーションを作る事はあったのですが、
windowsアプリケーションは初めてで、色々苦戦してます。

メッセージ等初歩的な事は理解できたのですが、分からないことが多いです。
描画ハンドラの適切な実装?を私は
InvalidateRectを呼び出して再描画させる事だと考えたのですが、うまくいかないようです。
見当違いなことを言っていたらすみません。


619:デフォルトの名無しさん
07/07/28 19:16:06
>>618
WindowsのGUIの基礎を勉強したほうがいいと思う。

断片的にやり方を調べてやっていると、
根本的なところを間違ったりするよ。

自前でチマチマやるくらいなら、
VCLとか使ったほうがいいかも。

620:デフォルトの名無しさん
07/07/28 19:20:28
>>618
見当違いなことを言い過ぎで恥ずかしいです。

621:611
07/07/28 19:30:50
今回質問をして、明らかに知識も技術も不足していることが分かりました。
もう一度基礎から勉強し直そうと思います。

指摘や指導して下さったみなさん、ありがとう。
次にこのスレに来るときは、もう少しレベルアップしてきます。
では。

622:デフォルトの名無しさん
07/07/28 21:19:59
>>621
し直す

というあたりが不安だ。
一度も勉強していないものを、どうやって し直す のかと。


623:デフォルトの名無しさん
07/07/28 21:50:39
お前さ、どんだけ上から目線なんだよ

624:デフォルトの名無しさん
07/07/28 22:07:01
お前さ、どんだけ下から目線なんだよ

625:デフォルトの名無しさん
07/07/28 22:13:23
#お前さ、どんだけ下から目線なんだよ

626:名無しさん@そうだ選挙に行こう
07/07/29 08:54:31
     ∧_∧
     ( ・ω・ ) <消しゴムが落ちたので拾ってください
      (====)
   ______( ⌒) )
 /\   ̄`J ̄ ̄ ̄\
  ̄ ̄ ̄ ̄| | ̄ ̄ ̄ ̄
         | |
       / \       □

627:名無しさん@そうだ選挙に行こう
07/07/29 09:47:56
##お前さ、どんだけ下から目線なんだよ

628:名無しさん@そうだ選挙に行こう
07/07/29 11:03:13
#ここに初心者に対するコメントをどうぞ

629:デフォルトの名無しさん
07/07/31 18:51:32
#include<stdio.h>
#include<window.h>
main(){
int i;
while(1){
printf("入力して下さい: ");
scanf("%d",&i);
Sleep(5000);//長い処理の代わり
printf("値:%d",i);
}
}
このようなプログラムの場合、sleepしてる間(長い処理)に
キーボードから標準入力を入れると次にscanfに回ってきたとき
sleepしてる間に打った数字が勝手に入ってしまうのですが、
scanfの後、キーボードからの標準入力をいったん停止することはできませんか?




630:デフォルトの名無しさん
07/07/31 18:55:36
読み捨てるしかありません。

631:デフォルトの名無しさん
07/07/31 19:36:16
すいません、読み捨てるって意味がよくわからないです。

632:デフォルトの名無しさん
07/07/31 19:41:46
すいません、これって超基本という感じもするのですが、、、
以下のソースをg++でコンパイルすると
最初の行とその次の行の結果が異なるのですが、
これは何故なのですか?

#include <iostream>
using namespace std;
int main()
{
cout << 1 + 0.05 * (0.25) / 90 << endl;
cout << 1 + 0.05 * (90/360) / 90 << endl;
return 0;
}





633:デフォルトの名無しさん
07/07/31 19:47:00
90 / 360 = 0 だから。
90.0 / 360 とかすれば同じになる。

634:デフォルトの名無しさん
07/07/31 19:53:59
int 型同士の演算はその結果も int 型
90/360 は 0.25 という結果が int 型に切り詰められてゼロになる

635:デフォルトの名無しさん
07/07/31 19:55:36
>>633
そうか!
ありがとうございます。
結構大きなソースを追いかけていたのですが、最後にようやく
上記の行が原因とわかりまして、でもなぜうまく動かないのか
わからなかったのですが、そうですよね、90も360もintになりますよね。
ありがとうございました。



636:デフォルトの名無しさん
07/07/31 19:56:20
>>634
ありがとうございました。

637:デフォルトの名無しさん
07/07/31 20:49:08
>>631
「scanf() 呼ぶ直前に、残った文字を全部読んでしまえ」ってことだろうが
それは無理。
 URLリンク(www.kouno.jp)

ついでに
 URLリンク(www.kouno.jp)

638:デフォルトの名無しさん
07/07/31 20:52:14
>>637
fflush使わずともscanf("%*[^\n]%*c");みたいにscanfだけでも何とかなる。

639:デフォルトの名無しさん
07/07/31 21:04:46
いや、
>読まれていな い文字は、O/Sレベルのバッファにもため込まれている可能性がある。
だから「それは無理。」なのだろう。
しかしこれはちょっと・・・元の>629はそんなシビアな話ではないと思う。

640:デフォルトの名無しさん
07/07/31 21:08:38
裏で字を食い続けるだけのスレッド動かせばいいんじゃね?

すげー無駄だけど

641:デフォルトの名無しさん
07/07/31 21:48:35
Aというファイルfopenで開き、fgetcでCString型の箱に格納。
Replaceで一部を置き換え、Bというファイルに書き出すというのは可能でしょうか。

642:デフォルトの名無しさん
07/07/31 21:57:17
>>641
そりゃぁできるでしょ。

643:デフォルトの名無しさん
07/07/31 22:00:23
CStringはTCHAR用なので、_gettc()ではなく(f)getc()を使うのなら
CStringAを使え

644:デフォルトの名無しさん
07/08/01 01:58:23
class Counter;
{
/* 略 */
int data[];
int total;
};
int main()
{
Counter counter(N); /* counter[i] = 0 */

クラスCounterは内部に配列を持っていて0で初期化されているとします
counter[i]の値をインクリメントしたとき自動的に
totalもインクリメントされるようにしたいのですが

Counter::inc(index)
{ data[index]++;total++; }
ではなく
Counter::operator ++ (int)で実現する方法はないでしょうか

class val



645:デフォルトの名無しさん
07/08/01 02:01:13
途中送信してしまいました・・・

class value
{
static int total;
int val;
/* 略 */
int operator ++();
};

というクラスを作れば実現できますが
これだとCounter c1,c2;としたときtotalが共有されてしまいます

646:デフォルトの名無しさん
07/08/01 02:02:48
最終的に
counter[i]++;
としたとき
counter.totalも++されるようにしたいのです

なにかいい方法があればご教授ください

647:デフォルトの名無しさん
07/08/01 03:22:28
テンプレートクラスをtypedefする方法ってありますか?

648:デフォルトの名無しさん
07/08/01 05:12:34
>>644-646
ちょっとサンプル作ってみたよ、参考にしてみてくだしあ><
URLリンク(2ch-library.com)

方針としてはDataの配列(サンプルではvectorだけど^^;)
を持つCounterから直接インクリメント演算子を呼び出すんでなくて、
間に別のクラスをかませるってやり方
サンプルではそのクラスが合計インクリメント数も保持しちゃうんだけど、
チョッと弄ればCounterクラスが合計を保持するようにも出来る
この場合はfriend指定使ってるけどboost::functionみたいなデリゲート使えば
必要な関数だけ渡してfriend指定なしにもできる

>>647
ちょっとエスパー回答だけど、例えば
foo< bar< hoge< hage<piyo> > > > …(*)
ってのをtypedefみたいにショートカットするなら
template <type T> struct foo2 {
  typedef typename foo< bar< hoge< hage<T> > > > type;
};
とでもして、foo2<piyo>::typeってすれば(*)と同じような意味になりtypedefみたいな使い方ができる
こういうのをメタ関数と呼ぶらしい

649:646
07/08/01 11:39:12
>>648

非常に参考になりました
Binderを内部クラスにする方向で進めてみます

どうもありがとうございました

650:デフォルトの名無しさん
07/08/01 11:39:21
すいません。質問です。
DXライブラリ(DirectXライブラリ)とVC++を使ってゲーム製作の学習中です。
スクリプトエンジンを作るため、テキストファイルを開いてstring型の配列に格納してファイルをクローズする、
という処理が上手く行きません。
ファイルを行と行ごとの内容でアクセス出来るようにしたいので、string型の二次元配列で最初は書いていたのですが、
上手く行きませんでした。
一昨日にvectorの存在を知って、早速試しているのですが、やはり上手く行きません。

vector<string> Scenario;
Scenario.resize(500);
char* ScenarioFile = "Log.txt";
char Buf[256];
int FileHandle = FileRead_open( ScenarioFile );
int i=0;
while(FileRead_eof(FileHandle) == 0){
FileRead_gets(Buf,256,FileHandle);
Scenario.push_back(Buf);
}
FileRead_close(FileHandle);

このように記述しているのですが、Scenario[0]から全て ・ としか表示されず、
どうやら漢字コードの半分だけを表示しているようだと予測しました。
完全に失敗です。
whileの中にブレークポイントいれてみると、Bufの内容はちゃんと1行まるまる入っています。
格納が上手くいっていないようです。

どうすればテキストファイル丸々をstring型配列に落とすことが出来るのでしょうか?
どんどん足していって、改行コード毎に1行と判別させるメソッドを組むしかないのでしょうか?

アホですいません。宜しくお願いします。


651:デフォルトの名無しさん
07/08/01 11:43:54
ファイルのエンコードの問題かな?
プログラムとファイルの双方のエンコードを確認してみては?

652:デフォルトの名無しさん
07/08/01 11:59:53
>>650
>Scenario.resize(500);
もしかして: Scenario.reserve(500);

653:650
07/08/01 12:12:39
すいません、誤解を招きそうな書き方をしてしまいました。
『Buf自体にはちゃんと1行入っていて、Scenario.puch_back(Buf)が出来ていないようです』という意味でした。
本当にすいません。

>>651さん
念のため、他のメソッドで使っているイベントデータを読み込んでみましたがダメでした。
ちなみに、そのメソッドはchar型で格納して1行ずつ表示したり、それをstrtok()に掛けるなど
の処理を行っています。こちらは動いています。

>>652さん
リザーブしてもダメでした……


おそらく、文法がちゃんと理解出来ていないせいだろうと思いますが、
例によって何が間違っているのか分からないという状態に陥っています(´・ω・`)
vector<string> a; a.reserve(500);と
string a[500];は、ひょっとすると配列としてはほぼ同じですか?


654:デフォルトの名無しさん
07/08/01 12:20:59
次の3つが、後にa[0]からa[499]までの要素が使えるという点で似たようなもの。
1. std::vector<std::string> a; a.resize(500);
2. std::vector<std::string> a(500);
3. std::string a[500];

push_backは現在の最終要素の後ろに追加するメンバ関数。
a.size()が500のときにpush_back(Buf)したら、
そのBufの内容はa[500]で参照することになる。


655:650
07/08/01 12:52:30
>>654さん
push_backの意味、理解出来ました!ありがとうございます。
ひょっとして、std::string Text[512];として、
Text[0]に1行目、Text[1]に二行目、という風に合計512行を
格納出来るんじゃないかという考え方は、そもそも間違っていますか?
char型のa[10]とstring型のa[10]は、どちらも10バイト分の要素を持つ配列、
という意味になってしまうのでしょうか?
てっきり、string型は1行を動的に格納出来る優れものだと思ってました……
行単位で保持しようという考え方が、そもそも無茶なのでしょうか。
ここまできて、ようやく、『ひょっとするとファイルオープンしたままのほうが
面倒が少なくていいんでね?』とか思い始めてきました……(´・ω・`)

ちなみに、リザーブせずにpush_backで継ぎ足していったら、要素を出力した瞬間に
『ハンドルされてない例外エラー』で停止しました……切ないです(´・ω・`)


656:デフォルトの名無しさん
07/08/01 13:03:43
>>655
stringは一行(というか可変長な文字列ひとつ)を扱うクラス。
stringの配列で、行ごとに扱うというのは別に間違ってないよ。

あと、reserveは使うとpush_backが早くなるかもしれないけど、
使わなくてもいいという代物。
reserveしないとエラーが出るというのは、別のとこに原因があるはず

657:650
07/08/01 13:19:33
>>656さん
ありがとうございます。
原因は、Scenario[0]を出力しようとしているところにありました。
そして、string型の要素が入ってるくせに、.c_str()が使えないようです。

諦めて、string Scenario[500]; にしてコードを適切に変えたら、
やりたかったこと(1行単位で格納)そのものは出来ました。
やはり、stringの考え方そのものは正しかったようです。
それはそれで嬉しいのですが、今度はvectorの使い方を理解出来ていないと
いうことが発覚して、非常に悔しいです。

改めて、また全く別の質問をさせてください。

vector<string> a(10);
と宣言しても、a. でリストに出てくるメソッドはvectorのもので、stringの .c_str()等が
使えないのはどうしてでしょうか?
また、a[0].にいたっては、リストすら表示されません。
a[0]にはstring型のデータが格納されていると考えるのは間違っていますか?

これが、string b[10];なら、b[0].c_str();が使えることは確認済みです。
てっきり、同じように扱える物だと思っていましたが、どうやら違うようです。

宜しくお願いします(涙)


658:デフォルトの名無しさん
07/08/01 13:38:24
いや、そんな感じだぞ。
vector<string> a(10);とすると、aは10個要素を持った状態になる。
a[0].でstringのメンバが出てこないのは、単にエディタが阿呆なだけだから諦めろ。

659:デフォルトの名無しさん
07/08/01 13:39:13
VC2005だとちゃんと表示されるぜ


660:デフォルトの名無しさん
07/08/01 14:06:47
VC2003だと所々怪しい。
ポインタと配列が組み合わさるとインテリセンスが働かないことがある。
VC6を使ってたときはもっとひどかった。

661:650
07/08/01 14:32:24
皆さん、本当にありがとうございます。
泥沼に入り込んだような絶望的状況の中、優しさに泣けてきます。
コーディング専用に使ってる古いノーパソの方はVC++2002でしたので、
メインPCに入っているVC++2005ExpressEditionのほうにソースコード移して、プロジェクト作り直してみました。
(2002と2005で互換性無いみたいで、余計なトラブル防ぐためです)

すると……出ます! vector<string> a; a.resize(500); で、 a[0]にちゃんとstringのメソッドが出ます!
やったぜ!

喜び勇んでデバッグビルド。

……LNK4217やらLNK2019やらLNK1120やら出まくりやがります……(´;ω;`)
どうやら、vectorを使うと出るっぽ……(コメントアウトすると出ない

とりあえずエラーコードを全部ググってみたのですが、正直、専門用語連打で今ひとつ原因が理解できていません。
もうちょっと格闘してみます。


662:デフォルトの名無しさん
07/08/01 14:35:53
#include <vector.h> とかやってるってオチはないだろうね

663:650
07/08/01 14:52:27
>>662さん
ちゃんと

#include "string"
#include "vector"

にしてます。
昼飯抜きでやってたので、いまちょっとラーメン食ってます。
今日は有給取ってまとまった時間があるんで頑張ります(^^)


664:デフォルトの名無しさん
07/08/01 15:00:07
ランタイムライブラリの設定がおかしくなっているような気がする。

665:デフォルトの名無しさん
07/08/01 15:44:18
C++のソースを他の言語に移植しているのですが、ちょっとこまったことがありました。

class Hoge
{
 Hoge();
 virtual ~Hoge();
}

といった、クラスがある場合、

ソース中、

 Hoge hoge;

として、動的生成ではなく、静的に宣言?した場合、
デストラクタ(~Hoge);は、スコープから外れると自動で呼ばれるものなのでしょうか?

自動で、呼ばれない言語に移植しているいじっているもので(Delphi)




666:デフォルトの名無しさん
07/08/01 15:45:22
>>665
試してみればわかると思うけど、YES

667:665
07/08/01 15:45:28
途中で、送信してしまいました。


自動で、静的な構造体の場合、デストラクタが呼ばれない言語に移植しているもので(Delphi)、
その場合は、手動でデストラクタを呼び出す必要があるということになりますよね。


668:650
07/08/01 15:46:10
いろいろ確認しましたが、やはり、vectorを使用するとリンカエラーが出るようです。
vector<int> i;
と宣言して未使用のままでも、エラーが出ます。
stringは問題なく使えます。
他のSTLについては、そもそも使い方をまだ学習していないのでインクルードすらしてません。
ノートの方でエラー出ないってのが不思議です……
どなたか、原因が分かる方いらっしゃいますか?

>>664
設定を戻したいのですが、どのようにしたら元に戻せるんでしょうか?
再配布用のVC++2005 SP1ランタイムは見付けましたが、多分、再配布用じゃないですよね(´・ω・`)

669:665
07/08/01 15:49:27
>>666
サンクスです。

こちらにも書いてありました。
C++編(言語解説) 第7章 コンストラクタとデストラクタ
URLリンク(www.geocities.jp)

newしない場合は、スコープ外れるときに自動で呼ばれるのですね。
newした場合は、deleteするときに呼ばれる、と・・・。


670:デフォルトの名無しさん
07/08/01 15:54:29
>>668
プロジェクトの設定でC/C++→コード生成で
ランタイムライブラリの設定をDLLからスタティックリンクライブラリにしてみたらどう?

671:650/668
07/08/01 16:10:06
>>670さん
ありがとうございます。
プロパティ→C/C++→コード生成→ランタイムライブラリ を見てみたところ、

マルチスレッド
マルチスレッド デバッグ
マルチスレッド DLL
マルチスレッド デバッグ DLL

の4つ選択肢があって、デフォルトではマルチスレッドデバッグDLL(Debugモードです。リリースだとマルチスレッドDLLになります)に
なっていましたので、スタティックリンクライブラリの意味が正直よく分かっていないのですが、
『マルチスレッドデバッグ』にしてみました。
やはりリンカエラーでます。

「LNK4098: defaultlib 'LIBCMT' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。」
これだけ、新しい(?)エラーが出た……のかな???
他はLNK2019,LNK2001,LNK1120(fatal)です。

ざーーーーーっとMSDNやぐぐってヒットした質問掲示板を片っ端から見て行ってるのですが、自分と該当するものは
今のところ見付かっていません。

#include "vector"
vector<int> i;
の二行だけでエラー出るってやっぱおかしいですよね?


672:デフォルトの名無しさん
07/08/01 16:11:49
ライブラリ見てる先が違うのでは?

673:デフォルトの名無しさん
07/08/01 16:23:59
ライブラリの設定をマルチスレッドデバッグDLLに戻して
#include <vector>
でも駄目かね?

674:デフォルトの名無しさん
07/08/01 16:26:36
いやまずは、

char str[100][300];
string str [100];

で読む込むかやって見ろよ




675:デフォルトの名無しさん
07/08/01 16:28:33
char* ScenarioFile = "Log.txt";
char buf[500][256];
int FileHandle = FileRead_open( ScenarioFile );
int i=0;


while(FileRead_eof(FileHandle) == 0){
FileRead_gets(Buf[i], 256, FileHandle);
i++;
}
FileRead_close(FileHandle);

676:650/668
07/08/01 16:30:57
>>672
それだと、stringもダメになりませんかね?
stringは普通に使えてます。

>>673
戻してみて、#include <vector>にしましたがダメでした。
時間掛かるけど、再インストールしてみたほうがいいっすかね?


677:デフォルトの名無しさん
07/08/01 16:32:07
つか、なぜC/C++ライブラリや、windowsAPIを使わないのか教えろ

678:デフォルトの名無しさん
07/08/01 16:37:36
普通のやり方だと動くのか???

#include <fstream>
using namespace std;

fstream fp;
string str;
fp.open("Log.txt", ios::in );

do{
getline(fp, str);
cout<< str<<endl;
}while(!fp.eof());

679:650/668
07/08/01 16:38:12
>>674さん
>>675さん
ありがとうございます。
vectorを使わないで何とかする方法は皆さんのおかげで無事なんとかなりましたm(_ _)m
今は、VC++2005でvectorそのものが使えないという状態で困っております……

>>677
すいません。WinAPIはまだ学習していませんので、使い方が分かりません。
やっとポインターと参照送りを覚えて、STLの存在を知って2週間ばかりのど素人です……
C/C++ライブラリとは、STLのことですよね?
今はSTLのstringを覚えて、vectorに差し掛かったばかりです。


680:650/668
07/08/01 16:41:14
すいません、先ほど>>677にさん付けるの忘れてました。他意はありませんm(_ _)m

>>678
普通のやり方でももちろん動きます。特にDXライブラリが悪さしているとは思えません。
ぜんぜん関係ない、ごく普通のC++の部分でエラー吐いてますので……

vectorさえ使わなければ、エラーも出ず普通に動きます。
さし当たって今やろうとしていることには必要のないものですが、C++の学習が主な目的でもありますので、
使ったらエラーという状態だけは何とかしておきたいなと思っています……


681:デフォルトの名無しさん
07/08/01 16:43:02
2003もアンインスコして再インスコだな
標準でさえこのざまなんだからこの先どんな不具合が起こるかわからないって状況は普通に怖いぞ

682:デフォルトの名無しさん
07/08/01 16:46:06
↓のプログラムをDOSで実行すると、何故か画面がフリーズして
「問題が発生したため、終了します」という画面が出て実行できないのですが
何故なんでしょうか?文法上の誤りも自分で見る限りは特に無いと思うのですが・・・
混じれ酢お願いします。
改行が多すぎて一度に書き込めない様なので分割して書き込ませて頂きます

#include<stdio.h>
#include<string.h>




683:デフォルトの名無しさん
07/08/01 16:47:05
main(int argc, char* argv[])
{


char filename[256];
char key[128];
if(argc>2){strcpy(filename,argv[1]);
strcpy(key,argv[2]);}
else if(argc){
strcpy(filename,argv[1]);
printf("暗号キーを入力してください>");
scanf("%s",key);

} else {
printf("ファイル名を入力してください>");
scanf("%s",filename);
printf("暗号キーを入力してください>");
scanf("%s",key);

}

printf("ファイル名:%s\n",filename);
printf("暗号キー:%s\n",key);

return 0;}


684:デフォルトの名無しさん
07/08/01 16:47:23
vectorは殆ど使い道ないよ
初めから必要な領域を動的確保すればよい

685:デフォルトの名無しさん
07/08/01 16:49:38
>>682
実行するときに引数入れろよ

686:デフォルトの名無しさん
07/08/01 16:52:43
>>683
コマンドライン引数ないとargv[1]参照してエラー起きる

argcは少なくとも1だよ
argv[0]にはプログラム名が入ってるから

687:デフォルトの名無しさん
07/08/01 16:52:45
else if(argc>=2){ にしとけ

688:デフォルトの名無しさん
07/08/01 16:53:07
>>685
実行するときに引数を入れても同じ画面が出てエラーになります・・・

689:デフォルトの名無しさん
07/08/01 16:53:43
途中だったw

if文書きかえて

if(argc > 2) うんたら
else if(argc == 2)うんたら
else うんたら
にしる


690:デフォルトの名無しさん
07/08/01 16:54:24
>>684
それだと解放する手間がかかるでしょ。
例外に強くするためにもvectorに解放を任せるのは有用。

もしかして釣られた?

691:デフォルトの名無しさん
07/08/01 16:59:46
>>689
ありがとうございます!!やってみたらできました
こんなくだらないミスで質問をしてすみません・・・
皆さんありがとうございました

692:デフォルトの名無しさん
07/08/01 17:00:47
一つ一つ内容を増やしていって確保する領域が不明であるケースなんて
ほとんどないよ
それに、個数が多ければ一度に確保しておいた方が速いし、
個数が少なければ多めに確保しておけばエラーは出ない

多くても少なくてもvectorは使えない

693:650/668
07/08/01 17:01:09
>>684さん
なんとなく『最初から上手く設計すればいらないような……?』とは思っていたのですが……_| ̄|○
はっきり言って下さってありがとうございます。
踏ん切りが付きましたので、ひとまずvectorの学習は中断することにします。


あ、でもVC2005の再インストールだけは念のためしておこうと思います(^^;

皆さん、本当にありがとうございました!


694:デフォルトの名無しさん
07/08/01 17:02:41
例えば、100万個データ追加するのに
毎回vectorのメンバ関数で追加するより
a[i]=5とやった方が速いし見やすい

695:デフォルトの名無しさん
07/08/01 17:06:06
               .|   |  | |   |    |  | |   |   |   || | |
               .|   |  | レ  |    |  | |   |  J   || | |
    ∩___∩    |   |  |     J    |  | |  し     || | |
    | ノ\   ,_ ヽ  .|   レ |      |  レ|       || J |
   /  ●゛  ● |   .J      し         |     |       ||   J
   | ∪  ( _●_) ミ             .|    し         J|
  彡、   |∪|   |              .J                レ
 /     ∩ノ ⊃  ヽ
 (  \ / _ノ |  |
  \  "  /  | |
   \ / ̄ ̄ ̄ /
      ̄ ̄ ̄ ̄

696:デフォルトの名無しさん
07/08/01 17:08:56
>>692
reserve

>>694
resize

697:デフォルトの名無しさん
07/08/01 17:10:55
vectorの方が楽
それだけで使用価値があるとは思わないか


698:デフォルトの名無しさん
07/08/01 17:13:17
vectorの方が不便
だって[]での代入が装備されていない

699:デフォルトの名無しさん
07/08/01 17:13:43
>>698
はい?kwsk

700:デフォルトの名無しさん
07/08/01 17:16:27
template <typename T>とtempalte <class T>ってどう使い分けすれば良いんでしょうか?

701:>>699
07/08/01 17:18:39
#include <vector>
#include <iostream>
using namespace std;

main(){
vector<int> v;

v.push_back(1); cout << v[0]<<endl;
v[0]=2; cout << v[0]<<endl;

/* 逆にしたこっちはエラーになる

v[0]=2; cout << v[0]<<endl;
v.push_back(1); cout << v[0]<<endl;


*/

}

702:デフォルトの名無しさん
07/08/01 17:20:46
reserve();で確保すればエラー出ないんだな
しらんかった すまん

703:デフォルトの名無しさん
07/08/01 17:21:27
>>701
そんな使い方ありえないから実装されてない
使いたければオーバライドすればいいじゃん


704:デフォルトの名無しさん
07/08/01 17:26:07
>>700
好みの問題。
ただし、下みたいなテンプレートテンプレートではclassしか使えなかったはず。
template<template<typename T> class T>
こんな機能使わないけど。

705:デフォルトの名無しさん
07/08/01 17:28:39
>>702
reserveで押さえただけ領域は使ってはいけないところ。
vectorで使える要素は0番目からsize()の1つ手前の要素まで。
size()の値を変えるにはresize()。

特に要素がクラスオブジェクトだとコンストラクタが呼ばれていなかったり、
デストラクタが呼ばれた後だったりするのでわかりやすいけど、
組込型でも駄目なことに変わりはない。



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

4308日前に更新/282 KB
担当:undef