itoa()ist eine sehr praktische Funktion, um eine Zahl in eine Zeichenfolge umzuwandeln. Linux scheint nicht zu haben itoa(), gibt es eine äquivalente Funktion oder muss ich verwenden sprintf(str, "%d", num)?
Gibt es einen Grund, nicht zu verwenden sprintf(str, "%d", num)? ist es viel langsamer als itoa?
Javapowered
1
@javapowered ermöglicht zum einen itoaeine beliebige Basiskonvertierung, printfSpezifizierer nicht.
Vladr
@javapowered sprintf () ist nicht signal sicher
lunesco
Gibt es einen Grund, nicht gcvt()aus der Standardbibliothek zu verwenden?
Subin Sebastian
Antworten:
100
EDIT: Sorry, ich hätte daran denken sollen, dass diese Maschine entschieden nicht dem Standard entspricht, da verschiedene nicht standardmäßige libcImplementierungen für akademische Zwecke angeschlossen wurden ;-)
Wie itoa()in der Tat nicht standardmäßig, wie von mehreren hilfreichen Kommentatoren erwähnt, ist es am besten, sprintf(target_string,"%d",source_int)oder zu verwenden (noch besser, weil es vor Pufferüberläufen sicher ist) snprintf(target_string, size_of_target_string_in_bytes, "%d", source_int). Ich weiß, dass es nicht ganz so prägnant oder cool ist wie itoa(), aber zumindest kannst du einmal schreiben, überall laufen (tm) ;-)
Hier ist die alte (bearbeitete) Antwort
Sie geben zu Recht an, dass die Standardeinstellung gcc libcnicht itoa()wie bei mehreren anderen Plattformen enthalten ist, da sie technisch nicht Teil des Standards ist. Sehen Sie hier für ein wenig mehr Informationen. Beachten Sie, dass Sie müssen
#include<stdlib.h>
Natürlich wissen Sie bereits , dies, weil man wollte verwendenitoa() unter Linux nach vermutlich mit ihm auf einer anderen Plattform, aber ... der Code (gestohlen aus dem Link oben) würde wie folgt aussehen:
Hmmm, wenn ich das auf Debian kompiliere, bekomme ich "einen undefinierten Verweis auf" itoa "". Vielleicht stimmt etwas mit meinem System nicht.
Adam Pierce
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
für die Richtigkeit bearbeitet, danke Jungs! Entschuldigung, ich vergesse immer, dass dies keine Vanille-Linux-Box ist ;-)
Matt J
Ich habe die Antwort so bearbeitet, dass sie das Argument für die Puffergröße enthält. Ich glaube, alles ist so, wie es jetzt sein sollte. Ich sehe kein Problem mit der Reihenfolge der Argumente an sich. Vermisse ich etwas
Matt J
Es funktioniert nicht für Linux? Was ist das Ergebnis der Frage / Antwort (Nicht-Standard scheint alle Linux zu sein?)
12
Wenn Sie es oft nennen, kann der Ratschlag "nur snprintf verwenden" ärgerlich sein. Also hier ist, was Sie wahrscheinlich wollen:
constchar*my_itoa_buf(char*buf,size_t len,int num){staticchar 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;}constchar*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 erraten, was die Funktion erhält?
Jcoder
Außerdem consttun Qualifizierer nichts für Funktionsrückgabetypen - Sie würden dies wissen, wenn Sie Compiler-Warnungen aktivieren würden :)
Katze
3
@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
1
@ Chortos-2 Das ist interessant, Sie haben natürlich völlig Recht - ich habe den semantischen Unterschied in der Bedeutung von constzwischen const int f (void) { ...und nicht erkannt const int* f (void) { ..., aber jetzt, nachdem ich es mit einem Compiler versucht habe, macht es Sinn.
Katze
11
itoaist keine Standard-C-Funktion. Sie können Ihre eigenen implementieren. Es erschien in der ersten Ausgabe von Kernighan und Ritchies The C Programming Language auf Seite 60. Die zweite Ausgabe von The C Programming Language ("K & R2") enthält die folgende Implementierung von itoaauf Seite 64. Das Buch stellt einige Probleme mit dieser Implementierung fest , einschließlich der Tatsache, dass die negativste Zahl nicht korrekt behandelt wird
/* 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 reverseoben verwendete Funktion wurde zwei Seiten zuvor 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;}}
Bearbeiten: Ich habe gerade herausgefunden, std::to_stringwelche 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 bereits ab 4.5, wenn Sie die c ++ 0x-Erweiterungen aktivieren.
Es itoafehlt nicht nur in gcc, es ist auch nicht die handlichste Funktion, die verwendet werden muss, da Sie ihm einen Puffer zuführen müssen. Ich brauchte etwas, das in einem Ausdruck verwendet werden konnte, also kam ich auf Folgendes:
Die folgende Funktion reserviert gerade genug Speicher, um die Zeichenfolgendarstellung der angegebenen Zahl beizubehalten, und schreibt dann die Zeichenfolgendarstellung mit der Standardmethode in diesen Bereich sprintf.
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;}
Vergessen Sie nicht, den freezugewiesenen Speicher zu erhöhen, wenn Sie ihn nicht benötigen:
Es ist keine gute Idee, Ihre Funktion aufzurufen, itoasondern sie anders zu verhalten als die gängigen Implementierungen itoa. Diese Funktion ist in Ordnung, aber nennen Sie sie etwas anderes :) Ich würde auch vorschlagen snprintf, die Pufferlänge anstelle der Gleitkommazeichenfolge zu berechnen. Gleitkomma kann Ungenauigkeiten im Eckfall aufweisen. Und nicht calloc
MM
Danke für Vorschläge.
mmdemirbas
Dies sollte verwendet werden, labswenn eine lange Ganzzahl benötigt wird. Sonst könnte es abschneiden.
Schwern
snprintfin einen tmp-Puffer fester Größe char buf[64], um dann die Länge zu erhalten mallocund in diesen zu kopieren. Sie profitieren nicht von callocOver malloc, da Sie alle Bytes schreiben. Das zusätzliche Kopieren einer sehr kurzen Zeichenfolge ist weniger schlecht als das Aufrufen des Gleitkomma-Protokolls10. Eine schnelle Annäherung mit einer Ganzzahl log2 kann jedoch hilfreich sein, wenn Sie eine Bit-Scan-Funktion haben, die zuverlässig zu etwas Effizientem (wie bsrbei x86) passt. (Alternative: mallocein 64-Byte-Puffer und dann, reallocnachdem Sie die endgültige Länge kennen.)
Peter Cordes
3
Wo ist die itoa-Funktion unter Linux?
Unter Linux gibt es keine solche Funktion. Ich benutze 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 (unsignedlonglong 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((longlong) value <0){
value =-value;
sign =true;}}*--dest ='\0';switch(radix){case16:while(value){*--dest ='0'+(value &0xF);if(*dest >'9')*dest +='A'-'9'-1;
value >>=4;}break;case10:while(value){*--dest ='0'+(value %10);
value /=10;}break;case8:while(value){*--dest ='0'+(value &7);
value >>=3;}break;case2:while(value){*--dest ='0'+(value &1);
value >>=1;}break;default:// The slow version, but universalwhile(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;}
direkte Kopie in den Puffer: 64-Bit-Ganzzahl itoa hex:
char* itoah(long num,char* s,int len){long n, m =16;int i =16+2;int shift ='a'-('9'+1);if(!s || len <1)return0;
n = num <0?-1:1;
n = n * num;
len = len > i ? i : len;
i = len < i ? len : i;
s[i-1]=0;
i--;if(!num){if(len <2)return&s[i];
s[i-1]='0';return&s[i-1];}while(i && n){
s[i-1]= n % m +'0';if(s[i-1]>'9')
s[i-1]+= shift ;
n = n/m;
i--;}if(num <0){if(i){
s[i-1]='-';
i--;}}return&s[i];}
Hinweis: Ändern Sie für 32-Bit-Computer long in long long. long to int für 32-Bit-Ganzzahlen. m ist der Radix. Erhöhen Sie beim Verringern des Radix die Anzahl der Zeichen (Variable i). Verringern Sie beim Erhöhen des Radix die Anzahl der Zeichen (besser). Im Falle eines vorzeichenlosen Datentyps wird i nur 16 + 1.
Hier ist eine stark verbesserte Version von Archanas Lösung. Es funktioniert für alle Radix 1-16 und Zahlen <= 0 und sollte den Speicher nicht überladen.
staticchar _numberSystem[]="0123456789ABCDEF";staticchar _twosComp[]="FEDCBA9876543210";staticvoid safestrrev(char*buffer,constint bufferSize,constint strlen){int len = strlen;if(len > bufferSize){
len = bufferSize;}for(int index =0; index <(len /2); index++){char ch = buffer[index];
buffer[index]= buffer[len - index -1];
buffer[len - index -1]= ch;}}staticint negateBuffer(char*buffer,constint bufferSize,constint strlen,constint radix){int len = strlen;if(len > bufferSize){
len = bufferSize;}if(radix ==10){if(len <(bufferSize -1)){
buffer[len++]='-';
buffer[len]='\0';}}else{int twosCompIndex =0;for(int index =0; index < len; index++){if((buffer[index]>='0')&&(buffer[index]<='9')){
twosCompIndex = buffer[index]-'0';}elseif((buffer[index]>='A')&&(buffer[index]<='F')){
twosCompIndex = buffer[index]-'A'+10;}elseif((buffer[index]>='a')&&(buffer[index]<='f')){
twosCompIndex = buffer[index]-'a'+10;}
twosCompIndex +=(16- radix);
buffer[index]= _twosComp[twosCompIndex];}if(len <(bufferSize -1)){
buffer[len++]= _numberSystem[radix -1];
buffer[len]=0;}}return len;}staticint twosNegation(constint x,constint radix){int n = x;if(x <0){if(radix ==10){
n =-x;}else{
n =~x;}}return n;}staticchar*safeitoa(constint x,char*buffer,constint bufferSize,constint radix){int strlen =0;int n = twosNegation(x, radix);int nuberSystemIndex =0;if(radix <=16){do{if(strlen <(bufferSize -1)){
nuberSystemIndex =(n % radix);
buffer[strlen++]= _numberSystem[nuberSystemIndex];
buffer[strlen]='\0';
n = n / radix;}else{break;}}while(n !=0);if(x <0){
strlen = negateBuffer(buffer, bufferSize, strlen, radix);}
safestrrev(buffer, bufferSize, strlen);return buffer;}return NULL;}
Wenn Sie den Code von Leuten lesen, die davon leben, werden Sie einen langen Weg finden.
Schauen Sie sich an, wie die Leute von MySQL das gemacht haben. Die Quelle ist SEHR GUT KOMMENTIERT und wird Ihnen viel mehr beibringen als gehackte Lösungen, die überall zu finden sind.
Ich stelle hier die erwähnte Implementierung zur Verfügung; Der Link dient als Referenz und sollte zum Lesen der vollständigen Implementierung verwendet werden.
char*
int2str(longint val,char*dst,int radix,int upcase){char buffer[65];char*p;longint new_val;char*dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower;
ulong uval=(ulong) val;if(radix <0){if(radix <-36|| radix >-2)returnNullS;if(val <0){*dst++='-';/* Avoid integer overflow in (-val) for LLONG_MIN (BUG#31799). */
uval =(ulong)0- uval;}
radix =-radix;}elseif(radix >36|| radix <2)returnNullS;/*
The slightly contorted code which follows is due to the fact that
few machines directly support unsigned long / and %. Certainly
the VAX C compiler generates a subroutine call. In the interests
of efficiency (hollow laugh) I let this happen for the first digit
only; after that "val" will be in range so that signed integer
division will do. Sorry 'bout that. CHECK THE CODE PRODUCED BY
YOUR C COMPILER. The first % and / should be unsigned, the second
% and / signed, but C compilers tend to be extraordinarily
sensitive to minor details of style. This works on a VAX, that's
all I claim for it.
*/
p =&buffer[sizeof(buffer)-1];*p ='\0';
new_val= uval /(ulong) radix;*--p = dig_vec[(uchar)(uval-(ulong) new_val*(ulong) radix)];
val = new_val;while(val !=0){ldiv_t res;
res=ldiv(val,radix);*--p = dig_vec[res.rem];
val= res.quot;}while((*dst++=*p++)!=0);return dst-1;}
Ein Link zu einer möglichen Lösung ist immer willkommen. Fügen Sie jedoch einen Kontext um den Link hinzu, damit Ihre Mitbenutzer eine Vorstellung davon haben, was es ist und warum es dort ist. Zitieren Sie immer den relevantesten Teil eines wichtigen Links, falls die Zielwebsite nicht erreichbar ist oder dauerhaft offline geht. Berücksichtigen Sie, dass kaum mehr als ein Link zu einer externen Website ein möglicher Grund dafür ist, warum und wie einige Antworten gelöscht werden. .
Tunaki
1
Was ist also so gut an dem Snippet, das du hier gepostet hast? Worauf sollten zukünftige Leser achten?
Martijn Pieters
1
Wo ist die itoa-Funktion unter Linux?
Wie itoa()es in C nicht Standard ist, existieren verschiedene Versionen mit verschiedenen Funktionssignaturen. char *itoa(int value, char *str, int base);ist in * nix üblich.
Sollte es unter Linux fehlen oder wenn Code die Portabilität nicht einschränken möchte, könnte Code es sich selbst machen.
Im Folgenden finden Sie eine Version, die keine Probleme mit INT_MINProblempuffern hat und diese behandelt: NULLoder eine unzureichende Pufferrückgabe NULL.
#include<stdlib.h>#include<limits.h>#include<string.h>// Buffer sized for a decimal string of a `signed int`, 28/93 > log10(2)#define SIGNED_PRINT_SIZE(object)((sizeof(object)* CHAR_BIT -1)*28/93+3)char*itoa_x(int number,char*dest,size_t dest_size){if(dest == NULL){return NULL;}char buf[SIGNED_PRINT_SIZE(number)];char*p =&buf[sizeof buf -1];// Work with negative absolute valueint neg_num = number <0? number :-number;// Form string*p ='\0';do{*--p =(char)('0'- neg_num %10);
neg_num /=10;}while(neg_num);if(number <0){*--p ='-';}// Copy stringsize_t src_size =(size_t)(&buf[sizeof buf]- p);if(src_size > dest_size){// Not enough roomreturn NULL;}return memcpy(dest, p, src_size);}
Unten finden Sie eine C99 oder neuere Version, die jede Basis handhabt [2 ... 36]
char*itoa_x(int number,char*dest,size_t dest_size,int base){if(dest == NULL || base <2|| base >36){return NULL;}char buf[sizeof number * CHAR_BIT +2];// worst case: itoa(INT_MIN,,,2)char*p =&buf[sizeof buf -1];// Work with negative absolute value to avoid UB of `abs(INT_MIN)`int neg_num = number <0? number :-number;// Form string*p ='\0';do{*--p ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-(neg_num % base)];
neg_num /= base;}while(neg_num);if(number <0){*--p ='-';}// Copy stringsize_t src_size =(size_t)(&buf[sizeof buf]- p);if(src_size > dest_size){// Not enough roomreturn NULL;}return memcpy(dest, p, src_size);}
Ersetzen Sie für einen C89- und weiter kompatiblen Code die innere Schleife durch
div_t qr;do{
qr = div(neg_num, base);*--p ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[-qr.rem];
neg_num = qr.quot;}while(neg_num);
Es sollte das schnellste itoa () aller Zeiten sein. Wir verwenden aus Leistungsgründen itoa () anstelle von sprintf (), daher ist ein schnellstes itoa () mit eingeschränkter Funktion sinnvoll und sinnvoll.
Es gibt so viele Fehler in diesem Code: 1) Konvertiert Hex nicht richtig. 2) Konvertiert überhaupt keine 0. 3) Funktioniert nicht mit negativen Zahlen. 4) Keine Überprüfung auf Pufferüberlauf. Ich werde in Kürze eine verbesserte Version dieses Codes veröffentlichen.
sprintf(str, "%d", num)
? ist es viel langsamer alsitoa
?itoa
eine beliebige Basiskonvertierung,printf
Spezifizierer nicht.gcvt()
aus der Standardbibliothek zu verwenden?Antworten:
EDIT: Sorry, ich hätte daran denken sollen, dass diese Maschine entschieden nicht dem Standard entspricht, da verschiedene nicht standardmäßige
libc
Implementierungen für akademische Zwecke angeschlossen wurden ;-)Wie
itoa()
in der Tat nicht standardmäßig, wie von mehreren hilfreichen Kommentatoren erwähnt, ist es am besten,sprintf(target_string,"%d",source_int)
oder zu verwenden (noch besser, weil es vor Pufferüberläufen sicher ist)snprintf(target_string, size_of_target_string_in_bytes, "%d", source_int)
. Ich weiß, dass es nicht ganz so prägnant oder cool ist wieitoa()
, aber zumindest kannst du einmal schreiben, überall laufen (tm) ;-)Hier ist die alte (bearbeitete) Antwort
Sie geben zu Recht an, dass die Standardeinstellung
gcc libc
nichtitoa()
wie bei mehreren anderen Plattformen enthalten ist, da sie technisch nicht Teil des Standards ist. Sehen Sie hier für ein wenig mehr Informationen. Beachten Sie, dass Sie müssenNatürlich wissen Sie bereits , dies, weil man wollte verwenden
itoa()
unter Linux nach vermutlich mit ihm auf einer anderen Plattform, aber ... der Code (gestohlen aus dem Link oben) würde wie folgt aussehen:Beispiel
Ausgabe:
Hoffe das hilft!
quelle
Wenn Sie es oft nennen, kann der Ratschlag "nur snprintf verwenden" ärgerlich sein. Also hier ist, was Sie wahrscheinlich wollen:
quelle
const
tun Qualifizierer nichts für Funktionsrückgabetypen - Sie würden dies wissen, wenn Sie Compiler-Warnungen aktivieren würden :)const char *
ist ein nicht konstanter Zeiger auf const, was sehr sinnvoll und korrekt ist.const
zwischenconst int f (void) { ...
und nicht erkanntconst int* f (void) { ...
, aber jetzt, nachdem ich es mit einem Compiler versucht habe, macht es Sinn.itoa
ist keine Standard-C-Funktion. Sie können Ihre eigenen implementieren. Es erschien in der ersten Ausgabe von Kernighan und Ritchies The C Programming Language auf Seite 60. Die zweite Ausgabe von The C Programming Language ("K & R2") enthält die folgende Implementierung vonitoa
auf Seite 64. Das Buch stellt einige Probleme mit dieser Implementierung fest , einschließlich der Tatsache, dass die negativste Zahl nicht korrekt behandelt wirdDie
reverse
oben verwendete Funktion wurde zwei Seiten zuvor implementiert:quelle
Bearbeiten: Ich habe gerade herausgefunden,
std::to_string
welche 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 bereits ab 4.5, wenn Sie die c ++ 0x-Erweiterungen aktivieren.Es
itoa
fehlt nicht nur in gcc, es ist auch nicht die handlichste Funktion, die verwendet werden muss, da Sie ihm einen Puffer zuführen müssen. Ich brauchte etwas, das in einem Ausdruck verwendet werden konnte, also kam ich auf Folgendes:Normalerweise wäre es sicherer,
snprintf
statt zu verwenden,sprintf
aber der Puffer ist sorgfältig dimensioniert, um immun gegen Überlaufen zu sein.Siehe ein Beispiel: http://ideone.com/mKmZVE
quelle
std::
Sachen usw. hatWie Matt J schrieb, gibt es
itoa
, aber es ist nicht Standard. Ihr Code ist portabler, wenn Sie ihn verwendensnprintf
.quelle
Die folgende Funktion reserviert gerade genug Speicher, um die Zeichenfolgendarstellung der angegebenen Zahl beizubehalten, und schreibt dann die Zeichenfolgendarstellung mit der Standardmethode in diesen Bereich
sprintf
.Vergessen Sie nicht, den
free
zugewiesenen Speicher zu erhöhen, wenn Sie ihn nicht benötigen:NB Wenn snprintf n-1 Bytes kopiert, müssen wir snprintf (buf, len + 1, "% ld", n) aufrufen (nicht nur snprintf (buf, len, "% ld", n)).
quelle
itoa
sondern sie anders zu verhalten als die gängigen Implementierungenitoa
. Diese Funktion ist in Ordnung, aber nennen Sie sie etwas anderes :) Ich würde auch vorschlagensnprintf
, die Pufferlänge anstelle der Gleitkommazeichenfolge zu berechnen. Gleitkomma kann Ungenauigkeiten im Eckfall aufweisen. Und nicht calloclabs
wenn eine lange Ganzzahl benötigt wird. Sonst könnte es abschneiden.snprintf
in einen tmp-Puffer fester Größechar buf[64]
, um dann die Länge zu erhaltenmalloc
und in diesen zu kopieren. Sie profitieren nicht voncalloc
Overmalloc
, da Sie alle Bytes schreiben. Das zusätzliche Kopieren einer sehr kurzen Zeichenfolge ist weniger schlecht als das Aufrufen des Gleitkomma-Protokolls10. Eine schnelle Annäherung mit einer Ganzzahl log2 kann jedoch hilfreich sein, wenn Sie eine Bit-Scan-Funktion haben, die zuverlässig zu etwas Effizientem (wiebsr
bei x86) passt. (Alternative:malloc
ein 64-Byte-Puffer und dann,realloc
nachdem Sie die endgültige Länge kennen.)Unter Linux gibt es keine solche Funktion. Ich benutze stattdessen diesen Code.
quelle
Ich habe meine eigene Implementierung von itoa () ausprobiert. Es scheint in Binär, Oktal, Dezimal und Hex zu funktionieren
quelle
direkte Kopie in den Puffer: 64-Bit-Ganzzahl itoa hex:
Hinweis: Ändern Sie für 32-Bit-Computer long in long long. long to int für 32-Bit-Ganzzahlen. m ist der Radix. Erhöhen Sie beim Verringern des Radix die Anzahl der Zeichen (Variable i). Verringern Sie beim Erhöhen des Radix die Anzahl der Zeichen (besser). Im Falle eines vorzeichenlosen Datentyps wird i nur 16 + 1.
quelle
Hier ist eine stark verbesserte Version von Archanas Lösung. Es funktioniert für alle Radix 1-16 und Zahlen <= 0 und sollte den Speicher nicht überladen.
quelle
Wenn Sie sie nur drucken möchten:
quelle
Wenn Sie den Code von Leuten lesen, die davon leben, werden Sie einen langen Weg finden.
Schauen Sie sich an, wie die Leute von MySQL das gemacht haben. Die Quelle ist SEHR GUT KOMMENTIERT und wird Ihnen viel mehr beibringen als gehackte Lösungen, die überall zu finden sind.
MySQLs Implementierung von int2str
Ich stelle hier die erwähnte Implementierung zur Verfügung; Der Link dient als Referenz und sollte zum Lesen der vollständigen Implementierung verwendet werden.
quelle
Wie
itoa()
es in C nicht Standard ist, existieren verschiedene Versionen mit verschiedenen Funktionssignaturen.char *itoa(int value, char *str, int base);
ist in * nix üblich.Sollte es unter Linux fehlen oder wenn Code die Portabilität nicht einschränken möchte, könnte Code es sich selbst machen.
Im Folgenden finden Sie eine Version, die keine Probleme mit
INT_MIN
Problempuffern hat und diese behandelt:NULL
oder eine unzureichende PufferrückgabeNULL
.Unten finden Sie eine C99 oder neuere Version, die jede Basis handhabt [2 ... 36]
Ersetzen Sie für einen C89- und weiter kompatiblen Code die innere Schleife durch
quelle
glibc interne Implementierung
glibc 2.28 hat eine interne Implementierung:
das wird an mehreren Stellen intern verwendet, aber ich konnte nicht finden, ob es belichtet werden kann oder wie.
Zumindest sollte dies eine robuste Implementierung sein, wenn Sie bereit sind, sie zu extrahieren.
In dieser Frage wird gefragt, wie Sie Ihre eigenen rollen: Wie konvertiere ich ein int in einen String in C?
quelle
Ich würde dies vorziehen: https://github.com/wsq003/itoa_for_linux
Es sollte das schnellste itoa () aller Zeiten sein. Wir verwenden aus Leistungsgründen itoa () anstelle von sprintf (), daher ist ein schnellstes itoa () mit eingeschränkter Funktion sinnvoll und sinnvoll.
quelle
Ich habe _itoa (...) auf RedHat 6 und GCC Compiler verwendet. Es klappt.
quelle
Der Ersatz durch snprintf ist NICHT vollständig!
Es werden nur Basen abgedeckt: 2, 8, 10, 16, während itoa für Basen zwischen 2 und 36 funktioniert.
Da ich nach einem Ersatz für Base 32 gesucht habe, muss ich wohl meinen eigenen codieren!
quelle
Sie können dieses Programm anstelle von sprintf verwenden.
quelle