[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 12/31 01:11 / Filesize : 246 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【初心者歓迎】C/C++室 Ver.59【環境依存OK】



1 名前:デフォルトの名無しさん [2008/03/30(日) 01:50:26 ]
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.50【環境依存OK】
pc11.2ch.net/test/read.cgi/tech/1204124447/
【アップローダー】(質問が長い時はココ使うと便利)
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm



862 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 12:28:04 ]
サンクス

863 名前:ミミ [2008/04/20(日) 13:10:19 ]
Visual C++ でデバッグバージョンのバイナリを作るときって、
みなさんは名前を変えますか?どんな方法にしてますか?

[方法1]
Debug も Release も同じファイル名にして、ビルドすると上書きされるようにする。

[方法2]
Debug バージョンには _d のようなサフィックスを付ける。
some_d.exe hoge_d.lib など。

[方法3]
Debug と Release で出力フォルダを分ける。
bin/Debug/some.exe bin/Release/some.exe など。

864 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 13:23:48 ]
デフォルトは方法3だよな。
単独で動かす時はそれで十分やね。

他のアプリから利用する必要がある場合は方法2じゃないと都合が悪い。

方法1は論外っすね。

865 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 14:40:32 ]
>>858
そういうものがあるとしたら、そういうフリーのソフトが公開されている筈だよな。
そういう公開ソフトはないのだから、当然そういうDLLはない。
まぁ、>859にある「統合アーカイバ・プロジェクト」辺りを見てこいと。

866 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 15:20:46 ]
XacRettで解決したんですけど…

867 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 17:28:14 ]
最近ゲームのプログラムいじってたらprint系で浮動小数が出力できなくなってしまったんだが、
同じようになったことある人いる?いたら解決策とか教えて欲しいです。
症状としては、%fを含むprint系の関数(wsprintfとかvfprintf)を実行すると
「問題が発生したため〜」っていうおなじみのダイアログが出てきて落ちちゃうんです。

868 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 17:30:03 ]
言語再インストール

869 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 18:34:25 ]
ウィンドウを作成して、そこにビットマップを表示させたりするDLLを作ってるんだが、
外部からもらったバイナリBMPデータをどういじればいいのか分からん。。。

//---
PAINTSTRUCT psPaint;
HDC hWndDC;
HDC hMemDC;
HBITMAP hBitmap;
HGDIOBJ hGdiObj;

hWndDC = BeginPaint(g_hWnd, &psPaint);
hMemDC = CreateCompatibleDC(GetDC(g_hWnd));
hBitmap = CreateComptibleBitmap(hMemDC, 100, 100);


hGdiObj = SelectObject(hMemDC, hBitmap);

/* ここでバイナリをhBitmapに設定したい */

BitBlt(hWndDC, 0, 0, 100, 100, hMemDC, 0, 0, SRCCOPY);
//---

ビットマップバイナリをどうにかしてhBitmapに突っ込んでやれば良いのかと思ってるんだけど、
方法がわからん…
そもそも考え方が間違ってる?


870 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 18:45:57 ]
>>869
SetDIBits



871 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 18:59:48 ]
CreateDIBitmap

872 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 19:08:32 ]
>>867
再現ソースとエラーを張れと何度いったことか

873 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 19:46:11 ]
>>872
再現コードの作成はちょっと全体の量も多いし見当もつかないので難しいです・・・。
関係あるとしたらどんなことが考えられるでしょうか?ロケールとか?

874 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 20:00:57 ]
>>873
スタックを壊したとか関数テーブルを壊したとか
多分バッファオーバーフローか未初期化ポインタを使って
アクセスしてはいけないメモリを壊した可能性が高い

875 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 20:01:01 ]
だからエラーメッセージ張れつ〜うの。テンプレに書いてあるでしょ
呼び出し規約とかランタイムとかリンクされるライブラリとか
なんかプロジェクトの設定いじったでしょ。それを直せばいい

876 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 20:45:31 ]
>>863
デバッグ版はインストール先のフォルダ。
リリース版はインストーラ作成のフォルダ。

