ページ 11

strstr()と_mbsstr()について

Posted: 2014年8月17日(日) 22:34
by stone
初めて投稿します。
VisualStudio2012で、MFCを利用しています。
以下の二点について教えてください。
1. Shift-jisでの全角文字などのマルチバイト文字には_mbsstr()を使わないといけないのかと思っていましたが、strstr()でも問題なく動作するように見える。strstr()と_mbsstr()の使い分けはどのようにしたらいいのでしょうか。

2. const char*とchar*、さらにはconst unsigned char*の違いが十分に理解できません。
たとえば_mbsstr()の引数としてconst unsigned char*が求められている。
std::stringのc_str()で得られるconst char*の文字列を引数として与えたいので、(const unsigned char*)で単純にキャストすると動作したがこれでいいのでしょうか。
検索対象文字列にもconst unsigned char*が求められているので、(const unsigned char*))"あいうえお"などとしたがこれでいいのでしょうか。
または、const char*をchar*にキャストすることもできましたが、これはやってはいけないような気がします。どうでしょうか?

Re: strstr()と_mbsstr()について

Posted: 2014年8月18日(月) 02:31
by かずま
stone さんが書きました: 1. Shift-jisでの全角文字などのマルチバイト文字には_mbsstr()を使わないといけないのかと思っていましたが、strstr()でも問題なく動作するように見える。strstr()と_mbsstr()の使い分けはどのようにしたらいいのでしょうか。

コード:

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

void dump(const unsigned char *s)
{
    printf("%8s: %p: ", s, s);
    while (*s) printf("%02x ", *s++);
    putchar('\n');
}

int main()
{
    const char *s1 = "投売り";
    const char *s2 = "株";
    const char *s3 = strstr(s1, s2);
    unsigned char *s4 = _mbsstr((unsigned char*)s1, (unsigned char*)s2);
    dump((unsigned char *)s1);
    dump((unsigned char *)s2);
    printf("strstr:  %p [%.2s]\n", s3, s3);
    printf("_mbsstr: %p [%s]\n", s4, s4);
    return 0;
}
実行結果

コード:

  投売り: 0115C014: 93 8a 94 84 82 e8 
      株: 0115C01C: 8a 94 
strstr:  0115C015 [株]
_mbsstr: 00000000 [(null)]
「投売り」の中に「株」なんかないのに、
strstr では見つかってしまいました。
strstr は、バイト単位で検索します。
_mbsstr は、文字単位で検索します。

2番目の質問は、他の人にお願いします。

Re: strstr()と_mbsstr()について

Posted: 2014年8月18日(月) 05:25
by へにっくす
1.はかずまさんの回答の通りですね。
stone さんが書きました:2. const char*とchar*、さらにはconst unsigned char*の違いが十分に理解できません。
たとえば_mbsstr()の引数としてconst unsigned char*が求められている。
std::stringのc_str()で得られるconst char*の文字列を引数として与えたいので、(const unsigned char*)で単純にキャストすると動作したがこれでいいのでしょうか。
検索対象文字列にもconst unsigned char*が求められているので、(const unsigned char*))"あいうえお"などとしたがこれでいいのでしょうか。
または、const char*をchar*にキャストすることもできましたが、これはやってはいけないような気がします。どうでしょうか?
2.は、あなたの考えている通りです。
unsigned付きの型、unsignedなしの型にキャストするのはok。
const付きの型をconstなしの型にキャストするのは基本的にはNG。
ただWin32APIなどのライブラリで、入力用なのにconst付きで宣言されていない場合は仕方がないのでconstなしの型にキャストするしかないです…
C++言語ならば、const_cast演算子を使ってください→C++ のキャスト - const_cast

Re: strstr()と_mbsstr()について

Posted: 2014年8月18日(月) 18:23
by stone
とても分かりやすく説明していただき、どうもありがとうございました。