Zahlen zu Strings

Eine Zahl in einen String umwandeln? An sich ganz leicht, allerdings im Standard nur für's Dezimalsystem vorgesehen. Das lässt sich aber leicht ändern.

Video

Quellcode

#include <string>
#include <iostream>
#include <stdexcept>

std::string toString(uint64_t value, uint8_t base)
{
    std::string tmp;
    
    while (value != 0) {
        auto digit = value % base;
        if (digit > 36) {
            throw std::out_of_range("Basis muss <= 36 sein"); 
        }
        tmp += (digit < 10) ? ('0'+digit) : ('a'+digit-10);
        value /= base;
    }
    return std::string(tmp.rbegin(), tmp.rend());
}

int main()
{
    unsigned int x = 0x3039;
    
    std::cerr << std::to_string(x) << std::endl;
    std::cerr << toString(x, 16) << std::endl;
    std::cerr << toString(x, 2) << std::endl;
    std::cerr << toString(x, 36) << std::endl;    
}

Erklärung

Der Standard hält eine (einfache) Methode zur Umwandlung von Integern in Strings bereit: std::to_string nimmt einen Integer und wandelt ihn in seine Darstellung als String im Dezimalsystem um. Das ist für ein Video ein bischen wenig, weswegen ich diese Methode etwas erweitert habe.

Grundsätzlich funktioniert das Umwandeln in einen String zu einer bestimmten Basis immer gleich: man teilt mit Rest immer wieder durch die Basis und ermittelt so die einzelnen Ziffern der Zahl. Diese werden dann für den String auf die entsprechenden Symbole abgebildet. Im Beispiel oben ist das Teilen mit Rest in Zeile 10 und 15 zu sehen. In Zeile 10 wird mit der Modulo-Operation die nächste Ziffer ermittelt, während in Zeile 15 das tatsächliche Teilen durchgeführt wird. Dabei "rutscht" die nächste Ziffer ans Ende und kann im nächsten Schleifendurchlauf mit der Modulo-Operation ermittelt werden. Die Abbildung der Ziffer auf ihren ASCII-Code geschieht mit dem ternären Operator in Zeile 14. Ist die Ziffer kleiner als 10, dann wird auf den Bereich '0' bis '9' abgebildet. Ist sie größer, dann eben auf das Alphabet. Die Abbildung macht sich zunutze, dass im ASCII-Code sowohl die Ziffern 0-9, als auch das Alphabet als Block hinteinander liegt und deswegen mittels einer einfachen Addidtion bearbeitet werden kann. Das Programmfragment ist damit zwar streng genommen nicht mehr portabel in andere Zeichensätze, aber heute ist ASCII sowieso so weit verbreitet, dass man wahrscheinlich ernste Schwierigkeiten hat, was anderes zu finden.

Nachteil der Methode: die Ziffern werden dabei von hinten nach vorn, also von der Einer- zu Hunderter-(Tausender- etc.)Stelle ermittelt. Daher muss der String natürlich vor der Rückgabe umgedreht werden. Das geschieht in Zeile 17: std::string bietet einen Konstruktor, der den String aus einem Bereich zwischen zwei Iteratoren initialisiert. Füttert man dort die Reverse-Iterators eines anderen Strings ein, so wird sich der neue als gespiegelte Variante des ursprünglichen initialisieren.