itoa selber basteln?
-
Hi,
ich habe im Netz diesen Source gefunden, jedoch naja... bissel groß für eine itoa-Funktion
Gibt es eine Kürzere Variante?
char * itoa(int value, char *string, int radix) { char tmp[33]; char *tp = tmp; int i; unsigned v; int sign; char *sp; if (radix > 36 || radix <= 1) { __set_errno(EDOM); return 0; } sign = (radix == 10 && value < 0); if (sign) v = -value; else v = (unsigned)value; while (v || tp == tmp) { i = v % radix; v = v / radix; if (i < 10) *tp++ = i+'0'; else *tp++ = i + 'a' - 10; } if (string == 0) string = (char *)malloc((tp-tmp)+sign+1); sp = string; if (sign) *sp++ = '-'; while (tp > tmp) *sp++ = *--tp; *sp = 0; return string; }
-
Hier eine nette, kleine Alround-Cast Funktion (bei den meisten unter lexika_cast bekannt). Sie wandelt jeden streambaren Typ in jeden anderen um:
#include <iostream> #include <sstream> #include <stdlib.h> #include <stdio.h> template<typename DestType, typename SourceType> DestType cast2(SourceType &source) { stringstream s; s << source; DestType dest; s >> dest; return dest; }
Anwendungsbeispiel:
int a = 10; string b; b = cast2<string>(a); cout<<b<<endl;
Die Funktion muss übrigens höchstwahrscheinlich gleich im Header implementiert werden.
Greetz,
Neo
-
och nee, wollte ohne die STL auskommen, die bläht mein Programm immer so derbe auf und nur für int2string sehe ich das nicht ein.
-
Der ITOA-Freund schrieb:
ich habe im Netz diesen Source gefunden, jedoch naja... bissel groß für eine itoa-Funktion
Gibt es eine Kürzere Variante?
Kürzer? Naja, vermutlich nicht viel. Es gibt aber sicherlich saubere, sinnvollere und effektivere Implementationen, einen Ganzzahlwert in einen String umzuwandeln. Man muss ja nicht unbedingt eine Funktion bauen, die exakt die Anforderungen einer itoa Funktion erfüllt.
-
groovemaster schrieb:
Der ITOA-Freund schrieb:
ich habe im Netz diesen Source gefunden, jedoch naja... bissel groß für eine itoa-Funktion
Gibt es eine Kürzere Variante?
Kürzer? Naja, vermutlich nicht viel.
Doch, zumindest für positive Zahlen
char *tostring (unsigned long x) { static char result[32]; int s = 31; while (x) { result[s--] = x%10 + '0'; x /= 10; } return &result[s+1]; }
-
Auch für neagtive Zahlen
char *tostring (long x) { static char result[32]; int s = 31; int sign = x < 0; if (sign) x = -x; while (x) { result[s--] = x%10 + '0'; x /= 10; } if (sign) result[s--] = '-'; return &result[s+1]; }
-
Abkürzer schrieb:
Doch, zumindest für positive Zahlen
Wie dir vielleicht entgangen ist, ist die itoa Funktion nicht auf unsigned ausgerichtet.
Ausserdem hab ich das Gefühl, dass du nur dezimale Zahlen kennst. Wo ist denn deine variable Basis (radix)?btw:
Schon mal was von bool gehört?
-
groovemaster schrieb:
Wie dir vielleicht entgangen ist, ist die itoa Funktion nicht auf unsigned ausgerichtet.
Ausserdem hab ich das Gefühl, dass du nur dezimale Zahlen kennst. Wo ist denn deine variable Basis (radix)?So besser?
char *tostring (long x, int radix) { static char result[256]; int s = sizeof(result) - 1; int sign = x < 0; if (sign) x = -x; for (; x; s--, x /= radix) if ((result[s] = x%radix + '0') > '9') result[s] += 7; if (sign) result[s--] = '-'; return &result[s+1]; }
groovemaster schrieb:
btw:
Schon mal was von bool gehört?
Ja, aber das braucht kein Schwein.
-
Abkürzer schrieb:
So besser?
char *tostring (long x, int radix) { static char result[256]; int s = sizeof(result) - 1; int sign = x < 0; if (sign) x = -x; for (; x; s--, x /= radix) if ((result[s] = x%radix + '0') > '9') result[s] += 7; if (sign) result[s--] = '-'; return &result[s+1]; }
Trotzdem noch lange nicht zum Original funktionsäquivalent.
Wie gesagt, du kannst die Funktion nicht wirklich kürzer machen. Dann musst du schon funktionell Änderungen machen. Das kann Der ITOA-Freund aber nur selbst wissen, was er möchte. Sicherlich kann man mit diversen Änderungen weniger Codezeilen bekommen, zB stattif (i < 10) *tp++ = i+'0'; else *tp++ = i + 'a' - 10;
einfach
if (i < 10) *tp++ = i+'0'; else *tp++ = i + 'a' - 10;
schreiben, uä. Nur ist das einfach 'ne Geschmacksfrage bzw eine Frage der Lesbarkeit. Lieber etwas mehr geschrieben und dafür lesbar und verständlich, als obfuscated Code. Und dein Code ist wenig lesbar, imo.
Abkürzer schrieb:
groovemaster schrieb:
btw:
Schon mal was von bool gehört?
Ja, aber das braucht kein Schwein.
Du musst es ja wissen.
-
groovemaster schrieb:
Trotzdem noch lange nicht zum Original funktionsäquivalent.
Wieso nicht?
groovemaster schrieb:
Abkürzer schrieb:
groovemaster schrieb:
btw:
Schon mal was von bool gehört?
Ja, aber das braucht kein Schwein.
Du musst es ja wissen.
bool ist ein schlechter Witz. Die Variablen werden so groß wie ints.
-
Abkürzer schrieb:
bool ist ein schlechter Witz. Die Variablen werden so groß wie ints.
Auf welchem Compiler hast du dieses Verhalten festgestellt? Bei den Compilern die ich kenne ist ein bool ein Byte groß und damit kleiner als ein int.
-
also ich bin mir nicht sicher inwieweit es stimmt,
aber es kann vorkommen das der compiler gewisse sachen aufbläht um in das 4byte-"schema" zu passen, da der cpu am besten mit 32bit umgehn kann....das da oben kann jetzt auch völliger schwachsinn sein ich mach mich da jetzt mal nich fest, aber ich hab sowas in der art düster im hinterkopf..
-
HumeSikkins schrieb:
Abkürzer schrieb:
bool ist ein schlechter Witz. Die Variablen werden so groß wie ints.
Auf welchem Compiler hast du dieses Verhalten festgestellt? Bei den Compilern die ich kenne ist ein bool ein Byte groß und damit kleiner als ein int.
Ja, stimmt. Ich habe mich getäuscht, aber ein ganzes Byte für zwei Zustände zu verbrauchen ist auch nicht schön.
-
Ach und deswegen ist int besser geeignet?
Der Grund wieso es bool gibt hat aber aus ganz anderen Gründen.
Der erste Grund ist, dass man ohne Cast Pointers zuweisen kann. Beispiel
typedef int BOOL; const BOOL TRUE = 1; const BOOL FALSE = 0; //... int *a = foo(); bool b = a; //ok BOOL c = (BOOL)a; //Cast wird gebraucht
Bei int gibt es ein Zustand der Falsch darstellt und alle anderen stellen Wahr dar. Bei bool gibt es immer nur 2 Zustände. Na zweites Problem schon erkannt? Wenn nicht dann schau mal her
typedef int BOOL; const BOOL TRUE = 1; const BOOL FALSE = 0; //... int*a = foo(); //foo gibt nicht NULL zurück BOOL b = (BOOL)a; if(b == TRUE) //Ausdruck ist falsch muss heißen if(b != FALSE) {/*...*/} bool c = a; if(c == true) //ok {/*...*/}
Im Vergleich zu bool ist BOOL nur ein typedef für ein int. Das heist du kannst Schablonen für bool spezialisiren aber nicht für BOOL.
Ich glaub das sollte reichen um bools Überlegenheit zu zeigen.
-
Irgendwer schrieb:
typedef int BOOL; const BOOL TRUE = 1; const BOOL FALSE = 0; //... int*a = foo(); //foo gibt nicht NULL zurück BOOL b = (BOOL)a; if(b == TRUE) //Ausdruck ist falsch muss heißen if(b != FALSE) {/*...*/}
Du mu0t das schon richtig machen
#define TRUE 1 #define FALSE 0 #define BOOL(x) (!(!(x))) //... int*a = foo(); //foo gibt nicht NULL zurück if(BOOL(b) == TRUE) //Kein Problem {/*...*/}
-
Und du findest es nicht etwas schwachsinnig einen BOOL in einen BOOL casten zu müssen um ein richtiges Ergebnis zu bekommen? o_O"
-
Angenommen ich habe ein Spiel mit verschiedenen States, die jeweils eine update() und eine draw() Methode haben.
Es gibt nun ne Variable "currentState", die eine Instanz des aktuellen States enthält.
In der Mainloop wird nun zunächst die update() Methode, dann die draw() Methode aufgerufen.Nun wird ja auch zwischen den States gewechselt. Fändet ihr es nun besser, wenn die update() Methode einen Pointer auf die Instanz des nächsten States zurückliefert (bzw this wenn keine Änderung vorgenommen werden soll), oder wenn die Methode einen Wert zurückliefert, der angibt in welchen State gewechselt werden soll und dies dann in einer switch-case Konstruktion geprüft wird.
-
Sorry, bitte Frage in eigenen Thread verschieben! Danke
-
Abkürzer schrieb:
groovemaster schrieb:
Trotzdem noch lange nicht zum Original funktionsäquivalent.
Wieso nicht?
Du überprüfst den Wertebereich von radix nicht. Dh mit 0 für radix könnte man bei dir problemlos undefiniertes Verhalten hervorrufen.
Im Origianlcode wird nur bei dezimaler Umwandlung das Vorzeichen beachtet.
Sollte der Zielpuffer im Origianlcode ein Nullzeiger sein, wird dynamisch in der Funktion Speicher reserviert. Find ich persönlich abartig, aber wenn der Autor es so will.
Abkürzer schrieb:
bool ist ein schlechter Witz. Die Variablen werden so groß wie ints.
Der Standard sieht das aber nicht so
, was den Compilern natürlich eine gewisse Freiheit gibt.
C++ Standard schrieb:
in particular, sizeof(bool) and sizeof(wchar_t) are implementationdefined.
Abkürzer schrieb:
aber ein ganzes Byte für zwei Zustände zu verbrauchen ist auch nicht schön
Genau deshalb gibt es ja bool. Den Standard interessiert der Speicherverbrauch herzlich wenig. Der sagt nur, dass es ein Typ ist, der zwei Zustände hat, false oder true. Dass herkömmliche x86 CPUs keine Bitregister haben, ist doch nicht die Schuld des C++ Typsystems. Und dass man gerade mit einem eigenen Typ auch speicherrelevant optimieren kann, zeigt vector<bool>. Was würdest du denn machen, wenn bool einfach nur ein typedef auf int wäre?
-
Gibt es nun eine gute itoa lösung?