C - Confronto di stringhe numeriche
Domanda
Per curiosità professionale, qual è il modo più sicuro / veloce / più efficiente per confrontare due stringhe completamente numeriche in 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;
}
Soluzione
strcmp ()
a mio avviso, in quanto non necessita di conversioni numeriche. Ma in questo caso devi assicurarti che uno di essi memorizzi una stringa che contiene solo caratteri numerici.
Inoltre puoi eseguire memcmp ()
sulla stringa
<”EDIT1
Come sottolineato da altri riguardo agli zeri iniziali, puoi scorrere manualmente gli zeri iniziali e chiamare strcmp ()
o memcmp ()
passando un puntatore alla prima cifra diversa da zero.
<”EDIT2
Il codice seguente dice cosa sto cercando di dire. Questo è solo per numeri interi, non per numeri in virgola mobile.
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;
}
Per i numeri in virgola mobile, gli zeri finali dopo il punto decimale dovrebbero essere eliminati manualmente.
Oppure fai tutto manualmente.
<”EDIT4
Vorrei anche che dessi un'occhiata a questo codice per la virgola mobile. Questo rileverà gli zeri iniziali prima del decimale e gli zeri finali dopo il decimale. Ad esempio
00000000000001.10000000000000
e 1.1
saranno Equal
per il codice seguente
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 di alcuni test prima dell'uso.
Altri suggerimenti
str(n)cmp
è il più veloce e sicuro.
Supponendo che tu stia cercando che siano identici, strncmp
sarà il più veloce e sicuro poiché può fare un confronto diretto senza alcuna conversione.Inoltre è generalmente considerato più sicuro del strcmp
.
Tuttavia, se desideri che 00
e 0
siano uguali o in altri modi per rappresentare lo stesso numero in modo leggermente diverso, dovrai utilizzare atoi
.
A mio parere, il modo "più sicuro" sarebbe probabilmente quello di convertire entrambi gli argomenti in numeri interi e quindi testarli, poiché in questo modo eviterai il potenziale problema degli zeri iniziali.Tuttavia, probabilmente non è il metodo più veloce o più efficiente.
Puoi semplicemente usare quanto segue:
if (strcmp ("123", "123")== 0)
{
printf("The strings are equal");
}
altro
{
printf("The strings are not equal.");
}
Secondo me dovrebbe funzionare.
Suggerisco questo modo per i numeri interi:
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;
}