Home > Tips Archive

Tips Archive

C++トリビアルメモ(ポインタの参照)

平成20年ってほんと?ありえなくない?

VC++でポインタの参照を使ってみました。どういうことなのかよく分からないけど動いたから正しいに違いない。
コンパイラが神様です。
C言語の場合、引数で渡された変数に関数内で領域を割り当てる場合は普通(?)二重ポインタにする。私の場合。


void foo(char **bar) {
   *bar = (char *)malloc(sizeof(char)*10);
}

int main(int argc, char **argv) {
   char *bar;

   foo(&bar);

   return 0;
}

そもそもこれがあってるのかという話もありますが、


void foo(char *bar) {
   bar = (char *)malloc(sizeof(char)*10);
}

ってやるとコンパイラに怒られるんだもん。
C++だとこんな感じ?


class Hoge {
public:
   Hoge(){}
   ~Hoge(){}

   int a;
};

void hogeUser(Hoge **hoge) {
   *hoge = new Hoge();
}

int main(int argc, char **argv) {
   Hoge *hoge;

   hogeUser(&hoge);

   return 0;
}

しかしこれ、以下のように書けた。


void hogeUser(Hoge *(&hoge)) {
   hoge = new Hoge();
}

int main(int argc, char **argv) {
   Hoge *hoge;

   hogeUser(hoge);

   return 0;
}

でもひょっとしたら動いてないかもしれない。デバッグ中に奇妙に勝手に終了することがあった(アクセス違反)。
関係ないところだったけど、これが影響しているのかもしれない。

「あほやん」と言う人は教えてください。

以上

C++トリビアルメモ2(std::vectorのデバッグVC)

Love理論届いた。すげぇアレゲ。感想は後日書く。

VCでデバッグしてるとき、std::vectorの中身が見られなくて困った。


std::vector< double > a;
a.push_back(1.0);
a.push_back(2.0);

for (size_t i = 0; i < a.size(); i++) {
    printf("%f ", a[i]);
}

まあ、上のは適当ですが、デバッガでa[0]とかを見ようと思ってウオッチウィンドウに入れても「オーバーロードがありません」とか何とか出て見られない。
もっともこれは2003だけの話かもしれないけど。
以下のようにアクセスできます。
a._Myfirst[0]
a._Myfirst[1]
std::mapも同じように見られるけど、どのキーがどこに入ってるのか分からんから、よく分かりませんでした。
それだけ。

以上

タブ機能付きコマンドプロンプトConsoleを日本語でアレする

小ざかしい作業をいろいろやっているとコマンドプロンプトがいっぱいになってしまって、なんかジャマってことがときどきあります。
そういうときに使えばいいのがConsoleっつうタブ機能付きコマンドプロンプトみたいな奴です。
この辺からダウンロードできます。
で、便利なんですが、日本語が表示されると激しくバグるというか、文字列の表示位置がずれます。
で、どうしたらいいか、なわけですが、いろいろ設定いじっても無駄。
実はこれ、どうも裏でコマンドプロンプトそのものが動いているらしく、その結果をバッファリングしてるようなんです。
そういうわけで、コマンドプロンプトそのものの設定をいじればいい感じになります。

やり方は簡単、

1.コマンドプロンプトを起動(アクセサリとかから)
2.タイトルバーのとこ(青いところ)を右クリックして「既定値」を選択
3.フォントのタブを開き、「ラスタフォント」になっているところを「MSゴシック」に変更
4.OK

で、OK。
おもむろにConsoleを起動し、dirとかやって日本語を表示してもずれないことを確認して一件落着。

以上

文字コード変換

rubyやらphpの統合開発環境らしいAptana。デバッグできなさそうなので微妙。Javascriptに関してはなかなか良さそう。

UTF8からSJISへの変換は、PHPとかならさくっとできますが、Cではどうなのか。
Cではきついというか、自分で作らなきゃいけないような気がするけど、WinAPIを使えば、ちょっとましになる。
やり方としては、UTF8⇒UCS2⇒SJIS(MS932)。
つまり、


wchar_t *ucs2;
char *sjis;
int wlength;
int length;

wlength= MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
ucs2 = new wchar_t[wlength];     // たぶん、wlength+1とかいらない。ナル文字まで含んだ「文字数」が上で返る。
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, uc2, wlength);

