atol() v/s. strtol()

Lesezeit: 4 Minuten

Was ist der Unterschied zwischen atol() und strtol()?

Laut ihren Manpages scheinen sie den gleichen Effekt sowie passende Argumente zu haben:

long atol(const char *nptr);

long int strtol(const char *nptr, char **endptr, int base);

In einem allgemeinen Fall, wenn ich die nicht verwenden möchte base Argument (ich habe nur Dezimalzahlen), welche Funktion soll ich verwenden?

Benutzeravatar von Eli Bendersky
Eli Bendersky

strtol bietet Ihnen mehr Flexibilität, da es Ihnen tatsächlich sagen kann, ob die gesamte Zeichenfolge in eine Ganzzahl konvertiert wurde oder nicht. atolwenn die Zeichenfolge nicht in eine Zahl konvertiert werden kann (wie in atol("help")), gibt 0 zurück, was nicht zu unterscheiden ist atol("0"):

int main()
{
  int res_help = atol("help");
  int res_zero = atol("0");

  printf("Got from help: %d, from zero: %d\n", res_help, res_zero);
  return 0;
}

Ausgänge:

Got from help: 0, from zero: 0

strtol wird angeben, mit seiner endptr Argument, bei dem die Konvertierung fehlgeschlagen ist.

int main()
{
  char* end;
  int res_help = strtol("help", &end, 10);

  if (!*end)
    printf("Converted successfully\n");
  else
    printf("Conversion error, non-convertible part: %s", end);

  return 0;
}

Ausgänge:

Conversion error, non-convertible part: help

Daher empfehle ich für jede ernsthafte Programmierung auf jeden Fall die Verwendung von strtol. Es ist etwas kniffliger zu bedienen, aber das hat einen guten Grund, wie ich oben erklärt habe.

atol möglicherweise nur für sehr einfache und kontrollierte Fälle geeignet.

  • Ich glaube an dein Beispiel, die Bedingung sollte sein if (!*end). Es zeigt auf den Null-Terminator der Zeichenfolge (wenn alles konvertiert wurde), wird aber selbst nicht auf NULL gesetzt.

    – Jeff Mercado

    25. September 2010 um 6:14 Uhr

  • Gilt diese gleiche Logik für die Linux-Kernel-Funktion? simple_strtol? Ich kann die nicht bekommen if (!*end) Bedingung, die unter Verwendung Ihres genauen Modells als wahr bewertet werden soll.

    – boltup_im_coding

    21. November 2012 um 17:01 Uhr

  • Dies behandelt keine Fehler im Zusammenhang mit Zahlen außerhalb des zulässigen Bereichs. Dazu muss errno überprüft werden!

    – Shriram V

    5. Dezember 2012 um 17:32 Uhr

  • Vielen Dank. Ich habe atol mit der Zeichenfolge “123ABC” ausprobiert und es hat mir den Wert 123 gegeben. Sie haben also Recht “für jede ernsthafte Programmierung empfehle ich definitiv die Verwendung von strtol”. 🙂

    – jemand_ Smiley

    1. August 2014 um 5:18 Uhr

  • Beachten Sie, dass POSIX 1003.1 tut nicht garantiere das 0 wird von zurückgegeben atol() im Fehlerfall. Zitieren: Wenn der Wert nicht dargestellt werden kann, ist das Verhalten undefiniert.

    – patryk.beza

    30. Dezember 2015 um 16:14 Uhr


AnT steht mit Russlands Benutzer-Avatar
AnT steht zu Russland

atol Funktionalität ist eine Teilmenge von strtol Funktionalität, außer das atol bietet Ihnen keine nutzbaren Fehlerbehandlungsfunktionen. Das auffälligste Problem mit ato... Funktionen ist, dass sie bei Überlauf zu undefiniertem Verhalten führen. Hinweis: Dies ist nicht nur ein Mangel an informativem Feedback im Fehlerfall undefiniertes Verhaltendh im Allgemeinen ein nicht behebbarer Fehler.

Das bedeutet, dass atol Funktion (sowie alle anderen ato.. Funktionen) ist für ernsthafte praktische Zwecke ziemlich nutzlos. Es war ein Designfehler und sein Platz ist auf dem Schrottplatz der C-Geschichte. Sie sollten Funktionen von verwenden strto... Gruppe, um die Konvertierungen durchzuführen. Sie wurden unter anderem eingeführt, um die inhärenten Probleme von Funktionen zu beheben ato... Gruppe.

Laut dem atoi Manpage, es wurde von veraltet strtol.

IMPLEMENTATION NOTES
The atoi() and atoi_l() functions have been deprecated by strtol() and strtol_l() 
and should not be used in new code.

atol(str) ist äquivalent zu

strtol(str, (char **)NULL, 10);

Verwenden Sie strtol, wenn Sie den Endzeiger (um zu überprüfen, ob noch weitere Zeichen zu lesen sind oder ob Sie überhaupt welche gelesen haben) oder eine andere Basis als 10 möchten. Andernfalls ist atol in Ordnung.

In neuem Code würde ich immer verwenden strtol. Es hat Fehlerbehandlung und die endptr Mit dem Argument können Sie sehen, welcher Teil der Zeichenfolge verwendet wurde.

Der C99-Standard sagt über die ato* Funktionen:

Bis auf das Fehlerverhalten sind sie äquivalent

atoi: (int)strtol(nptr,(char **)NULL, 10)
atol: strtol(nptr,(char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)

Benutzeravatar von Jeff Mercado
Jeff Mercado

Wenn die Erinnerung dient, strtol() hat den zusätzlichen Vorteil, die (optional) endptr um auf das erste Zeichen zu zeigen, das nicht konvertiert werden konnte. Wenn NULL, wird ignoriert. Auf diese Weise könnten Sie fortfahren, wenn Sie eine Zeichenfolge verarbeiten, die Zahlen und Zeichen gemischt enthält.

z.B,

char buf[] = "213982 and the rest";
char *theRest;
long int num = strtol(buf, &theRest, 10);
printf("%ld\n", num);    /* 213982 */
printf("%s\n", theRest); /* " and the rest" */

Benutzeravatar von Shriram V
Schram V

Die Manpage von strtol gibt folgendes aus:

ERRORS
   EINVAL (not in C99) The given base contains an unsupported value.
   ERANGE The resulting value was out of range.
   The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).

Der folgende Code prüft auf Bereichsfehler. (Code von Eli etwas geändert)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main()
{
   errno = 0;
   char* end = 0;
   long res = strtol("83459299999999999K997", &end, 10);

   if(errno != 0)
   {
      printf("Conversion error, %s\n", strerror(errno));
   }
   else if (*end)
   {
      printf("Converted partially: %i, non-convertible part: %s\n", res, end);
   }
   else
   {
      printf("Converted successfully: %i\n", res);
   }

   return 0;
}

1415830cookie-checkatol() v/s. strtol()

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy