Länge eines stringstreams, wie?



  • Hallo haben einen Integer Wert und will die Anzahl der dezimalstellen ermitteln, damit ich später einen string (chars) erstellen kann.
    Mein Code bisher:

    int a=3432;
    stringstream Str;
    Str << a;
    int stellen=(int)Str.gcount();
    char* test_chars= new char[stellen+1];
    memset(test_chars,'\0',stellen+1);
    Str >> test_chars;
    

    soweit funzt das, aber wie in der ref. geht gcount nur mit unformatierten Daten, bekommen da immer 0 als anzahl der stellen.

    Danke im vorraus fü Hilfe



  • hast du ne aufgabenstellung oder willst du einfach nur einen integer in einen string umwandeln?

    bb



  • nein ich brauch die Anzahl der Dezimalstellen. Und wenn man mit cout in der Lage ist dies auf den Bildschirm zu geben, muss es doch mögich sein mittels iostream bzw. stringstream die Anzahl der Stellen auszugeben.



  • wieso auch immer du die anz der stellen mit nem stringstream rausbekommen möchtest...

    hier die fertiglösung:

    std::string get_int_as_string(int value)
    {
      std::stringstream ss;
      ss << value;
      return ss.str();
    }
    

    hier die doku:
    http://www.cplusplus.com/reference/iostream/stringstream/

    die länge geht am einfachsten über den string herauszubekommen...
    wenn du aber nur die länge brauchst:

    int get_length(int value)
    {
      int ret_val = 0;
      for(; value != 0; ++ret_val)
        value /= 10;
      return ret_val;
    }
    

    gibt noch ca. 300 andere möglichkeiten - du solltest halt mal sagen, wieso du die länge haben möchtest...

    bb



  • Dein Code "failt" bei 0 (Länge = 0) und Minuszahlen (Endlosschleife).
    Hier mal ein Fix 😉

    int get_length(int value)
    {
    	if (value == 0)
    		return 1;
    
    	int ret_val = 0;
    
    	if (value < 0)
    	{
    		value *= -1;
    		++ret_val;
    	}
    
    	for(; value != 0; ++ret_val)
    		value /= 10;
    
    	return ret_val;
    }
    


  • theliquidwave schrieb:

    Dein Code "failt" bei 0 (Länge = 0) und Minuszahlen (Endlosschleife).
    Hier mal ein Fix 😉

    int get_length(int value)
    {
    	if (value == 0)
    		return 1;
    	
    	int ret_val = 0;
    	
    	if (value < 0)
    	{
    		value *= -1;
    		++ret_val;
    	}
    	
    	for(; value != 0; ++ret_val)
    		value /= 10;
    	
    	return ret_val;
    }
    

    a) Welchen Zweck hat

    value *= -1;
    

    ?

    b) Ich würde eine do-Schleife nehmen.



  • danke unskilled, nehme die erste variante :),

    will es als reinen int zurück haben, um damit die größe eines neuen chararrays zu erzeugen,



  • @ volkard:
    -200 * -1 = 200 = abs(-200)
    Mit Minuszahlen entsteht sonst eine Endlosschleife...

    Gruß



  • theliquidwave schrieb:

    Dein Code "failt" bei 0 (Länge = 0) und Minuszahlen (Endlosschleife).

    tur er nicht!?



  • theliquidwave schrieb:

    @ volkard:
    -200 * -1 = 200 = abs(-200)
    Mit Minuszahlen entsteht sonst eine Endlosschleife...

    Gruß

    Tatsächlich?

    -200 / 10 = -20
         / 10 = -2
         / 10 = 0
    


  • theliquidwave schrieb:

    @ volkard:
    -200 * -1 = 200 = abs(-200)
    Mit Minuszahlen entsteht sonst eine Endlosschleife...
    Gruß

    Ein Bißchen mehr Begründung hatte ich mir erträumt, denn bei mir gibt

    int i=-200;
    	cout<<i<<' '<<get_length(i)<<'\n';
    

    brav

    -200 4
    

    aus.



  • wenn das minus in der länge mitzählen soll müsste die fkt so aussehen:

    int get_length(int value, bool count_minus = false)
    {
      int ret_val = count_minus && value < 0;
      for(; value != 0; ++ret_val)
        value /= 10;
      return ret_val;
    }
    

    bb



  • unskilled schrieb:

    wenn das minus in der länge mitzählen soll müsste die fkt so aussehen:

    int get_length(int value, bool count_minus = false)
    {
      int ret_val = count_minus && value < 0;
      for(; value != 0; ++ret_val)
        value /= 10;
      return ret_val;
    }
    

    bb

    Da wäre ich bei der 0 noch anderer Meinung.
    Deswegen bevorzuge ich do

    int get_length(int value, bool count_minus = false)
    {
      int ret_val = count_minus && value < 0;
      do
        ++ret_val;
      while(value /= 10);
      return ret_val;
    }
    


  • hmm... ich find do-while hässlich 😛
    war aber auch die ganze zeit davon ausgegangen, dass 0 die länge null haben sollte... mein fail : D

    int get_length(int value, bool count_minus = false)
    {
      int ret_val( value == 0 || count_minus && value < 0 );
      for(; value != 0; ++ret_val)
        value /= 10;
      return ret_val;
    }
    

    kein plan, ob das performance-mäßig was bringt, ich denke zwar schon, aber bin zu faul zu vergleichen... ^^

    bb



  • Hi,
    könnte man das Problem nicht einfacher lösen?
    Soweit ich mich erinnere kann man mit dem Logarithmus die Anzahl der stellen ermitteln...
    Man nehme entsprechend zum Zahlensystem einen Logarithmus und Rundet auf...
    Für das Dezimalsystem :

    int getLenght(int const& X)
    {
        return log10( abs(X) ) +1 + (X<0);
    }
    

    Gruss

    Edit:
    Man müsste noch testen bis zu welcher Zahl es sich lohnt, die schleifenversion zu nehmen und danach zu prüfen.



  • ich glaube kaum, dass es sich bei einer 32bit zahl überhaupt lohnen wird...

    alleine schon die ständigen umwandlungen wären für mich schon grund genug, es nicht zu verwenden...

    int g0(int const& X)
    {
        return log10( abs(X) ) +1 + (X<0);
    }
    

    kompiliert bei mir nicht mal (msvc9):
    error C2668: 'log10': Mehrdeutiger Aufruf einer überladenen Funktion

    ich hab mir mal erlaubt es so zu schreiben:

    #include <cmath>
    
    unsigned int f(int X, bool count_minus = false)
    {
    	float log_10 = std::log10( float(abs(X)) );
    	unsigned int ret_val = unsigned int(log_10);
    	return ret_val + 1 + (count_minus && X<0);
    }
    

    test-aufruf:

    unsigned int a = f(INT_MIN);
    //a == 1
    

    der log-aufruf hier geht schief - in dem float steht irgend ein code, der sich mir nicht ganz erschließt - irgendwas mit IND001

    bb



  • theliquidwave schrieb:

    Dein Code "failt" bei 0 (Länge = 0) und Minuszahlen (Endlosschleife).
    Hier mal ein Fix 😉

    int get_length(int value)
    {
    	if (value == 0)
    		return 1;
    	
    	int ret_val = 0;
    	
    	if (value < 0)
    	{
    		value *= -1;
    		++ret_val;
    	}
    	
    	for(; value != 0; ++ret_val)
    		value /= 10;
    	
    	return ret_val;
    }
    
    get_length(-2147483648);
    

    :p



  • Michael E. schrieb:

    theliquidwave schrieb:

    Dein Code "failt" bei 0 (Länge = 0) und Minuszahlen (Endlosschleife).
    Hier mal ein Fix 😉

    int get_length(int value)
    {
    	if (value == 0)
    		return 1;
    	
    	int ret_val = 0;
    	
    	if (value < 0)
    	{
    		value *= -1;
    		++ret_val;
    	}
    	
    	for(; value != 0; ++ret_val)
    		value /= 10;
    	
    	return ret_val;
    }
    
    get_length(-2147483648);
    

    :p

    Das gibt aber auch kein falsches Ergebnis.
    Falls value*=-1 gar nicht benötigt wird, was zur Zeit vermutet wird.



  • unskilled schrieb:

    ich glaube kaum, dass es sich bei einer 32bit zahl überhaupt lohnen wird...

    alleine schon die ständigen umwandlungen wären für mich schon grund genug, es nicht zu verwenden...

    int g0(int const& X)
    {
        return log10( abs(X) ) +1 + (X<0);
    }
    

    Jo, hab das std:: vergessen, hinzukommt das ich X=0 nicht abfrage,
    lustigerweise funktionierte es bei mir trozdem (gcc), da ich es mit unsigned als Rückgabewert getestet habe und scheinbar -inf +1 zu null gecasted wird?!
    Ist das Compiler abhängig?
    Kann das jemand erklären?

    #include <iostream>
    #include <cmath>
    
    int main()
    {
        std::cout << std::log10(0) <<"\n"; //-inf0
        std::cout << (int)std::log10(0)<<"\n"; // -2147483648
        std::cout << (unsigned int)std::log10(0); // 0
        return 0;
    }
    


  • Was spricht gegen diese Lösung?

    unskilled schrieb:

    std::string get_int_as_string(int value)
    {
      std::stringstream ss;
      ss << value;
      return ss.str();
    }
    

Log in to reply