length = WideCharToMultiByte(CP_ACP, 0, ucs2, -1, NULL, 0, NULL, NULL);
sjis = new char[length];
WideCharToMultiByte(CP_ACP, 0, ucs2, -1, sjis, length, NULL, NULL);

delete[] ucs2;
return sjis;

こまかいパラメータとかは、
マイクロソフトの、こことかここを見るといいと思うよ。

以上

jQueryトリビアルメモ2 (prototype.jsとかと共存、jQuery.jsの複数回読み込みについて)

昨日のエントリーがあまりにもひどいので追記。

1.複数回読み込み
jQuery.jsの複数回の読み込み自体は別に問題ないようですね。


<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.shadow.js"></script>
<script type="text/javascript" src="jquery.js"></script>

なんでそんなことがしたかったのかというと、ブログのエントリごとに読み込みたいから。

2.prototype.jsとかとの共存
共存できるんでしょうか?よくは知らない。
ただ、$()の衝突を避けたい場合、


 jQuery.noConflict();

を実行しておけば、


$("div").fadeTo("fast", 0.5);

とする代わりに、


jQuery("div").fadeTo("fast", 0.5);

と書けます。で、prototype.jsを読み込んでいる場合、$()はprototypeの仕様で使えます。

あるいは


 var j = jQuery.noConflict();

としておけば、


j("div").fadeTo("fast", 0.5);

でOKです。

以上

jQueryでFormのバリデーション

jQueryの便利そうなプラグイン。ValidationAide
フォームの入力値の妥当性を検査してくれます。

使い方:
1.フォームをかく


<form id="Test">
	<div id="ClientValidationSummary"></div>
	<input type="text" id="name" title="名前" class="textbox validator-required" /><br />
	<input type="text" id="mail" title="メール" class="textbox validator-required validator-email" />
	<input type="submit" value="Submit" />
</form>

入力値にエラーがあった場合、ClientValidationSummaryのところに要約(サマリ)が表示されます。
titleで指定された文字列が要約表示時などに項目名として使われます。
バリデートしたい部品のclassに上記のような指定をします。
上記の場合、「名前」のところは「テキストボックス」「入力必須」で、
「メール」のところは「テキストボックス」「入力必須」「メールアドレス」でバリデートしてます。
validtor-emailとしておけば、aaa@aaa.comのような有効なメールアドレスの形式かどうかを検査してくれます。
表示されるメッセージをデフォルトから変更したい場合は、titleに” – “区切りで書きます。マイナスの前後にスペースが要るので注意。
例えば「title=”名前 – 名前を入力してください”」とすると、項目が「名前」、メッセージが「名前を入力してください」になります。
マウスをオーバーラップさせたときにも表示されてしまうのが難点?

2.初期化


$(function() {
	$("#Test").validationAideEnable();
});

formのIDを指定して、validationAideEnable()を実行します。
各部品の横にメッセージを表示したい場合などは、パラメータをJSON形式で渡します。


$("#Test").validationAideEnable(null, {showInlineMessages:true, inlineShowSpeed:"fast"});

第一引数は独自ルールを定義する場合に使います。
その辺の詳しいところはダウンロードしたファイルのdemoのソースを見てください。

3.サンプル

以上

SQLのORDER BYに条件をつける

  • 2007-08-09 (木)
  • Tips

「VistaからXPにアップグレードする」などといわれているVistaですが、SP1が11月にでるっぽい?でたら使えるようになるっぽい?

というわけでORDER BYですが、よく使うのは「ORDER BY ASC」「ORDER BY DESC」だと思います。
でも、実は「ORDER BY 条件」ってできるっぽいです。
例えば(SQLITEですが)


create table test (id integer primary key, name blob, number integer);
insert into test (name,number) values("a", 10);
insert into test (name,number) values("b", 11);
insert into test (name,number) values("c", 12);
insert into test (name,number) values("d", 100);
insert into test (name,number) values("e", 101);
insert into test (name,number) values("f", 102);
insert into test (name,number) values("g", 1000);
insert into test (name,number) values("h", 1001);
insert into test (name,number) values("i", 1002);
insert into test (name,number) values("j", 13);
insert into test (name,number) values("k", 14);
insert into test (name,number) values("l", 15);

に対して


select * from test order by number >= 10 and number <= 101 DESC;
id          name        number
----------  ----------  ----------
1           a           10
2           b           11
3           c           12
4           d           100
5           e           101
10          j           13
11          k           14
12          l           15
6           f           102
7           g           1000
8           h           1001
9           i           1002

となります。つまり、ORDER BYの後に続く条件に見合うものが上位に来る感じです。
SQLITEの場合、比較が文字列比較になってるところがあるらしく、SQLITE3とSQLITE2で微妙に結果が異なります。
MySQLとかだとまたちょっと違う結果になるかもしれませんが、条件に見合うものを上位に持ってくることが可能です。

以上

Perlトリビアルメモ 1(ファイルロック、正規表現、foreach)

今日、これ(中村屋)の紹介を受けたんですが、こういうのはもっと早く報告していただかないと困りますね。本家じゃないようですが、本家消えてるようで。早めに世界遺産に登録したほうがいいんじゃないでしょうか?

今回はPerlのメモ。最近Perl触ってないので、思い出すため。ノスタルジー。たいしたことは書き(け)ません。

1.ファイルのロック
ファイルのロックは、今時flock()。昔はWindowsサーバーとかで使えなかったりしてsymlinkやmkdirで代用する手法がメジャー(?)だった。今はWindowsでもflock()使えるし、大体においてflock()でOK、ってどっかで読んだ。
問題はロックするタイミング。
失敗例:


open(FILE, " > file.txt");
flock(FILE, 2);

ロックする前にファイルサイズが0になるので×。追加書き込みモードで開く。


open(FILE, "+< file.txt");
flock(FILE, 2);

もちろん、新規にファイルを作成する場合は最初のでOK。
もっと問題なのはデッドロック。CGIなどで複数のファイルを読み書きする必要がある場合で、複数の同時アクセスがあった場合、一個一個のファイル操作で無頓着にロックを行っているとデッドロックになる。
例えば、ユーザの1アクセスでファイルAとファイルBを読み書きする場合。次のような順番で処理が行われると危険。

①ユーザFooがファイルAをロックして読み書き開始。
②ユーザBarがファイルBをロックして読み書き開始。
③ユーザFooはファイルAをロックしたままファイルBを読み書き開始。
④ユーザBarはファイルBをロックしたままファイルAを読み書き開始。

この場合、③でファイルBはBarによってロックされているので、ロックが解除されるまでFooは待とうとします。同様に④でファイルAはFooによってロックされているので、ロックが解除されるまでBarは待とうとします。ここでどちらも処理が止まり、どのファイルもロックが解除されることはありません。デッドロック。
①の後、FooがとっととファイルAを開放すりゃいいじゃないかという案もありますが、ファイルAを更新するためにはファイルBの内容が必要ということもあります。いったんファイルAを開放し、ファイルBを読み込んだ後改めてファイルAを更新するという手順を踏むと、ファイルAを開放している間に他のプロセスによってファイルAが更新されてしまい、データの連続性が失われる、とかそういう話です。
こういう場合はどうしたらいいかというと、簡単には2通りだったと思います。

○どんなアクセスでもファイルAを読み込んでからファイルBを読み込む。
○処理全体でロックしちゃう。

最初の方法だと、②でユーザBarはファイルBを操作する前にファイルAを操作しなくてはなりません。しかし、ファイルAはロックされているため、ユーザFooの処理が終わるまではBarは手出しできないという寸法です。
しかし、実際にはファイルAやBがユーザ情報ファイルだったりする場合、Barが最初に読み込むべきはファイルBでしょう。

そういうわけで、後者の方法が手っ取り早いです。現在のネット航海時代のユーザ情報ファイルアクセスもこの方式(のはず)です。
この方法ではファイルロック用に別途ファイルを用意しておいて、プロセス開始後、目的のファイルを操作する前にこのファイルロック用ファイルをロックします。その後、どのファイルでも何個でも適当にアクセスします。プロセス終了時にファイルロック用のファイルのロックを解除します。こうしておけば、処理中はファイルロック用ファイルがずっとロックされた状態になり、他のプロセスは手出しできないようになります。ネット航海時代ではシステム上、複数のユーザ情報ファイルにアクセスする必要があるためこのようにしています。(パフォーマンスは下がると思いますが。というか「DBを使え」という話も・・・。一度DB化したんですが、めんどくさくてリリースしませんでした。)

2.正規表現
同じ正規表現を繰り返し利用する場合は、正規表現をコンパイルしたほうが早いらしいです。正規表現のコンパイルにはqrを使います。


$pattern = qr/abc(\\d+)efg/;

foreach (@text) {
    if ($_ =~ /$pattern/) {
        print $1;    # 後方参照もOK
    }
}

3.foreach()
PHPやってるから思う疑問かもしれません。foreachでの変数の変更は有効か。


@text = ("aaa", "bbb");

foreach (@text) {
	$_ = "ccc";
}

foreach (@text) {
	print "$_\n";
}

結果:


ccc
ccc

ちなみにPHPでやると


$text = array("aaa", "bbb");

foreach ($text as $one) {
	$one = "ccc";
}
print_r($text);

結果:


aaa
bbb

PHP5だと以下のように書けば、


$text = array("aaa", "bbb");

foreach ($text as &$one) {   // &が付いた
	$one = "ccc";
}
print_r($text);

結果:


ccc
ccc

以上

C++でも正規表現を使いたいよ!本当はCでも使いたいけど!

今はもうない読んだ。まあ、いわゆるひとつの「やられた」。いつものことですが。
萌絵みたいな女性がいたら、一度ぎゃふんと言わされてみたい。

C++で正規表現。
boostとか使えばできますが、boostって結構でかいって言うか、ちょっと正規表現使いたいだけなのにboostの諸々を入れるのは面倒、ということはあるんじゃないかと思います。
で、便利じゃないかと思ってるのがGRETAです。
(2010/05/20 ↑消えたっぽい。とりあえずこっち。)
VCで使うという条件で、商用利用もフリーで可だったと思われるライブラリです。
簡単な使い方だけ示しておきます。(要望があれば多少詳しく説明します。)


#include < iostream >
#include < string >
#include "regexpr2.h"

int main(int argc, char *argv[]) {
    regex::match_results results;  // 結果格納用変数
    string str("abcdefg12345hijk"); // 検索対象文字列

    regex::rpattern pat("\\d+(\\w+)");  // 正規表現。\\は2個要るよ!
    regex::match_results::backref_type br = pat.match( str, results );  // マッチ。brはマッチした部分が入る。br=="12345hijk"
    std::cout << br << std::endl; // 12345hjik
    regex::match_results::backref_vector all_br = results.all_backrefs();  // 後方参照をするためのvector。
    std::cout << all_br[0] << std::endl; // 12345hjik
    std::cout << all_br[1] << std::endl; // hjik


    regex::rpattern subst("\\d+", "zzzz", regex::GLOBAL);  // 置換定義。置換前、置換後、パラメータ。
    regex::subst_results substitute_results;
    subst.substitute(str, substitute_results);
    std::cout << str << std::endl; // abcdefgzzzzhijk

    return 0;
}

wstringを使いたい場合はbasic_rpatternなどがあります。
置換はパラメータをいろいろ与えることで、全部置換とか最初の一個とか指定できます。
また、置換だけでなくsplitとかもあります。
注意事項としては、GRETAは完全なテンプレートライブラリというわけではなく、regexpr2.cppとsyntax2.cppをコンパイルしてリンクする必要があります。

以上

CakePHPではまったこと 4(sqliteをデータベースとして使う)

WiiWare第一弾?的なものが発表されています。
日本語のものはまだですか?

実は今回は別にはまったわけじゃないけど、番号稼ぎ(4)。
CakePHPでデータベースにSQLiteを使う。
SQLiteはGoogleGearsにも使われとるし。(関係ないけど)

まあ、コンフィグいじるだけ。(まったくもってたいした内容じゃないな)
/app/config/database.php


    var $default = array('driver' => 'sqlite',
                                'connect' => 'sqlite_open',
                                'host' => '',                         // 空でいい
                                'login' => '',                         // 空でいいんだろう
                                'password' => '',                  // 空でいいんじゃないかな
                                'database' => 'filename.db',   // webroot直下にこの名前でファイルができる
                                'prefix' => '');

/app/webroot/filename.dbっていうファイルができます。これがデータベースです。
トランザクションは基本的に使ってないみたいなんで(SQLiteに限らず)、使いたいときはちょっと考えないといけないなぁ。
つか、使いたいよなぁ。どのデータベースでもトランザクション使わないと遅そうだし、SQLiteは特に遅いし。
その辺はまた今度。
ちなみにPHPのSQLiteはバージョンが2.xなんで、このファイルをコマンドラインツールから扱いたいときは2.xで。

以上

Home > Tips Archive

Search
Feeds
Meta
 合計:018987
 今日:0126 昨日:0157

Return to page top