2011-06-17 7 views
8

プロの好奇心の中で、Cで2つの完全な数字の文字列を比較する最も安全で最速の/最も効率的な方法は何ですか?C - 数字の文字列を比較する

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

int main(void){ 

char str1[5] = "123"; 
char str2[5] = "123"; 
char *ptr; 

if(atoi(str1) == atoi(str2)) 
    printf("Equal strings"); 

if(strtol(str1,&ptr,10) == strtol(str2,&ptr,10)) 
    printf("Equal strings"); 

if(strcmp(str1,str2)==0) 
    printf("Equal strings"); 

return 0; 
} 

答えて

9

strcmp()私の意見では、数値の変換は必要ないため、しかし、この場合は、そのうちの1つに数字だけの文字列が格納されていることを確認する必要があります。あなたは

EDIT1

としては、先行ゼロについて他の人が指摘した文字列にmemcmp()を行うことができます。また

、手動で先行ゼロをスキャンして、ポインタを渡すことによってstrcmp()またはmemcmp()を呼び出すことができます最初のゼロ以外の数字に変更します。

EDIT2

以下のコードは、私が言うことを試みているものを伝えます。これは整数のみであり、浮動小数点数ではありません。

浮動小数点数の場合、小数点以下の後続ゼロは手動で切り捨てる必要があります。

また、手作業全体を手動で行うこともできます。

EDIT4

私はまた、あなたが浮動小数点のために、このコードを見てみたいものです。これは、小数点の前に先行ゼロを検出し、小数点の後にゼロを検出します。例えば

00000000000001.100000000000001.1は、使用前に、いくつかのテストが必要

以下のコードのためのEqual

int main (void) 
{ 
    char s1[128], s2[128]; 
    char *p1, *p2, *p1b, *p2b; 

    printf ("\nEnter 1: "); 
    scanf ("%s", s1); 
    printf ("\nEnter 2: "); 
    scanf ("%s", s2); 

    p1 = s1; 
    p2 = s2; 
    /* used for counting backwards to trim trailing zeros 
    * in case of floating point 
    */ 
    p1b = s1 + strlen (s1) - 1; 
    p2b = s2 + strlen (s2) - 1; 


    /* Eliminate Leading Zeros */ 
    while (*p1 && (*p1 == '0')) 
    p1++; 

    while (*p2 && (*p2 == '0')) 
    p2++; 

    /* Match upto decimal point */ 
    while (((*p1 && *p2) && ((*p1 != '.') && (*p2 != '.'))) && (*p1 == *p2)) 
    { 
    p1++; 
    p2++; 
    } 

    /* if a decimal point was found, then eliminate trailing zeros */ 
    if ((*p1 == '.') && (*p2 == '.')) 
    { 
    /* Eliminate trailing zeros (from back) */ 
    while (*p1b == '0') 
     p1b--; 
    while (*p2b == '0') 
     p2b--; 

    /* match string forward, only upto the remaining portion after 
    * discarding of the trailing zero after decimal 
    */ 
    while (((p1 != p1b) && (p2 != p2b)) && (*p1 == *p2)) 
    { 
     p1++; 
     p2++; 
    } 
    } 

    /* First condition on the LHS of || will be true for decimal portion 
    * for float the RHS will be . If not equal then none will be equal 
    */ 
    if (((*p1 == '\0') && (*p2 == '\0')) || ((p1 == p1b) && (p2 == p2b))) 
    printf ("\nEqual"); 
    else 
    printf ("\nNot equal"); 

    printf ("\n"); 
    return 0; 
} 
になります。

+0

ありがとうございます。これは、関数のstr *ファミリに多く依存しているので、私が常に使用するメソッドです。実際には標準のように見えます。知っておいてよかった! – Valdogg21

+0

@ Valdogg21:私が更新したコードを見てください。これで、設定したプロトコルに従って浮動小数点数を比較できます。 – phoxis

4

str(n)cmpが最も速くて安全です。

+1

'strの(n)のcmp'は、先行ゼロの異なる数の整数の文字列に失敗しました。 – JAB

+1

@ JAB:あなたは文字列 "002"と "0002"が同じであると言っていますか? –

+0

@cnicutar:どういうことですか?私は「100」と「0100」を比較するなどの状況を指していました。 'strcmp'と' strncmp'の両方は、目的の値が0で平等を示すときに0以外の値を返すので、比較は失敗します。 – JAB

0

あなたはそれらが同一であることを望んでいると仮定すると、strncmpは、変換なしで直接比較できるため、最も速く安全です。また、一般的にはstrcmpよりも安全であると考えられています。

ただし、000を同じにするか、同じ番号を若干異なるように表現するには、atoiを使用する必要があります。

+2

"atoi()関数はstrtol()によって廃止されました。新しいコードでは使用しないでください。" –

+0

おかげで、ありがとう。 –

0

私の意見では、「最も安全な」方法は、両方の引数を整数に変換してからテストすることです。そうすることで、先行ゼロの可能性の問題を回避できます。しかし、おそらく最も高速で効率的な方法ではありません。

0

あなたは、単に、次の使用することができます。他

IF(のstrcmp( "123"、 "123")== 0)

{

printf("The strings are equal"); 

}

{

printf("The strings are not equal."); 

}

私の意見では、動作するはずです。

+0

文字列に表された2つの数字が等しいかどうかにかかわらず、質問者は一致したかった – phoxis

0

私は整数のためにこの方法をお勧め:

int strcmp_for_integers(char *aa, char *bb){ 
    char aa2[11] = ""; 
    char bb2[11] = ""; 
    int answer; 

    sprintf(aa2, "%010d", atoi(aa)); 
    sprintf(bb2, "%010d", atoi(bb)); 
    answer = strcmp(aa2, bb2); 

    return answer; 
}