877 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 21:22:45 ]
>>874-875
レスありがとうございます。以前できていたところがいじってないのに
急になったので875さんの臭いかも知れないけど、気づいたらなってしまってました・・・
BCCでやっててエラーメッセージを取得できる部分が見当たりません・・・。
こういう時ってどうやってメッセージを受け取るんでしょう?すいませんアホで・・

878 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 21:58:31 ]
浮動小数とか言ってる時点でキミがアホなのはみんな分かってるよ

879 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 22:11:33 ]
これでまったく関係ない場所でゼロ除算で落ちてたとかだとウケるな

880 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 22:24:46 ]
あっwsprintfかw
printf系じゃないから%fとか無理
sprintfつかえ



881 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 22:29:26 ]
snprintfとかswprintfでもいいよ

882 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 01:09:03 ]
>>870
>>871
さんくす。
CreateDIBitmap使ってやってみたらいけた。

表示用のビットマップはCreateCompatibleBitmapで作って、
外部からもらったバイナリを描画するビットマップをCreateDIBitmapで作成

BitBltで転送して実装できたよ

ありがとう

883 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 20:49:40 ]
>>879確実にvsprintfで落ちてました。
>>880-881ダメでした。あきらめます。
親切にレスしてくださった皆様、ありがとうございました

884 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 21:15:55 ]
null = new int[10]
で確保した領域はどこに存在するの?
delete[]しなければ、この確保した領域はプログラムが終了してもずっとそこに存在したままになるの?

885 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 21:18:33 ]
>>884
ヒープ領域のどこか

終了したらちゃんと解放される
一部されないOSもなくはない


886 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 21:38:02 ]
コンパイル時にtype_infoみたいな感じで静的にクラス名の文字列を取得できる方法ってありますか?
テンプレートクラスで例外を投げる時に使いたいんですが・・・

887 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 21:52:34 ]
>>886
boostのこの辺のが役に立つかもしれない
ttp://www.kmonos.net/alang/boost/classes/enable_if.html

888 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 22:10:44 ]
boostって本当にすごいね・・・そんなのも判定できるとは
でも型名の取得は厳しいのかな・・・

889 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 01:38:20 ]
やっぱりboostでtypeofってのがあって、それで
型名は取得できるのだけど、staticな処理じゃないんだよね。
なのでその用途だとtypeid使うのとあまり変わりない。
ttp://www.kmonos.net/alang/boost/classes/typeof.html

890 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 03:19:09 ]
STLをはじめ、テンプレートをよく使いなさい。
型の完全名がカオスになって諦めがつくから。



891 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 04:20:31 ]
void CtimerDlg::OnBnClickedButton2()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
msgdlg aaae = new msgdlg();
aaae.Create(IDD_DIALOG1, this);
aaae.ShowWindow(SW_SHOW);

}

このボタンを押すとダイアログウィンドウが一瞬表示されたようにみえるのですが、表示されません。
SW_SHOWがいけないんでしょうか?

892 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 07:09:45 ]
それコンパイル通るの?

893 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 07:55:39 ]
コンパイルできないし、それが単なるtypoだったとしても資源の管理はどうなってるんでしょうね、と。

894 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 09:21:56 ]
コンパイルはできますがやはりaaae.ShowWindow(SW_SHOW);で消滅します

895 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 09:25:14 ]
あ、aaaeをポインタにしたら出来ました。

896 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 20:23:53 ]
単にスコープ抜けたから、msgdlgのインスタンスが死亡しただけだろう。

897 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 21:23:39 ]
vsprintfについてなんですけど、下記のva_end(..)っているのですか?

xx func(const char* format, ...) {
char buf[256];
va_list args;
va_start(args,format);
vsprintf(buf, format, args);
va_end(args); // <=== これ必要なんですか?
...
}

898 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 21:30:35 ]
規格で、同じネストレベルでva_start,va_endの組で使うことになっている。

899 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 21:32:48 ]
実装によるかも知れんがメモリとかがぶっ壊れるんじゃまいか

900 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 21:49:24 ]
すいませんちょっとお聞きしたいのですが、GCCで

