Die RICHTIGE Art zu konvertieren



  • Swordfish schrieb:

    Swordfish schrieb:

    Zustand (dein m_stStringBuffer *)) sollten beide [Funktionen] keinen haben [...]

    Printe schrieb:

    std::string ist char* in jeder Hinsicht überlegen. Wenn du trotzdem mit char* arbeiten willst, solltest du dafür extrem gute Gründe haben.

    SeppJ schrieb:

    warum keine Strings?

    😉 jetzt wird es mit m_... noch enger, denn Namespaces sind keine Klassen oder Structs, von denen es Instanzen geben könnte. Dein m_stStringBuffer ist eher ein g(lobal)_sonstwas .

    Achso, ja das war ein Typo.. habs einfach aus meiner Klasse kopiert.



  • Lass diesen ganzen Unsinn weg.
    Ganz genau das, was du da machst, gibt es schon. Du verwendest es ja sogar in deiner Funktion.
    Du sorgst nur noch einmal dafür, dass es langsamer wird - etwas, was du doch eigentlich nicht willst, oder?

    Verwende std::to_string() und std::stoi(). Das ist genau das, was du suchst.
    Weder mehr noch weniger.

    Irgendwie habe ich bei dir auch definitiv das Gefühl, dass da einige (bis viele) dringend benötigte Grundlagen fehlen...



  • me_and_cpp schrieb:

    Lass diesen ganzen Unsinn weg.
    Ganz genau das, was du da machst, gibt es schon. Du verwendest es ja sogar in deiner Funktion.
    Du sorgst nur noch einmal dafür, dass es langsamer wird - etwas, was du doch eigentlich nicht willst, oder?

    Verwende std::to_string() und std::stoi(). Das ist genau das, was du suchst.
    Weder mehr noch weniger.

    Irgendwie habe ich bei dir auch definitiv das Gefühl, dass da einige (bis viele) dringend benötigte Grundlagen fehlen...

    Ich habe mein letztes Projekt ganz normal mit strings gemacht.
    Ich verwende char weil ich bis jetzt nie richtig damit gearbeitet habe.

    P.S. Ich habe wieder ein Problem.
    Beim Einbinden meiner namespace hpp gibt es folgenden Fehler.. (erstmal code):

    #ifndef NConvert_HPP
    #define NConvert_HPP
    
    #include <string>
    
    namespace Convert 
    {
    	// string buffer
    	std::string stStringBuffer;
    
    	// char to int 
    	int CharToInt(const char *p_szChar);
    
    	// int to char
    	const char* IntToChar(int p_nInt);
    }
    
    #endif
    
    #include "NConvert.hpp"
    
    namespace Convert
    {
    	int CharToInt(const char *p_szChar)
    	{
    		return std::stoi(p_szChar);
    	}
    
    	const char* IntToChar(int p_nInt)
    	{
    		stStringBuffer = std::to_string(p_nInt);
    
    		return stStringBuffer.c_str();
    	}
    }
    

    Fehler LNK2005 "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > Convert::stStringBuffer" (?stStringBuffer@Convert@@3V?basic_string@DU?basic\_string@DU?char_traits@D@std@@V?$allocator@D@2@@std@@A) ist bereits in NConvert.obj definiert.

    Fehler LNK1169 Mindestens ein mehrfach definiertes Symbol gefunden.



  • Bizarreofnature schrieb:

    Ich habe mein letztes Projekt ganz normal mit strings gemacht.
    Ich verwende char weil ich bis jetzt nie richtig damit gearbeitet habe.

    Und so wie du es jetzt mit C-Strings (so nennt man das, wozu du char sagst) machst, ist es nicht Fisch und nicht Fleisch, denn wenn schon C-Strings, dann übergibt man solchen Funktionen in der Regel einen Buffer und dessen Größe und lässt die Funktion den bereitgestellten Buffer befüllen. So, wie es auch std::itoa() macht.

    me_and_cpp schrieb:

    Irgendwie habe ich bei dir auch definitiv das Gefühl, dass da einige (bis viele) dringend benötigte Grundlagen fehlen...

    +1



  • Hab den Bug gefunden. Danke trotzdem 🙂



  • *kopfschüttel*



  • Swordfish schrieb:

    *kopfschüttel*

    Was soll ich sagen? Kann sein dass vieles fehlt.
    Ich arbeite ja dran. Ich habe bis auf die letzten 2 Projekte etwa 7 Jahre nicht mehr programmiert.



  • Swordfish schrieb:

    Bizarreofnature schrieb:

    Ich habe mein letztes Projekt ganz normal mit strings gemacht.
    Ich verwende char weil ich bis jetzt nie richtig damit gearbeitet habe.

    Und so wie du es jetzt mit C-Strings (so nennt man das, wozu du char sagst) machst, ist es nicht Fisch und nicht Fleisch, denn wenn schon C-Strings, dann übergibt man solchen Funktionen in der Regel einen Buffer und dessen Größe und lässt die Funktion den bereitgestellten Buffer befüllen. So, wie es auch std::itoa() macht.

    Da hast du natürlich recht. Ich schätze ich änder das. Aber morgen. Zu müde.



  • Bizarreofnature schrieb:

    Ich habe mein letztes Projekt ganz normal mit strings gemacht.
    Ich verwende char weil ich bis jetzt nie richtig damit gearbeitet habe.

    Nein! Schlechte Idee! Bleib bei string! Du verpasst absolut nichts!

    Tu dir bitte den Gefallen und geh dein Projekt von vorne bis hinten durch, und zwar jetzt, solange es noch eine übersichtliche Größe hat. Schmeiß alle Vorkommen von char*, char[] und ähnlichem raus und setz std::string dafür ein.



  • Printe schrieb:

    Bizarreofnature schrieb:

    Ich habe mein letztes Projekt ganz normal mit strings gemacht.
    Ich verwende char weil ich bis jetzt nie richtig damit gearbeitet habe.

    Nein! Schlechte Idee! Bleib bei string! Du verpasst absolut nichts!

    Tu dir bitte den Gefallen und geh dein Projekt von vorne bis hinten durch, und zwar jetzt, solange es noch eine übersichtliche Größe hat. Schmeiß alle Vorkommen von char*, char[] und ähnlichem raus und setz std::string dafür ein.

    👍



  • me_and_cpp schrieb:

    Verwende std::to_string() und std::stoi(). Das ist genau das, was du suchst.
    Weder mehr noch weniger.

    👍



  • Während std::to_string bei mir häufig im Einsatz ist, war interessanterweise stoi noch nie das, was ich gebraucht habe. Ich finde diese Funktion auch reichlich nutzlos. Der angebliche Vorteil gegenüber atoi ist ja Fehlerkontrolle. Nur funktioniert die bei stoi nur "von links". stoi("1dudum") gibt mir zum Beispiel 1 aus, wobei "1dudum" bestimmt keine Zahl ist. Wenn man es also mit Nutzereingaben zu tun hat, kann man diese Funktion genausowenig wie atoi benutzen, weil man eben Fehleingaben nicht zuverlässig erkennen kann. Problematisch ist das z.B., wenn der Benutzer "1.5" oder "1e4" eingibt und somit offensichtlich (für Menschen) was anderes als 1 meint. Mit boost::lexical_cast<int> ist dieses Problem dann z.B. behoben. Und sobald ich solche Benutzereingaben habe, ist die Effizienz dieser Umwandlung auch ziemlich egal.

    Aber im hier vorliegenden Fall ist ja sowieso immer noch unklar, wozu diese Konvertierung überhaupt benötigt wird.



  • TE:
    Ich habe hier eine Dose Ravioli und habe Probleme, sie aufzumachen. Kann mir jemand helfen?

    Forum:
    Was hast du denn bisher versucht?

    TE:
    Also, ich habe hier einen Hammer. Aber jedes Mal, wenn ich damit auf die Dose haue geht sie zwar auf, aber die Tomatensauce spritzt überall herum.

    Forum:
    Argh, nein, wirf den Hammer weg und benutz´ nen Dosenöffner!

    TE:
    Aber ich möchte gern den Hammer benutzen, weil noch nie etwas mit einem Hammer gemacht habe.

    Forum:
    Nein, der Hammer ist dazu nicht geeignet! Nimm nen Dosenöffner!

    TE:
    Alles, klar, mach ich!

    TE:
    So, ich habe jetzt eine Schneide an den Hammer gebastelt, aber irgendwie funktioniert das nicht richtg. Kann mir jemand helfen?

    Forum:
    ...



  • wob schrieb:

    ... stoi("1dudum") gibt mir zum Beispiel 1 aus, wobei "1dudum" bestimmt keine Zahl ist. Wenn man es also mit Nutzereingaben zu tun hat, kann man diese Funktion genausowenig ...

    Wieso? Genau dafür hat die Funktion den zweiten Parameter (idx), der wird dann nämlich auf die Position des ersten 'd' gesetzt.

    Wenn du nach Ausführung von

    std::string s = "1dudum";
    std::size_t idx;
    int n = std::stoi (s, &idx, 10);
    

    idx mit s.size() vergleichst und das stimmt nicht überein, dann weißt du, dass nicht der ganze String umgewandelt werden konnte und wo die Umwandlung abgebrochen wurde.

    Problematisch ist das z.B., wenn der Benutzer "1.5" oder "1e4" eingibt und somit offensichtlich (für Menschen) was anderes als 1 meint.

    Wieso ist das problematisch? Das machst du genau wie oben und brüllst den Benutzer anschließend an "das ist keine Ganzzahl, du Armleuchter!".
    Oder du erwartest Kommazahlen, dann benutzt du stof.



  • Printe schrieb:

    Wieso? Genau dafür hat die Funktion den zweiten Parameter (idx), der wird dann nämlich auf die Position des ersten 'd' gesetzt.

    Ok, da hast du recht und ich vergesse immer wieder, dass es diesem Parameter gibt. Meine Schuld. Nur warum wird dann bei einem Fehler "von links" eine Exception geworfen? Dann sollte man da stillschweigend 0 zurückgeben - du könntest ja von dann ebenfalls diesen 2. Parameter prüfen. Finde ich inkonsistent.

    Es ist außerdem extrem umständlich zu bedienen. Also lohnt es sich, das stoi zu in eine eigene Funktion zu wrappen. Man kann ja auch ein optional<int> zurückgeben oder immer ne Exception werfen. Für welche Fälle soll es denn nützlich sein, rechts von der Zahl Fehleingaben zu ignorieren, was ja der Default ist? Wäre es, wenn der 2. Parameter nicht angegeben wird, nicht viel besser/konsistenter, auch bei Fehlern von rechts eine Exception zu werfen?

    Problematisch ist das z.B., wenn der Benutzer "1.5" oder "1e4" eingibt und somit offensichtlich (für Menschen) was anderes als 1 meint.

    Wieso ist das problematisch? Das machst du genau wie oben und brüllst den Benutzer anschließend an "das ist keine Ganzzahl, du Armleuchter!".

    Genau. Nur dass es zu kompliziert ist. (wie gesagt, irgendwann hatte (ggf. sogar hier?) mich jemand schonmal auf den 2. Parameter hingewiesen - ich vergesse den immer und sehe auch in Code (fast?) immer nur stoi("ein arguemnt") .

    Ich nehme also hiermit meine Kritik an stoi halb zurück 😉



  • wob schrieb:

    Nur warum wird dann bei einem Fehler "von links" eine Exception geworfen? Dann sollte man da stillschweigend 0 zurückgeben - du könntest ja von dann ebenfalls diesen 2. Parameter prüfen. Finde ich inkonsistent.

    Eine "stillschweigende Default-0" ist aber was anderes als eine eindeutig im String erkannte 0. Das muss unterscheidbar sein.

    Es gibt mehrere mögliche Ansätze, z.B.:

    int stoi (string s) throw;    // so wirds gemacht
    int stoi (string s, size_t * idx); // idx ist nicht optional - man wird zu nichts gezwungen, aber doch nachdrücklich erinnert
    bool stoi (string s, int & result); // result nur gültig, wenn rückgabe == true
    

    Die Designer der c++-Lib haben sich für die erste Variante entschieden, vermutlich deshalb, weil damit eine garantiert mögliche Konvertierung am elegantesten zu programmieren ist und alle anderen mit vertretbarem Aufwand in etwas Elegantes gewrappt werden können.



  • An dieser Stelle möchte ich nochmal sagen, dass ich sehr froh über jede Hilfe bin, die ich hier erhalte.

    Ihr habt mich überzeugt. Ich werde mein Projekt mit Strings machen. Die CFramework Klasse ist schon fertig. Jetzt erstmal was schönes essen und dann kommt der Rest. 🙂



  • String wird mit st abgekürzt, oder?

    Z.B. std::string stName;



  • Bizarreofnature schrieb:

    String wird mit st abgekürzt, oder?

    Z.B. std::string stName;

    ne, mit "str"



  • Garnicht. Was soll "Name" sonst sein, als ein String? Welchen mehrwert hat da ein Präfix? Schau mal https://stackoverflow.com/questions/111933/why-shouldnt-i-use-hungarian-notation an. Eventuell auch Making Wrong Code look Wrong.


Anmelden zum Antworten