[CPP] Integer in String umwandeln, die schwere Methode

Übersicht Sonstiges Smalltalk

Neue Antwort erstellen

Xaymar

ehemals "Cgamer"

Betreff: [CPP] Integer in String umwandeln, die schwere Methode

BeitragFr, Okt 22, 2010 20:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Zuerst mal, das hier hat nichts mit BB zu tun, sondern C++(Wie man aus dem Titel ja vermuten kann).
Seit tagen frage ich mich wo der fehler liegt. debugger kann mir nichts sagen, compiler gibt auch keine warnmeldung.

Code: [AUSKLAPPEN]
      UniString& operator+=(const UniString& String) {
         //if (this == &String) {return *this;}
         uInt32 newLen = uLen+String.uLen;
         uInt16* newData = (uInt16*)malloc(newLen+2);
         
         for (uInt32 i = 1; i <= uLen; i++)
            newData[i] = uData[i];
         for (uInt32 i = 1; i <= String.uLen; i++)
            newData[i+uLen-1] = String.uData[i]; //<-- ERROR IS HERE
         
         free((void*)uData);
         uData = newData;
         uLen = newLen;
         return *this;
      }

Kommentiere ich die markierte Zeile mit der for schleife aus, funktioniert der Test code einwandfrei:
Code: [AUSKLAPPEN]
   //Testing Unistring
    std::stringstream stuff;
   
    uString MyString = "Hello World";
    stuff<<"MyString Length: "<<MyString.GetLength()<<"@"<<MyString.GetAnsi()<<std::endl;
    MessageBoxA(0,stuff.str().c_str(),"t",0);
   
    uString MyWString = L"Hello Unicode World";
    stuff<<"MyWString Length: "<<MyWString.GetLength()<<"@"<<MyWString.GetAnsi()<<std::endl;
    MessageBoxA(0,stuff.str().c_str(),"t",0);
   
    uString MyAString = MyString+MyWString;//Crashes here for some reason.
    stuff<<"MyAString Length: "<<MyAString.GetLength()<<"@"<<MyAString.GetAnsi()<<std::endl;
    MessageBoxA(0,stuff.str().c_str(),"t",0);
   
    uString MyMString = MyString*4;
    stuff<<"MyMString Length: "<<MyMString.GetLength()<<"@"<<MyMString.GetAnsi()<<std::endl;
    MessageBoxA(0,stuff.str().c_str(),"t",0);


Jetzt die frage an die c++'ler da draußen: woran liegts?
Warbseite
  • Zuletzt bearbeitet von Xaymar am Mo, Okt 25, 2010 13:51, insgesamt einmal bearbeitet
 

Macintosh

BeitragFr, Okt 22, 2010 20:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Bin nur C'ler, verstehe von C++ nichts, aber vieleicht wird i ja einfach zu groß?
Was sagt denn dein Compiler?

mach doch testweise aus dem <= ein <

Code: [AUSKLAPPEN]

newData[i+uLen-1] = String.uData[i]; //<-- ERROR IS HERE - > i zu groß?

Xaymar

ehemals "Cgamer"

BeitragFr, Okt 22, 2010 21:00
Antworten mit Zitat
Benutzer-Profile anzeigen
nichts.
Aber ich hoffe das ich den fehler gefunden habe. wenn ja, dann verlasse ich mich nicht mehr aufs tutorial >Sad
Warbseite
 

Macintosh

BeitragFr, Okt 22, 2010 21:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Irgendwas muss er doch sagen, oder es steht doch sicher was in der konsole.

Xaymar

ehemals "Cgamer"

BeitragFr, Okt 22, 2010 21:17
Antworten mit Zitat
Benutzer-Profile anzeigen
meh, habs gefunden. Laut tutorial macht malloc das multiplizieren selbst wenn man da nen (type*) voranhängt.
Warbseite

Xaymar

ehemals "Cgamer"

BeitragMo, Okt 25, 2010 14:04
Antworten mit Zitat
Benutzer-Profile anzeigen
So nun habe ich ein neues Problem: Ich möchte einen integer in einen String umwandeln.
Bin bereits mit itoa/atoa und der stringstream methode vertraut. Allerdings halte ich die für langsamer, als wenn das die Klasse selbst kann.

Bei stringstream gibt es eine verlinkung über viele dateien wo irgendwann vielleicht mal die implementation kommt(bin da noch nicht angekommen).
itoa/atoa sind verlinkungen auf eine DLL o.ä.
Wie genau geht das? Und ja, ich meine das ernst. Es macht mir auch nichts aus ein paar seiten lange dokumente zu lesen die das Thema befassen. Gegoogelt habe ich, 90% stringstream 10% itoa/atoa.
Warbseite

Thunder

BeitragMo, Okt 25, 2010 14:09
Antworten mit Zitat
Benutzer-Profile anzeigen
sprintf sollte das können: http://www.cplusplus.com/refer...o/sprintf/
Aber deine Frage habe ich nicht verstanden, nämlich worauf sich das "wie geht das?" bezieht.

mfg Thunder
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

Noobody

BeitragMo, Okt 25, 2010 14:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Hast du wirklich gesucht? Wenn ich nach "itoa implementation" suche, finde ich haufenweise Links Razz

Der hier zum Beispiel vergleicht mehrere verschiedene Varianten miteinander. Im Prinzip aber funktionieren sie alle gleich: Solange die Zahl nicht Null ist, wird Zahl Modulo Basis an den String angehängt und die Zahl durch die Basis dividiert. Dann noch das Vorzeichen anhängen (falls nötig), den String umdrehen und man ist fertig.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

Xaymar

ehemals "Cgamer"

BeitragMo, Okt 25, 2010 15:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Meine Suchanfragen beinhalten nicht "itoa implementation", sondern "integer zu string umwandeln".

Geht dieselbe methode auch mit floats?

@hamZta: Genau DAS habe ich erwartet als antwort. Vielen Dank für keine Hilfe.
  • Zuletzt bearbeitet von Xaymar am Mo, Okt 25, 2010 19:09, insgesamt einmal bearbeitet

hamZta

Administrator

BeitragMo, Okt 25, 2010 16:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Wieso verwendest du nicht ein die Stringstream-Klasse von C++? Einfach einen Integer reinjagen und dann in einen String schreiben (zB mit der Method stringstream::str()).

itoa bzw. atoi basieren beide auf der Verwendung von char arrays. Willst du jedoch mit C++-Strings arbeiten empfehle ich dir, auch die geeigneten C++-Werkzeuge zu verwenden.
Blog.
 

Macintosh

BeitragMo, Okt 25, 2010 19:18
Antworten mit Zitat
Benutzer-Profile anzeigen
integer zu string, in C, mal schnell und dreckig ^^

n integer
b basis
str das char-array
Code: [AUSKLAPPEN]
void itos(int n, int b, char str[])
{

   int i, sign;
   i = sign = 0;
   if (n < 0) {
      sign = 1;
      n = -n;
   }
   while (i < 32 && n != 0) {
      str[i++] = (n % b) + '0';
      n /= b;
   }
   if (sign)
      str[i++] = '-';
   str[i] = '\0';
   //reverse
   int x, y;
   for (x = 0, y = strlen(str)-1; x < y; x++, y--) {
      int t = str[x];
      str[x] = str[y];
      str[y] = t;
   }

}

Thunder

BeitragMo, Okt 25, 2010 19:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für den Link Noobody. Da kann man sich echt was abschauen.
Ich hab das für meinen Kernel immer etwa so gelöst:

Code: [AUSKLAPPEN]
#define FORMEL ((y % (x*10))/x)

//funktioniert nicht für große Zahlen, muss dafür aber den String nicht umkehren.
void itoa2(int y,char *s){
    int x,zif=0;
    if(y<0){
        *s++='-'; y=-y;
    }
    for(x=1000000000;x>=1;x/=10){
        if(zif!=0 || FORMEL!=0){
            *s++='0' + FORMEL;
            zif=1;
        }
    }
    if(!zif) *s++='0';
    *s++=0;
}

#undef FORMEL


Edit: Für den Kernel war die Basis irrelevant. Ich habe noch eine zweite Funktion für die Basis 16. Dürfte schneller sein.
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit
  • Zuletzt bearbeitet von Thunder am Mo, Okt 25, 2010 20:10, insgesamt einmal bearbeitet
 

Macintosh

BeitragMo, Okt 25, 2010 19:53
Antworten mit Zitat
Benutzer-Profile anzeigen
bei deinem kann man aber nicht die basis übergeben.
noch ne verbesserte version, für hex ausgabe:
Code: [AUSKLAPPEN]

void itoa(int n, int b, char str[])
{
   int i, sign;
   i = sign = 0;
   if (n < 0) {
      sign = 1;
      n = -n;
   }
   while (i < 32 && n > 0) {
      str[i++] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n % b];
      n /= b;
   }
   if (sign)
      str[i++] = '-';
   str[i] = '\0';
   //reverse
   int x, y;
   for (x = 0, y = strlen(str)-1; x < y; x++, y--) {
      int t = str[x];
      str[x] = str[y];
      str[y] = t;
   }
}
 

GERMAX

BeitragMo, Okt 25, 2010 22:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Gegeben sei eine vz(int16).

zb: 1000 1100 0000 1111

bit 15=1--->32768
bit 11=1---> 2048
bit 10=1---> 1024
bit 3=1---> 8
bit 2=1---> 4
bit 1=1---> 2
bit 0=1---> 1
-----------------------
Die Zahlen kann man ja in eine Tab packen oder generieren. Smile
Jetzt braucht man nur noch addieren. Soll heissen:

1. Stelle:35--->5 und die $30 (wieder) mit Or draufpacken---> 35h.
2. Stelle:12+3(Ov) =15--->5 dto 35h.
3. Stelle: 7+1 (Ov) =8 38h
4. Stelle:5 35h
5. Stelle:3 33h
---------------->35855

Das sieht wie ASS aus und soll auch so sein - aber sowas sollte man in einem C-Gedöhns auch machen können. In einer Hochsprache kann man dann sowieso nie so genau sehen, was da für code entsteht.
Und so langsam ist meine Methode glaub ich gar nicht.
Erfolglos begonnene BB-Projekte:TRON/CONVOY/MYSTIC
 

GERMAX

BeitragDi, Okt 26, 2010 21:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Nachdem ich mal in meinem schlauen Assembler-Buch nachgeguckt habe, ist dabei folgende Methode rausgekommen:


Die int(zahl) einfach solange durch 10 teilen, bis das Divergebnis=0 ist. Bei jeder div muß dann der Divrest mit 30h geort werden und in den Speicher geschrieben werden. Der Code ist dabei ziemlich compakt und höchstens durch spezielle cpu-befehle noch zu verbessern (evtl durch FILD/FBSTP-aber FBSTP erzeugt nur gepackte Dezimalzahlen, die müsste man noch in einen ASCii-Str umwandeln).

Das gute an der div-Methode ist, dass man das in c(bla..) so hinbringen kann, dass beim kompilieren in etwa der Maschinencode erzeugt wird-und effiz. geht es nunmal kaum.
Erfolglos begonnene BB-Projekte:TRON/CONVOY/MYSTIC

Neue Antwort erstellen


Übersicht Sonstiges Smalltalk

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group