質問
専門的な好奇心から、Cで2つの完全に数値の文字列を比較する最も安全な/最速の/最も効率的な方法は何ですか?
#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;
}
解決
strcmp ()
私の意見では、数値変換は必要ありません。しかし、この場合、そのうちの1つに数字のみを含む文字列が格納されていることを確認する必要があります。
また、あなたが行うことができます memcmp ()
文字列に
編集1
先行ゼロについて他の人が指摘したように、先行ゼロを手動でスキャンして呼び出すことができます strcmp ()
または memcmp ()
最初のゼロ以外の数字へのポインタを渡すことによって。
編集2
以下のコードは、私が何を言おうとしているかを示しています。これは整数のためだけであり、浮動小数点数のためではありません。
int main (void)
{
char s1[128], s2[128];
char *p1 = s1, *p2 = s2;
/* populate s1, s2 */
while (*p1 && (*p1 == '0'))
p1++;
while (*p2 && (*p2 == '0'))
p2++;
if (strcmp (p1, p2) == 0)
printf ("\nEqual");
else
printf ("\nNot equal");
printf ("\n");
return 0;
}
浮動小数点数の場合、小数点の後の末尾のゼロは手動で切り捨てる必要があります。
または手動で全体のものを行います。
編集4
私はまた、浮動小数点のためにこのコードを見てほしいと思います。これにより、10進数の前に先行ゼロが検出され、10進数の後に後続ゼロが検出されます。例えば
00000000000001.10000000000000
と 1.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;
}
使用の前にテストを必要とします。
他のヒント
str(n)cmp
が最も速く安全です。
それらが同一であることを探していると仮定すると、strncmp
は、変換なしで直接比較できるため、最も高速で安全です。また、一般的に、strcmp
よりも安全であると考えられています。
ただし、00
と0
を同じにする場合、または同じ数値をわずかに異なる方法で表すことができるその他の方法を使用する場合は、atoi
を使用する必要があります。
私の意見では、「最も安全な」方法は、両方の引数を整数に変換してからテストすることです。そうすれば、潜在的な先行ゼロの問題を回避できます。ただし、これはおそらく最速または最も効率的な方法ではありません。
次のように簡単に使用できます:
if(strcmp( "123"、 "123")== 0)
{ ジェネラコディセタグプレ
}
その他
{ ジェネラコディセタグプレ
}
私の意見では、うまくいくはずです。
整数の場合はこの方法をお勧めします: ジェネラコディセタグプレ