Pergunta

Por curiosidade profissional, qual é a maneira mais segura / rápida / eficiente de comparar duas strings totalmente numéricas em 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;
}
Foi útil?

Solução

strcmp () na minha opinião, uma vez que não necessita de conversões numéricas. Mas, neste caso, você precisa ter certeza de que um deles armazena uma string que contém apenas caracteres numéricos.

Além disso, você pode fazer memcmp () na string

< PaulEDIT1

Conforme apontado por outros sobre os zeros à esquerda, você pode ler manualmente os zeros à esquerda e chamar strcmp () ou memcmp () passando um ponteiro para o primeiro dígito diferente de zero.

O código abaixo diz o que estou tentando dizer. Isso é apenas para números inteiros, não para números de ponto flutuante.

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

Para números de ponto flutuante, os zeros à direita após o ponto decimal devem ser cortados manualmente.

Ou faça tudo manualmente.

< PaulEDIT4

Também gostaria que você desse uma olhada neste código para ponto flutuante. Isso detectará zeros à esquerda antes do decimal e zeros à direita depois do decimal. Por exemplo

00000000000001.10000000000000 e 1.1 serão Equal para o código abaixo

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

Necessita de alguns testes antes de usar.

Outras dicas

str(n)cmp é o mais rápido e seguro.

Supondo que você esteja procurando que sejam idênticos, strncmp será o mais rápido e seguro, pois pode fazer uma comparação direta sem nenhuma conversão.Também é geralmente considerado mais seguro do que strcmp.

No entanto, se você deseja que 00 e 0 sejam iguais ou outras maneiras de representar o mesmo número de maneira um pouco diferente, será necessário usar atoi.

Na minha opinião, a maneira "mais segura" provavelmente seria converter ambos os argumentos em inteiros e, em seguida, testar, pois dessa forma você evitará o problema potencial de zeros à esquerda.Provavelmente não é o método mais rápido ou eficiente.

Você pode simplesmente usar o seguinte:

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

{

  printf("The strings are equal");

}

outro

{

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

}

Na minha opinião, deve funcionar.

Sugiro esta forma para inteiros:

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;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top