Pregunta

Por curiosidad profesional, ¿cuál es la forma más segura / rápida / eficiente de comparar dos cadenas completamente numéricas en 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;
}
¿Fue útil?

Solución

strcmp () en mi opinión, ya que no necesita conversiones numéricas. Pero en este caso, debe asegurarse de que uno de ellos almacene una cadena que contenga solo caracteres numéricos.

También puede hacer memcmp () en la cadena

<×EDIT1

Como han señalado otros acerca de los ceros iniciales, puede escanear manualmente los ceros iniciales y llamar a strcmp () o memcmp () pasando un puntero al primer dígito distinto de cero.

<×EDIT2

El siguiente código dice lo que estoy tratando de decir. Esto es solo para números enteros, no para números de coma flotante.

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 los números de coma flotante, los ceros que siguen a la coma decimal deben cortarse manualmente.

O haz todo el proceso manualmente.

<×EDIT4

También me gustaría que echaras un vistazo a este código para punto flotante. Esto detectará ceros iniciales antes del decimal y ceros finales después del decimal. Por ejemplo

00000000000001.10000000000000 y 1.1 serán Equal para el siguiente código

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

Necesita algunas pruebas antes de su uso.

Otros consejos

str(n)cmp es el más rápido y seguro.

Suponiendo que busca que sean idénticos, strncmp será el más rápido y seguro ya que puede hacer una comparación directa sin conversiones.También se considera generalmente más seguro que strcmp.

Sin embargo, si desea que 00 y 0 sean iguales, u otras formas en las que pueda representar el mismo número de forma ligeramente diferente, deberá utilizar atoi.

En mi opinión, la forma "más segura" probablemente sería convertir ambos argumentos en números enteros y luego probar, ya que de esa forma evitará el problema potencial de los ceros iniciales.Sin embargo, probablemente no sea el método más rápido o más eficiente.

Simplemente puede usar lo siguiente:

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

{

  printf("The strings are equal");

}

más

{

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

}

En mi opinión, debería funcionar.

Sugiero esta forma para los números enteros:

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top