if(ret = 1){
int dt = 1;
}

みたいにしたら、
「真偽値として使われる代入のまわりでは、丸括弧の使用をお勧めします」
と言われたので、

if((ret = 1)){
int dt = 1;
}

みたいにしたら、許してもらえました。

なぜ ((ret = 1)) の方がよいのでしょうか??




901 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 21:52:09 ]
>>900
ret==1って書いたらその警告消えてくれるよ。

902 名前:897 mailto:sage [2008/04/22(火) 21:54:54 ]
>>898-899 どうも、
ここのサンプルではva_end使ってないんです
msdn2.microsoft.com/ja-jp/library/28d5ce15(VS.80).aspx
そして、www.bohyoh.com/CandCPP/C/Library/vsprintf.html
ここに、「本関数は、va_endマクロを呼び出さない」 と記述があるんです

903 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 22:00:56 ]
>>900
==の間違いだったりしませんよね?大丈夫?っていう警告だからそういうもんだと思え
別に前の書き方でも問題ない

(())の方がよいというわけじゃない

904 名前:900 mailto:sage [2008/04/22(火) 22:05:44 ]
>>901 さん
>>903 さん
なるほど!ありがとうございます!


905 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 22:28:34 ]
>>902
VCに限っていえばva_endマクロは何もしないから呼ばなくても問題はない。
しかし、他の処理系で動くとは限らない。

906 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:00:01 ]
>>902
書かなくてもいい環境が有るとはいえ、プログラムとしては書かないと駄目。
運悪く駄目なサンプルに当たったね。

907 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:05:39 ]
>>896
なるほど!
msgdlg aaae = new msgdlg();
をグローバル領域に持って行っても起動しました。
ポインタの理解が深まりました。ありがとう!

908 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:07:36 ]
ちょっとぉぉぉぉぉ

909 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:13:26 ]
これが
「何か適当にいじったら動いた」
という奴か

910 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:14:27 ]
> グローバル領域
深まってない悪寒



911 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:15:55 ]
さすがにこれをコンボでくらったら元のソースを自分で書いていたとしてもデバッグしたくなくなるな
(だから、その変てこなのは後から馬鹿が弄ったんだってば ><)

912 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:18:30 ]
>msgdlg aaae = new msgdlg();
このコード、何度見ても謎が残りすぎ。

913 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:29:02 ]
>891の段階で既に釣りだったんじゃね?

914 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:30:42 ]
>>907
C++の入門書か入門サイトをもう一度見て回った方が良いと思うぞ。
煽りとかじゃなくて本当に。基礎は大事だから。

とりあえず、理解する必要のあるキーワードとしては、
   ポインタ、参照、自動変数、デストラクタ、delete、スコープ、スタック、ヒープ
あたりかな。

915 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 23:32:33 ]
釣りなら、それはそれでおk。

916 名前:デフォルトの名無しさん [2008/04/23(水) 00:24:05 ]
switchのcase文内で、auto変数を宣言しようとすると、{}をつかってブロックを
作らないとだめですか?

917 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 00:25:05 ]
だめです

918 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 00:30:02 ]
>>916
例えばこういうことならできる。
switch (value) {
int someVar;
case 0:
someVar = 0;
break;
case 1:
someVar = -1;
default:
someVar = value;
break;
}

919 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 00:35:00 ]
>>914
レベルアップした気分ですごく満足なのですが
もう一度新C++言語入門シニア編上下を読み直してみます・・・
が、ずばり一言でどこがおかしいですか?頭関係以外でおねがいします。

920 名前:デフォルトの名無しさん [2008/04/23(水) 00:35:09 ]
>>917-918
ありがとうです。
918はやり方自体知らんかったス。




921 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 01:01:17 ]
>>919
頭関係以外で一言にまとめるには、対象が「少数」の「具体的なディテール」である必要がある。
でも君の場合、「基本的な抽象概念」の理解が「幾つも」欠けているように見受けられるから、まとめようがない。
だから>>914も困った挙げ句
> ポインタ、参照、自動変数、デストラクタ、delete、スコープ、スタック、ヒープあたり
という言い方になってるんだよ(これでも親切に用語を絞って挙げてるほう)。

922 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 02:37:20 ]
>>919
msgdlg aaae; //○msgdlg型の変数
msgdlg aaae = new msgdlg(); //×msgdlg型の変数にmsgdlg*型の値を代入
msgdlg *aaae = new msgdlg(); //○msgdlg*型の変数にmsgdlg*型の値を代入
一言でいうと,どこがイコールよ?





923 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 07:18:54 ]
>>919

void CtimerDlg::OnBnClickedButton2()
{
  // new msgdlg() → msgdlgのインスタンスをヒープに確保。
  //
  // msgdlg aaae = ... → msgdlgのインスタンスをスタックに確保して、
  // msgdlg(msgdlg* ptr)に適合するコンストラクタで初期化。(※1)
  msgdlg aaae = new msgdlg();

  ...

  // 自動変数のaaaeがスコープから外れるのでデストラクタが呼ばれ、
  // aaaaが保持していたウィンドウなどが削除される。
  //
  // (※1)のポインタptrをdeleteしていなければメモリリーク。
}

が理解出来ていないように見える。

作りたいのがモーダルダイアログなら、
{
  msgdlg aaae;
  aaae.Create(IDD_DIALOG1, this);
  aaaa.DoModal();
}

関数を抜けてもmsgdlgを保持するなら、
グローバルでなくCtimerDlgのメンバにする。

924 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 07:20:43 ]
よく見たらeだった。
× aaaa
○ aaae

925 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 09:41:18 ]
ビットフィールドは、

unsigned char x : 50;

のように元の型を超えていても定義できますか?



926 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 09:43:54 ]
unsigned char配列を、38 、 6 、 4 のように分けたいのですが、ビットフィールドで出来ますか?
あと、38bitの部分は、=で比較できますか? 無理な場合、別の方法はないでしょうか

927 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 09:51:28 ]
このようにしたら、確保する領域は、40bit + 8bitになりますよね?
33 + 7 ではないですよね?

class A{
public:
bitset<33> a;
char b : 7;
};

928 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 10:06:17 ]
自己解決しました
これで長い列に変換出来ました


bitset<40> *p;
unsigned char s[5]={1,255,1,255,128};
p=(bitset<40>*)&s;
cout<< *p;

929 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 10:53:08 ]
そ れ は 偶 然 だ

930 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 11:16:25 ]
>>922>>923
ありがとうございます。すごくよくわかりました。
void CtimerDlg::OnBnClickedButton2()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
int a =0;
while(a < 100){
msgdlg *aaae = new msgdlg[100];
aaae[a]->Create(IDD_DIALOG1, this); // エラー
aaae[a]->ShowWindow(SW_SHOW);
aaae[a]->OnBnClickedOk();
delete aaae[a];
a++;
}
}
error C2819: クラス 'msgdlg' にはオーバーロードされたメンバ 'operator ->' がありません。

これは何がいけないんでしょうか?



931 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 11:32:26 ]
下記のコードを実行したときに test::aaa で内部的に確保されたメモリ(?)が解放されず、
メモリリークが起きてしまっているようで解決方法が見つからず困っています。
STLなどの場合、確保したメモリを明示的に解放する関数などがあるのでしょうか?
( aaa.clear() や aaa.~vector() などは試してみたのですが駄目でした)
それとも test::aaa 自体も new で確保して delete で解放したほうが良いのでしょうか?
環境はVC++2005です、よろしくお願いします。

class base {
public:
~base(){ destory(); }
virtual void destory(){};
};
class test : base {
public:
std::vector< int > aaa;
void destory(){ aaa.clear(); }
};

void main(){
void *p;
{
test *ptest;
ptest = new test;
ptest->aaa.resize(100);
p = (void*)ptest;
}
//ここではポインタ p の基本クラスが base ということ以外はわからない
delete (base*)p;
}

932 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 11:39:01 ]
デストラクタで仮想関数呼び出すとか馬鹿じゃねーの?

