C - Сравнение числовых строк - PullRequest
8 голосов
/ 17 июня 2011

Из профессионального любопытства, какой самый безопасный / быстрый / самый эффективный способ сравнить две полностью числовые строки в 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;
}

Ответы [ 6 ]

9 голосов
/ 17 июня 2011

strcmp () на мой взгляд, так как не нуждается в числовых преобразованиях. Но в этом случае вам нужно убедиться, что один из них хранит строку, которая содержит только числовые символы.

Также вы можете сделать memcmp () на строку

EDIT1

Как уже отмечалось другими о ведущих нулях, вы можете вручную просмотреть начальные нули и вызвать strcmp () или memcmp (), передав указатель на первую ненулевую цифру.

EDIT2

Код ниже говорит о том, что я пытаюсь сказать. Это только для целых чисел, а не для чисел с плавающей запятой.

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;
}

Для чисел с плавающей запятой конечные нули после десятичной запятой должны быть вырезаны вручную.

Или все это сделать вручную.

EDIT4

Я также хотел бы, чтобы вы взглянули на этот код с плавающей запятой. Это позволит обнаружить ведущие нули до десятичной дроби и конечные нули после десятичной. Например

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;
}

Перед использованием требуется некоторое тестирование.

4 голосов
/ 17 июня 2011

str(n)cmp самый быстрый и безопасный.

0 голосов
/ 26 февраля 2012

Я предлагаю этот способ для целых чисел:

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;
}
0 голосов
/ 17 июня 2011

Вы можете просто использовать следующее:

if (strcmp ("123", "123") == 0)

{

  printf("The strings are equal");

}

еще

{

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

}

На мой взгляд, это должно работать.

0 голосов
/ 17 июня 2011

По моему мнению, самый безопасный способ, скорее всего, состоит в том, чтобы преобразовать оба аргумента в целые числа и затем протестировать, так как таким образом вы избежите потенциальной проблемы начальных нулей.Хотя, вероятно, это не самый быстрый или самый эффективный метод.

0 голосов
/ 17 июня 2011

Если вы ищете, чтобы они были идентичными, strncmp будет самым быстрым и безопасным, поскольку он может выполнять прямое сравнение без каких-либо преобразований.Это также обычно считается более безопасным, чем strcmp.

Однако, если вы хотите, чтобы значения 00 и 0 были равны, или для других способов представления одного и того же числа немного по-другому, вам потребуетсяиспользуйте atoi.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...