23

私は答えをかなり探し回っています。、などmy_strcmp()の独自の文字列関数のシリーズを作成します。my_strcat()

strcmp()文字の2つの配列の各インデックスを処理し、ASCII値が2つの文字列の同一のインデックスで小さい場合、その文字列はアルファベット順に大きいため、0、1、または2が返されますか?私が求めているのは、これらの結果を返すために文字のASCII値を使用しているのでしょうか。

どんな助けでも大歓迎です。

[改訂]

OK、それで私はこれを思いついた...それは2番目の文字列が最初の文字列よりも大きい場合を除いてすべての場合に機能します。

任意のヒント?

int my_strcmp(char s1[], char s2[])
{   
    int i = 0;
    while ( s1[i] != '\0' )
    {
        if( s2[i] == '\0' ) { return 1; }
        else if( s1[i] < s2[i] ) { return -1; }
        else if( s1[i] > s2[i] ) { return 1; }
        i++;
    }   
    return 0;
}


int main (int argc, char *argv[])
{
    int result = my_strcmp(argv[1], argv[2]);

    printf("Value: %d \n", result);

    return 0;

}
4

9 に答える 9

35

の擬似コード「実装」は次のstrcmpようになります。

define strcmp (s1, s2):
    p1 = address of first character of str1
    p2 = address of first character of str2

    while contents of p1 not equal to null:
        if contents of p2 equal to null: 
            return 1

        if contents of p2 greater than contents of p1:
            return -1

        if contents of p1 greater than contents of p2:
            return 1

        advance p1
        advance p2

    if contents of p2 not equal to null:
        return -1

    return 0

基本的にはそれだけです。各文字が順番に比較され、その文字に基づいて、最初の文字列と2番目の文字列のどちらが大きいかが決定されます。

文字が同一の場合にのみ次の文字に移動し、すべての文字が同一の場合はゼロが返されます。

必ずしも1と-1を取得できるとは限らないことに注意してください。仕様では、正または負の値で十分であると規定されているため、常に< 0> 0またはで戻り値を確認する必要があります== 0

それを実際のCに変換するのは比較的簡単です。

int myStrCmp (const char *s1, const char *s2) {
    const unsigned char *p1 = (const unsigned char *)s1;
    const unsigned char *p2 = (const unsigned char *)s2;

    while (*p1 != '\0') {
        if (*p2 == '\0') return  1;
        if (*p2 > *p1)   return -1;
        if (*p1 > *p2)   return  1;

        p1++;
        p2++;
    }

    if (*p2 != '\0') return -1;

    return 0;
}

また、文字のコンテキストでの「より大きい」は、必ずしもすべての文字列関数の単純なASCII順序に基づいているわけではないことにも注意してください。

Cには、(とりわけ)照合または基になる文字セットの順序を指定する「ロケール」と呼ばれる概念があり、たとえば、文字a、、、およびがすべて同一であると見なされる場合がありますá。これは、のような関数で発生します。àästrcoll

于 2012-08-27T04:53:14.810 に答える
10

BSDの実装は次のとおりです。

int
strcmp(s1, s2)
    register const char *s1, *s2;
{
    while (*s1 == *s2++)
        if (*s1++ == 0)
            return (0);
    return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
}

2つの文字の間に不一致があると、それらの2つの文字の違いを返すだけです。

于 2012-08-27T04:48:54.663 に答える
9

文字のバイト値を使用し、最初の文字列が2番目の文字列の前に表示される場合は負の値(バイト値の順序)を返し、等しい場合はゼロを返し、最初の文字列が2番目の文字列の後に表示される場合は正の値を返します。バイトで動作するため、エンコーディングに対応していません。

例えば:

strcmp("abc", "def") < 0
strcmp("abc", "abcd") < 0 // null character is less than 'd'
strcmp("abc", "ABC") > 0 // 'a' > 'A' in ASCII
strcmp("abc", "abc") == 0

より正確には、strcmp OpenGroup仕様で説明されているように:

ゼロ以外の戻り値の符号は、比較される文字列が異なる最初のバイトのペア(両方ともunsigned char型として解釈される)の値の差の符号によって決定されます。

