PHPのC言語による実装「function ucwords」
てかこんな便利な関数あったの今日知ったんだけどな。
バージョン:PHP 5.2.3
ソース
ext/standard/string.c @line 2463
/* {{{ proto string ucwords(string str) Uppercase the first character of every word in a string */ PHP_FUNCTION(ucwords) { zval **str; register char *r, *r_end; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(str); if (!Z_STRLEN_PP(str)) { RETURN_EMPTY_STRING(); } ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); r = Z_STRVAL_P(return_value); *r = toupper((unsigned char) *r); for (r_end = r + Z_STRLEN_P(return_value) - 1; r < r_end; ) { if (isspace((int) *(unsigned char *)r++)) { *r = toupper((unsigned char) *r); } } } /* }}} */
処理の流れ
とりあえず、ZVALとかその辺の、なんかいつも使ってるんだろうな?というあたりは無視して、ucwordsの処理のクリティカルな部分だけ追うことにする。その上は今度調べるとしよう、そうしよう。
なので、追うところは、
*r = toupper((unsigned char) *r); for (r_end = r + Z_STRLEN_P(return_value) - 1; r < r_end; ) { if (isspace((int) *(unsigned char *)r++)) { *r = toupper((unsigned char) *r); } }
これだ。
- 最初の文字を大文字にする。(toupper)
- r_end (文字列の最後)まで繰り返す
- もし空白なら、次の文字は大文字にする。
意外と処理内容は普通。forでまわしてるのか。
って、ここまで読みながら書きながら考えながらでしたが、重大なことに気づいた。
(int) *(unsigned char *)r++
これなにやってるかよくわからん。(ぉ なんでintにキャストしてるの?
...調べ中...*1
あ。isspace(int c) か。isspaceの引数ってintなんだ。たしかC言語て、charをintにすると文字コードになるんだったかな?ふーん、それで。