itoa()
ist eine wirklich praktische Funktion, um eine Zahl in einen String umzuwandeln. Linux scheint nicht zu haben itoa()
gibt es eine äquivalente Funktion oder muss ich verwenden sprintf(str, "%d", num)
?
Wo ist die Itoa-Funktion in Linux?
Adam Pierc
Matt J
BEARBEITEN: Entschuldigung, ich hätte daran denken sollen, dass diese Maschine entschieden nicht standardmäßig ist, nachdem ich verschiedene nicht standardmäßige angeschlossen hatte libc
Implementierungen für akademische Zwecke 😉
Wie itoa()
ist in der Tat kein Standard, wie von mehreren hilfreichen Kommentatoren erwähnt, es ist am besten zu verwenden sprintf(target_string,"%d",source_int)
oder (noch besser, weil es vor Pufferüberläufen sicher ist) snprintf(target_string, size_of_target_string_in_bytes, "%d", source_int)
. Ich weiß, es ist nicht ganz so prägnant oder cool wie itoa()
aber zumindest kannst du Write Once, Run Everywhere ™ 😉
Hier ist die alte (bearbeitete) Antwort
Sie haben Recht, wenn Sie sagen, dass die Standardeinstellung gcc libc
beinhaltet nicht itoa()
, wie mehrere andere Plattformen, da es technisch gesehen nicht Teil des Standards ist. Sehen hier für ein bisschen mehr info. Beachten Sie, dass Sie müssen
#include <stdlib.h>
Das weißt du natürlich schon, weil du es wolltest verwenden itoa()
unter Linux, nachdem Sie es vermutlich auf einer anderen Plattform verwendet haben, aber … der Code (von dem obigen Link gestohlen) würde so aussehen:
Beispiel
/* itoa example */
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i;
char buffer [33];
printf ("Enter a number: ");
scanf ("%d",&i);
itoa (i,buffer,10);
printf ("decimal: %s\n",buffer);
itoa (i,buffer,16);
printf ("hexadecimal: %s\n",buffer);
itoa (i,buffer,2);
printf ("binary: %s\n",buffer);
return 0;
}
Ausgabe:
Enter a number: 1750 decimal: 1750 hexadecimal: 6d6 binary: 11011010110
Hoffe das hilft!
-
Hmmm, das Kompilieren auf Debian gibt mir “undefinierte Referenz auf `itoa'”. Vielleicht stimmt etwas mit meinem System nicht.
– Adam Pierce
10. Oktober 2008 um 5:38 Uhr
-
Ich bekomme das gleiche auf Ubuntu 8.04. Ich kann auch in stdio.h oder stdlib.h keinen Hinweis auf itoa finden (nicht überraschend, da es nicht Teil des Standards ist)
– camh
10. Oktober 2008 um 5:39 Uhr
-
auf Korrektheit bearbeitet, danke Jungs! Entschuldigung, ich vergesse immer, dass dies keine Vanilla-Linux-Box ist 😉
– Matt J
10. Oktober 2008 um 5:53 Uhr
-
Ich habe die Antwort so bearbeitet, dass sie das Argument der Puffergröße enthält. Ich glaube, jetzt ist alles so, wie es sein sollte, ich sehe kein Problem mit der Reihenfolge der Argumente an sich. Übersehe ich etwas?
– Matt J
7. Januar 2010 um 23:38 Uhr
-
Es funktioniert nicht für Linux? Was ist das Ergebnis der Frage / Antwort (Nicht-Standard scheinen alle Linux zu sein?)
– Benutzer784435
15. Mai 2013 um 8:27 Uhr
hackt
itoa
ist keine Standard-C-Funktion. Sie können Ihre eigenen implementieren. Es erschien in der ersten Ausgabe von Kernighan und Ritchies Die Programmiersprache Cauf Seite 60. Die zweite Ausgabe von The C Programming Language (“K&R2”) enthält die folgende Implementierung von itoa
auf Seite 64. Das Buch weist auf mehrere Probleme mit dieser Implementierung hin, einschließlich der Tatsache, dass die negativste Zahl wird nicht korrekt behandelt
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
Die Funktion reverse
oben verwendet wird zwei Seiten früher implementiert:
#include <string.h>
/* reverse: reverse string s in place */
void reverse(char s[])
{
int i, j;
char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
Jakob Antill
Wenn Sie es häufig aufrufen, kann der Rat “einfach snprintf verwenden” lästig sein. Also hier ist, was Sie wahrscheinlich wollen:
const char *my_itoa_buf(char *buf, size_t len, int num)
{
static char loc_buf[sizeof(int) * CHAR_BITS]; /* not thread safe */
if (!buf)
{
buf = loc_buf;
len = sizeof(loc_buf);
}
if (snprintf(buf, len, "%d", num) == -1)
return ""; /* or whatever */
return buf;
}
const char *my_itoa(int num)
{ return my_itoa_buf(NULL, 0, num); }
-
Es ist nicht nur nicht-threadsicher, es ist überhaupt nicht sehr sicher: – void some_func(char* a, char* b); some_func(itoa(123), itoa(456)); Möchten Sie raten, was die Funktion erhält?
– jcoder
13. November 2012 um 12:55 Uhr
-
Ebenfalls,
const
Qualifizierer haben keine Auswirkungen auf Funktionsrückgabetypen – Sie würden dies wissen, wenn Sie Compiler-Warnungen aktiviert hätten 🙂– Katze
22. September 2016 um 17:25 Uhr
-
@cat Aber hier gibt es keine const-qualifizierten Rückgabetypen.
const char *
ist ein nicht konstanter Zeiger auf const, was sehr sinnvoll und korrekt ist.– Chortos-2
14. Oktober 2016 um 0:16 Uhr
-
@ Chortos-2 Das ist interessant, Sie haben natürlich völlig recht – ich habe den semantischen Unterschied in der Bedeutung von nicht erkannt
const
zwischenconst int f (void) { ...
undconst int* f (void) { ...
aber nachdem ich es jetzt mit einem Compiler versucht habe, macht es Sinn.– Katze
14. Oktober 2016 um 0:22 Uhr
-
Die Größe des statischen Puffers macht überhaupt keinen Sinn, da der darin abgelegte String nicht binär ist. Auf einem typischen Computer sind es 32 Zeichen, aber (unter der Annahme von 32-Bit
int
) die längste Zeichenfolge ist"-2147483648"
die nur 12 Zeichen benötigt. Vielleicht ist es aber eine sichere, großzügige Obergrenze?– abschalten
1. Februar 2019 um 12:28 Uhr
Mark Lösegeld
Bearbeiten: Ich habe es gerade erfahren std::to_string
die im Betrieb mit meiner eigenen Funktion unten identisch ist. Es wurde in C++11 eingeführt und ist in neueren Versionen von gcc verfügbar, mindestens so früh wie 4.5, wenn Sie die c++0x-Erweiterungen aktivieren.
Nicht nur ist itoa
Da gcc fehlt, ist es nicht die praktischste Funktion, da Sie es mit einem Puffer füttern müssen. Ich brauchte etwas, das in einem Ausdruck verwendet werden konnte, also kam ich auf Folgendes:
std::string itos(int n)
{
const int max_size = std::numeric_limits<int>::digits10 + 1 /*sign*/ + 1 /*0-terminator*/;
char buffer[max_size] = {0};
sprintf(buffer, "%d", n);
return std::string(buffer);
}
Normalerweise wäre es sicherer zu verwenden snprintf
Anstatt von sprintf
Der Puffer ist jedoch sorgfältig dimensioniert, um gegen Überlaufen immun zu sein.
Siehe ein Beispiel: http://ideone.com/mKmZVE
Wie Matt J schrieb, gibt es itoa
, aber es ist kein Standard. Ihr Code wird portabler sein, wenn Sie verwenden snprintf
.
Die folgende Funktion weist gerade genug Speicher zu, um die Zeichenfolgendarstellung der angegebenen Zahl beizubehalten, und schreibt dann die Zeichenfolgendarstellung unter Verwendung von Standard in diesen Bereich sprintf
Methode.
char *itoa(long n)
{
int len = n==0 ? 1 : floor(log10l(labs(n)))+1;
if (n<0) len++; // room for negative sign '-'
char *buf = calloc(sizeof(char), len+1); // +1 for null
snprintf(buf, len+1, "%ld", n);
return buf;
}
Vergiss es nicht free
Allokierten Speicher erhöhen, wenn er nicht mehr benötigt wird:
char *num_str = itoa(123456789L);
// ...
free(num_str);
NB Da snprintf n-1 Bytes kopiert, müssen wir snprintf(buf, len+1, “%ld”, n) aufrufen (nicht nur snprintf(buf, len, “%ld”, n))
Wo ist die Itoa-Funktion in Linux?
Eine solche Funktion gibt es unter Linux nicht. Ich verwende stattdessen diesen Code.
/*
=============
itoa
Convert integer to string
PARAMS:
- value A 64-bit number to convert
- str Destination buffer; should be 66 characters long for radix2, 24 - radix8, 22 - radix10, 18 - radix16.
- radix Radix must be in range -36 .. 36. Negative values used for signed numbers.
=============
*/
char* itoa (unsigned long long value, char str[], int radix)
{
char buf [66];
char* dest = buf + sizeof(buf);
boolean sign = false;
if (value == 0) {
memcpy (str, "0", 2);
return str;
}
if (radix < 0) {
radix = -radix;
if ( (long long) value < 0) {
value = -value;
sign = true;
}
}
*--dest="\0";
switch (radix)
{
case 16:
while (value) {
* --dest="0" + (value & 0xF);
if (*dest > '9') *dest += 'A' - '9' - 1;
value >>= 4;
}
break;
case 10:
while (value) {
*--dest="0" + (value % 10);
value /= 10;
}
break;
case 8:
while (value) {
*--dest="0" + (value & 7);
value >>= 3;
}
break;
case 2:
while (value) {
*--dest="0" + (value & 1);
value >>= 1;
}
break;
default: // The slow version, but universal
while (value) {
*--dest="0" + (value % radix);
if (*dest > '9') *dest += 'A' - '9' - 1;
value /= radix;
}
break;
}
if (sign) *--dest="-";
memcpy (str, dest, buf +sizeof(buf) - dest);
return str;
}
-
Sie sollten Ihre Antwort bearbeiten, um zu erklären, wie dieser Code die Frage beantwortet.
– C. Helling
13. Oktober 2017 um 14:45 Uhr
-
Codefehler… negative Werte funktionieren nicht
– Calandoa
9. Dezember 2020 um 18:39 Uhr
-
Calandoa, können Sie genaue Werte (Wert, Radix) angeben, die nicht funktionieren?
– Rick-Rick-Rick
11. Dezember 2020 um 8:23 Uhr
-
@rick-rick-rick (vergiss das @ nicht, damit der Benutzer benachrichtigt wird!): positiver Radix und negativer Wert. Verwenden Sie übrigens kein negatives Radix oder machen Sie es richtig: en.wikipedia.org/wiki/Negative_base
– Calandoa
15. Dezember 2020 um 20:14 Uhr
irgendein Grund, es nicht zu verwenden
sprintf(str, "%d", num)
? ist es viel langsamer alsitoa
?– Oleg Waschnew
15. September 2014 um 18:53 Uhr
@javapowered, zum einen,
itoa
erlaubt beliebige Basenkonvertierung,printf
Spezifizierer nicht.– vladr
26. August 2016 um 15:35 Uhr
@javapowered sprintf() ist nicht signalsicher
– Lunesco
3. April 2019 um 15:28 Uhr
Irgendein Grund, es nicht zu verwenden
gcvt()
aus der Standardbibliothek?– C–
6. Mai 2019 um 10:13 Uhr
@C–, zum einen,
gcvt
ist nicht Teil des C-Standards und POSIX.1-2008 hat es auch aus POSIX entfernt.– Wurzelkea
6. April um 5:39 Uhr