戻り値はこの差と等しくない場合がありますが、同じ符号が付けられることに注意してください。

于 2012-08-27T04:44:35.137 に答える
4

これが私のバージョンで、MISRA-C準拠の小さなマイクロコントローラーアプリケーション用に書かれています。このコードの主な目的は、ほとんどのコンパイラライブラリにある1行のgooではなく、読み取り可能なコードを記述することでした。

int8_t strcmp (const uint8_t* s1, const uint8_t* s2)
{
  while ( (*s1 != '\0') && (*s1 == *s2) )
  {
    s1++; 
    s2++;
  }

  return (int8_t)( (int16_t)*s1 - (int16_t)*s2 );
}

注:コードは16ビットintタイプを想定しています。

于 2012-08-27T06:39:35.640 に答える
4

これは、マスター自身から(K&R、第2版、106ページ):

// strcmp: return < 0 if s < t, 0 if s == t, > 0 if s > t
int strcmp(char *s, char *t) 
{
    int i;

    for (i = 0; s[i] == t[i]; i++)
        if (s[i] == '\0')
            return 0;
    return s[i] - t[i];
}
于 2015-12-04T08:15:48.290 に答える
2

このコードは同等で、短く、読みやすくなっています。

int8_t strcmp (const uint8_t* s1, const uint8_t* s2)
{
    while( (*s1!='\0') && (*s1==*s2) ){
        s1++; 
        s2++;
    }

    return (int8_t)*s1 - (int8_t)*s2;
}

s1の終わりをテストする必要があるのは、s1の終わりの前にs2の終わりに達すると、ループが終了するためです(* s2!= * s1以降)。

戻り式は、7ビット(純粋なASCII)文字のみを使用している場合、すべての場合に正しい値を計算します。 整数のオーバーフローのリスクがあるため、8ビット文字の正しいコードを生成するには注意が必要です。

于 2014-05-12T03:18:27.960 に答える
1

私はこれをウェブ上で見つけました。

http://www.opensource.apple.com/source/Libc/Libc-262/ppc/gen/strcmp.c

int strcmp(const char *s1, const char *s2)
{
    for ( ; *s1 == *s2; s1++, s2++)
        if (*s1 == '\0')
            return 0;
    return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
}
于 2015-09-15T11:50:03.733 に答える
-1

これが私のstrcmpの実装方法です。これは次のように 機能します。2つの文字列の最初の文字を比較し、同一の場合は次の文字に進みます。そうでない場合は、対応する値を返します。非常にシンプルで理解しやすいです:#include

//function declaration:
int strcmp(char string1[], char string2[]);

int main()
{
    char string1[]=" The San Antonio spurs";
    char string2[]=" will be champins again!";
    //calling the function- strcmp
    printf("\n number returned by the strcmp function: %d", strcmp(string1, string2));
    getch();
    return(0);
}

/**This function calculates the dictionary value of the string and compares it to another string.
it returns a number bigger than 0 if the first string is bigger than the second
it returns a number smaller than 0 if the second string is bigger than the first
input: string1, string2
output: value- can be 1, 0 or -1 according to the case*/
int strcmp(char string1[], char string2[])
{
    int i=0;
    int value=2;    //this initialization value could be any number but the numbers that can be      returned by the function
    while(value==2)
    {
        if (string1[i]>string2[i])
        {
            value=1;
        }
        else if (string1[i]<string2[i])
        {
            value=-1;
        }
        else
        {
            i++;
        }
    }
    return(value);
}
于 2015-01-09T12:05:31.630 に答える
-2

これだけです:

int strcmp(char *str1, char *str2){
    while( (*str1 == *str2) && (*str1 != 0) ){
        ++*str1;
        ++*str2;
    }
    return (*str1-*str2);
}

より高速にしたい場合は、次のように、入力の前に「register」を追加できます。register char

次に、このように:

int strcmp(register char *str1, register char *str2){
    while( (*str1 == *str2) && (*str1 != 0) ){
        ++*str1;
        ++*str2;
    }
    return (*str1-*str2);
}

このようにして、可能であれば、ALUのレジスタが使用されます。

于 2016-07-03T13:14:26.790 に答える