933 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 11:42:12 ]
古い形式のキャスト使ってるとか馬鹿じゃねーの?
スマートポインタ使ってないとか馬鹿じゃねーの?

いやいや、馬鹿じゃないって。
デストラクタの中から仮想関数呼び出すのはさすがにないけど。

934 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 11:44:25 ]
>>930
これはひどい

935 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 11:57:28 ]
… ~base() が呼び出されるときは
既に test::destory の実体はなくなっているからでしょうか?
馬鹿ですみません…
こういう場合、クラスtestで確保したメモリは
どう解放したら良いのでしょうか?


936 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 11:59:40 ]
しかも書いてありました。
スマートポインタで調べてみます。

937 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 12:31:15 ]
baseのデストラクタにvirtualをつけて上で
testに自分のdestoryを呼ぶデストラクタを書けば
baseのデストラクタの最初でtestのデストラクタが呼ばれて、testのdetoryが呼び出されるため
この場合はmain内部の変更無しでメモリリークがなくなるけど、それじゃ駄目なの?

938 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 13:22:22 ]
>>937
ありがとうございます、無事に解放されるようになりました。
いろいろと勉強不足でした。
仮想デストラクタにしないと派生クラスのデストラクタが呼び出されないのはもちろん
メンバ変数のデストラクタも呼び出されないということ(?)なんですね。


939 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 13:39:34 ]
>メンバ変数のデストラクタも呼び出されない
詳しくは覚えてないが、デストラクタが仮想関数(virtual)であれば、delete演算子が
渡されたポインタから仮想関数テーブルを辿って継承関係を把握できるとか
だったと思う(逆に言えば仮想関数でないと把握できない)。
ちなみに勘違いしてそうなので書いておくけど、デストラクタとは
~クラス名();←引数無し
のこと。destroyとか勝手に名前つけたらそれはただのメンバ関数だよ。
この場合正しくは virtual ~base();とかだ。

940 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 13:43:43 ]
あ、そういえば~base()はちゃんと書いてあるのかw



941 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 14:11:20 ]
なるほど…仮想関数テーブルですか、
virtual指定はなんだか漠然としていて理解しにくかったですが
なんとなくはどう動作するかが理解できました。
ありがとうございます。

942 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 14:16:49 ]
>>930
下のソースはコンパイル可能
行数減らしたから少し見辛いかも
>>914の言うようにポインタと参照について学んだ方がいい

struct CTest{ void test(){} };
void f(){
CTest a;
CTest* b = new CTest();
CTest* c = new CTest[1];
CTest d[1];
a.test(); (*&a).test(); (&a)->test(); (&a)[0].test();
(*b).test(); b->test(); b[0].test();
(*c).test(); c->test(); c[0].test();
(*d).test(); d->test(); d[0].test();
delete b;
delete[] c;
}

943 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 14:47:49 ]
>>942
感動しました。こんなにわかりやすいの初めてみました。がんばります!

944 名前:デフォルトの名無しさん [2008/04/23(水) 15:37:22 ]
物凄い初歩的な質問なんですが
上手い方法を教えてもらいたくて質問します。

ある文字列があって
1文字ずつ処理していくんですが、
何か文字に変化があった時だけ処理を行いたいのです。

char str[]="ああいうええお";//何か文字列
int len=strlen(str);
char current_c;

current_c=str[0];//内容を覚える
for(int i=0; i<len; i++){
if(current_c!=str[i]){//連続している文字が変われば
//処理
}
}

こんなのを思いついたんですが
これだと、1つ目の文字が当然処理されません。
current_c=str[0];//内容を覚える
これを
current_c=str[0]+1;//内容を覚える
として、必ず1回目は処理が行われるようにするのも考えたんですが
もっとちゃんとしたスマートな方法があると思うんですが・・・
こういう場合、どうやるのが一般的なのでしょうか?

945 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 15:46:25 ]
str[0]+1なんて代入しなくても、0で初期化しておけばいいんじゃないの?

946 名前:デフォルトの名無しさん [2008/04/23(水) 15:48:09 ]
>>944
charは1バイトだから平仮名みたいな多バイト文字はうまくゆかないよ。
分かっているならごめん。

947 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 16:11:33 ]
>>945
0に相当する文字が来た時に駄目でしょ。

948 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 16:12:08 ]
>>944

typedef char val_t;
val_t str[]="aabbbcccddee";

typedef val_t* iter_t;
for(iter_t begin=str,end=str+strlen(str),back,it=begin; it!=end; ++it){
  if(it==begin || *back!=*it){
    //処理
    back=it;
  }
}


(・∀・)

949 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 16:13:42 ]
>>947
それはひょっとしてギャグでいってるのか・・・・

950 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 16:19:37 ]
>>944
最初に1文字目と異なる値 str[0]+1 で初期化しとけば良いんじゃね?
ってのは結構頭の良い発想。凡百の徒には嫌われるけどね。

でもそういうときの current_c は普通 prev_c だな。



951 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 16:22:12 ]
>>950
そうか?ムダじゃね?

952 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 16:33:50 ]
一つ目の文字が変わるっていう意味が分からんw

953 名前:948 mailto:sage [2008/04/23(水) 16:41:36 ]
struct CTest{
  bool operator!=(const CTest& o){
    // ...
    return true;
  }
};
template<typename iter_t> void unique_each(iter_t begin, iter_t end){
  for(iter_t back,it=begin; it!=end; ++it){
    if(it==begin || *back!=*it){
      //処理
      back=it;
    }
  }
}
void f(){
  CTest v[10];
  // v[0] ...
  unique_each(v,v+sizeof(v)/sizeof(*v));
}

(∩゜д゜)アーアーきこえなーい

954 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 16:46:59 ]
>>951
今回は文字だから 0 にしときゃ良いけど、
一般に先頭要素または直前のと異なる要素を
判定していくには良い方法だよ。

955 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 16:58:36 ]
>>945の前提条件
nul終端文字列

>>947の前提条件
文字列

>>950の前提条件
コピーコンストラクタ
operator+
operator!=
を持っている型

>>953の前提条件
operator!=
を持っている型

956 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 17:04:34 ]
>>955
もう>>944とは別世界に行ってるなw

957 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 17:31:55 ]
PHPやperlでprint を使いながらデバッグするような方法をC++でもやりたいのですが、どうすればよいでしょうか??
そういうデバッグの仕方はC++では難しいのでしょうか。


958 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 17:32:34 ]
>>944 ちょっとトリッキー、でもうまいやり方
>>945 一番シンプル
>>946 一番重要なレスw
>>953 汎用化し杉ワロタw

959 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 17:44:15 ]
>>944
#include <algorithm>
#include <string>
#include <iostream>
#include <functional>

int main() {
  std::wstring src = L"ああいうええお";
  src.push_back(0);
  ::setlocale(LC_ALL, "ja_JP.UTF-8");
  for (std::wstring::iterator i = src.begin(); *i != 0; ++i) {
    i = std::adjacent_find(i, src.end(), std::not_equal_to<wchar_t>());
    std::wcout << i-src.begin() << *i << std::endl;;
  }
}

終端一つ加えて条件が逆のadjacent_find

>>957
エスパーするとコードを読ませて実行時に一時的な値を見るとかならデバッガ
gdbとVC付属のやつとか

960 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 17:44:31 ]
>>944は、charの取りうる最大値を指していた場合
+1すると、オーバーする。

>>945は、処理内容次第では、\0がいきなり来た場合にヤバい。
が、あのプログラムの場合strlenの値がループの実行回数だからOK

>953は、恐らく>>944が本当に必要だったものではない可能性が高いw




961 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 17:47:00 ]
>>959 さん
なるほどデバッガで変数に格納されてる値を見ることが出来るんですね。
ありがとうございましたm(_ _)m

962 名前:デフォルトの名無しさん mailto:sage [2008/04/23(水) 17:51:55 ]
>>>944は、charの取りうる最大値を指していた場合
>+1すると、オーバーする。

するってーと current_c=~str[0]; が適切?






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<246KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef