ページ 11

strcmp

Posted: 2009年4月24日(金) 13:37
by 研修生
strcmpの戻り値についてご質問ですがいったい何が戻ってきてるのでしょう?
0より小か大もしくは=で比較していますが-54だったり3だったりでこれは
strcmp(s1,s2)を考えた場合に、s1のバイト数-s2のバイト数を戻り値にしてるのでしょうか?
処理系によって値は異なるみたいですがVC++6.0です。

Re:strcmp

Posted: 2009年4月24日(金) 13:48
by バグ
うちのVC++6.0では、0、-1、1のいずれかしか返ってきません…何故だろう(^_^;)
というか、処理系によって内部処理が違うのならば、それを詳しく知る意味はないのではないでしょうか?
比較方法が知りたいという事であれば、MSDNに詳しく書かれていますよ?

Re:strcmp

Posted: 2009年4月24日(金) 13:55
by 研修生
あ・・失礼しました。教科書のstrcmpの書いた通りにうちこんでコンパイルしてますが
どうもこちらがおかしいようです。ライブラリ関数の方使ったら0,-1,1になりました。
意味がないこともないのですが、文字列の場合どの基準で大小決めてるのか気になったものですから
又、今度自分でもこのような比較関数を作る場合にも参考になります。

Re:strcmp

Posted: 2009年4月24日(金) 14:02
by 研修生
それと、今stricmp関数について考えてるのですが大小区別なく比較とのことで
この関数について考える為に知りたいというのもあります。

Re:strcmp

Posted: 2009年4月24日(金) 14:16
by バグ
VC++6.0のMSDNによると、比較の仕方は基本的に辞書と同じようですね。
ためしに実装してみました。
int strcmp(const char* str1, const char* str2)
{
    while (*str1 != '\0' && *str2 != '\0')
	{
        if (*str1 != *str2)
		{
			break;
		}
		else
		{
			++str1;
			++str2;
		}
    }

    if (*str1 == '\0' && *str2 == '\0')
	{
		return 0;
	}
    else if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
	    return -1;
	}
}

Re:strcmp

Posted: 2009年4月24日(金) 14:21
by たかぎ
strcmpの仕様は、
#include <string.h>

int strcmp(const char *s1, const char *s2)
{
  while (*s1 != '\0' && *s1 == *s2)
  {
    ++s1;
    ++s2;
  }
  return (unsigned char)*s1 - (unsigned char)*s2;
}
といった実装を想定しています。

Visual C++の場合、わざわざ最後に-1, 0, +1に直していますので、それだけ効率が悪くなっています。

Re:strcmp

Posted: 2009年4月24日(金) 14:21
by バグ
>>それと、今stricmp関数について考えてるのですが大小区別なく比較とのことで
>>この関数について考える為に知りたいというのもあります。

これは、toupper、towlowerで全ての文字を大文字か小文字のどちらかに変換しておいて、strcmpを行えば、望んだ結果が得られそうですね。

Re:strcmp

Posted: 2009年4月24日(金) 14:23
by バグ
>>たかぎさん
なるほど、単純比較の結果を戻り値とすることを想定しているから、正負もしくは0という取り決めになっているんですね。

Re:strcmp

Posted: 2009年4月24日(金) 14:57
by Hermit
strcmp の比較は、
とりあえず、unsigned char でキャストするもんだと思ってましたが・・・

VC++ 6.0 の char は、デフォルトでは unsigned char でしょうか?

VC++2008EE のコマンドラインでは、デフォルトで、signed char みたいなので、
後々のためには、一応キャストしておいたほうがいいと思いますよ。

私が書いてるうちに、たかぎさんが書いてましたね。
とりあえず、消せないみたいなので、このまま置いておきます(^^;

Re:strcmp

Posted: 2009年4月24日(金) 15:15
by 研修生
stricmpに関しては小文字か大文字かに直すまでは考えていましたが比較基準による・・
と思ってました。無事にできました、ありがとうございました。

Re:strcmp

Posted: 2009年4月24日(金) 15:31
by たかぎ
stricmpもstrcasecmpも、文字列に含まれる文字をいったん小文字に変換してから比較します。
ただ、ロケールの扱いをどうするのかが難問です。

tolowerを使って変換すると、動作がロケール依存になってしまいます。
そして、もちろんのことながら多バイト文字には対応できません。

また、マルチスレッド環境では、バッググラウンドでロケールの設定が変更された場合にどうするかといった問題もあり、一筋縄ではいきません。