Resource icon

Beispiel zur Umwandlung von Zahlen in verschiedene Zahlensysteme 2018-07-08

No permission to download
Programmiersprache(n)
c++
Betriebssystem(e)
Linux
Hallo Leute!

Sicherlich hat jeder von euch schon mal Dezimalzahlen ins Binäre, hexadezimale oder oktale Zahlensystem umgewandelt. Wenn man aber von einen beliebigen Zahlensystem von 2 bis 36 in ein anderes Zahlensystem konvertieren will?
Hier bietet sich folgende Taktik an.
Zuerst liest man diese Zahl als String (std::string) ein und wandelt diese in eine integer Variable (4 Byte Länge)
um. Danach konvertiert man diese Dezimalzahl wieder in einen String der diese Zahl konvertiert in einem
Zahlensystem von 2 bis 36 symbolisiert.

Nun zuerst einmal den code:

Hier die Hauptfunktion main.cpp:
Code:
#include "zahlwandl.h"
#include <stdlib.h>

int main(void)
{
int wouhi = 8, deza, basis, erge;
std::string puffer;
std::string zahlstring = "";

do
switch(wouhi)
 {
default:
      std::cout << std::endl  << "Programm zum umrechnen von Dezimal- und Hexadezimalzahlen" << std::endl << std::endl;
      std::cout << "Programmende..........0" << std::endl;
      std::cout << "dezi in hexa..........1" << std::endl;
      std::cout << "hexa in dezi..........2" << std::endl;
      std::cout << "Basis x in Basis y....3" << std::endl;
      std::cout << "max Basis x ..........4" << std::endl;
      std::cout << std::endl << "Ihre Wahl: " << std::endl;
      std::cin >> wouhi;
    break;

case 0:
    std::cout << "Programmende" << std::endl;
    return EXIT_SUCCESS;
   break;

case 1:
    deza = 0;
    std::cout << "Dezimalzahl?: ";
    std::cin >> deza;
    std::cout << "Hexa = 0x" << std::hex << deza << std::endl;
    wouhi = 8;
   break;

case 2:
     deza = 0;
     std::cout << std::endl << "Hexadezimalzahl?";
     std::cin >> std::hex >> deza; ///puffer;
     std::cout << "dezimal= " << std::dec << deza;
    wouhi = 8;
  break;

case 3:
     std::cout << std::endl << "Umzuwandelnde Zahl eingeben: ";
     std::cin >> puffer;
     std::cout << std::endl << "Basis dieser Zahl eingeben(von 2 bis 36): ";
     std::cin >> basis;

     erge = xwertzudez(&deza, puffer, basis);
     if (erge == 0)
      {
       std::cout << "Im Dezimalsystem: " << deza << std::endl;

       std::cout << std::endl << "Zielzahlensystem eingeben(2 bis 36): ";
       std::cin >> basis;
       zahlstring = itoa (deza, basis);
       std::cout << std::endl << "Dezi= " << deza << " Im "<< basis<< "er-System dargestellt: " << zahlstring;
      }
     else
      std::cout << "Fehlerhafte Zeichen im String\n";

     wouhi = 8;
  break;

 case 4:
     std::cout << std::endl << "Umzuwandelnde Zahl eingeben: ";
     std::cin >> puffer;
     std::cout << std::endl << "Basis dieser Zahl eingeben(von 2 bis 36): ";
     std::cin >> basis;
     basis = 36;

     erge = xwertzudez(&deza, puffer, basis);

     if (erge == 0)
      {
       std::cout << std::endl << "Umzuwandelnde Zahl: " << deza << std::endl;

       for (basis = 2; basis <= 36; basis++)
        {
         zahlstring = itoa (deza, basis);
         std::cout << std::setw(2) << basis << "er-System: " << zahlstring << std::endl;
        }

       }
      else
      std::cout << "Fehlerhafte Zeichen im String\n";

     wouhi = 8;

  break;


 }while(wouhi != 0);

return EXIT_SUCCESS;
}
Jetzt der Header der Datei zahlwandl.h:
Code:
#ifndef ZAHLWANDL_H_INCLUDED
#define ZAHLWANDL_H_INCLUDED

#include <iostream>
#include <iomanip> /// wegen std::setw()
#include <stdio.h> /// wegen getchar
#include <ctype.h> /// wegen tolower
#include <algorithm>    // std::reverse
#include <string.h>
#include <math.h>
#include <errno.h>

//char *itoa(int zahl, char puffer[], int basis);
std::string de_tolower(std::string upsatz);
std::string itoa(int zahl, int basis);
int xwertzudez(int *wert, std::string puffer, int basis);


#endif // ZAHLWANDL_H_INCLUDED
Nun die dazugehörige Datei zahlwandl.cxx:
Code:
#include "zahlwandl.h"
#include <string>


std::string de_tolower(std::string upsatz)
{
 std::string losatz = "";
 std::string gxe[29] = {"Ö", "Ä", "Ü", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "k", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "w", "X", "Y", "Z"};
 std::string kxe[29] = {"ö", "ä", "ü", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};

 int slei = 0, slen = 0,  p = 1;

for (slei = 0; slei < 29; slei++)
 {
 p = upsatz.find(gxe[slei]);
  while(p != -1)
   {
    //std::cout << "p: "   << p << " *   ";
    //std::cout << upsatz << "  gxe: " << gxe[slei] << "   p: " << p << "     n: ";
     slen = gxe[slei].length();
     upsatz.erase(p,slen);
     upsatz.insert(p, kxe[slei]);
     //std::cout << upsatz << std::endl;
     p = upsatz.find(gxe[slei]);
    }
 }

return upsatz;
}


 /**Diese Funktion wandelt ganze Dezimalzahlen vom Typ int in Strings um
    Die umzuwandelnde Zahl ist der Parameter 1, der zweite Parameter ist
    das Zahlensystem, im Dezimalsystem die 10, in anderen die 16 oder
    zum Beispiel die 8(wäre oktal) */
std::string itoa(int zahl, int basis)
 {
  std::string erge = "";
  int slei = 0, start;
  int produkt = 0, dummy = 0, nullsteller = 0;
  char zeichensatz[50];
  strcpy(zeichensatz, "0123456789abcdefghijklmnopqrstuvwxyz");

  /* behandelt maximal basis hoch 16 große ganze Dezimalzahlen (natürliche Zahlen) */
    /// Falls eine Null umgewandelt werden soll sinnlos, Null ist Null
    if ((zahl == 0) || (basis < 2) || (basis > 36))
     {
      erge = "0";
      return erge;
     }

     //std::cout << "*Stufe 1" << std::endl;
     /// zuerst wird geprüft, ob eine negative Zahl vorliegt
    if (zahl < 0 )
     {
      erge += "-";
      zahl *= -1;
     }
    /// feststellen, wie hoch die erste Potenz der Basis in dieser Zahl ist
   for (slei = 32; slei >= 0; slei--)
     {
      produkt = (int)pow(basis, slei);
      if (errno != ERANGE)
       {
        start = slei;
        dummy  = zahl / produkt;
        if (dummy > 0)
         break;
       }
     }

    for (slei = start; slei >= 0; slei--)
     {
      produkt = (int)pow(basis, slei);
      dummy   = zahl / produkt;
      zahl   -= dummy * produkt;
      if ((dummy == 0) && (nullsteller == 1))
       erge += "0";
      if ( dummy != 0)
       {
        erge += zeichensatz[dummy];
        nullsteller = 1;
       }
      erge += '\0';
     }
 return erge;
 }

 ///Gegenteil von itoa, wandelt eine als string gespeicherte Zahl in eine Dezimalzahl um
int xwertzudez(int *wert, std::string puffer, int basis)
 {
  char zeichen [50];
  int slei, sleib, erge, lenge, zahl, dummy, fehlertest;
  strcpy(zeichen, "0123456789abcdefghijklmnopqrstuvwxyz");

  // Rückgabewert ist -1 falls basis ungueltig
  erge = -1;
  zahl = fehlertest = 0;
  lenge = puffer.length(); //Feststellen der Stringlänge
  *wert = lenge;

  //std::cout << "lenge = " << lenge << std::endl;
  std::cout << std::endl;
  /// Pruefe ob basis gueltig
  if (basis < 2 || basis > 36) return erge;

  /// Grossbuchstaben in Kleinbuchstaben umwandeln
  puffer = de_tolower(puffer);

  /// Test, ob andere Zeichen vorhanden sind
  for (slei = 0; slei < lenge; slei++)
   {
    for (sleib = 0; sleib < basis; sleib++)
     if (zeichen[sleib] == puffer[slei]) fehlertest++;
   }

 ///Wenn falsche Zeichen festgestellt wurden Abbruch
 if (fehlertest != lenge)
  {
   erge = -2;
   return erge;
  }

  ///Umwandlung des Strings in eine Dezimalzahl
  for (slei = lenge - 1; slei >= 0; slei--)
   {
    dummy = puffer[slei];
    for (sleib = 0; sleib <= 35; sleib++)
     if ((dummy == zeichen[sleib]) && (sleib > 0)) zahl += pow(basis, (lenge -slei -1)) * sleib;
   }
  erge = 0;
  *wert = zahl;

return erge;
}
Eigentlich bin ich erst vor kurzem auf die Idee gekommen, die Zahl TXTP8 in andere Zahlensysteme
umzuwandeln. Jedoch möchte ich bemerken, das ich mit diesem Beispiel gewissen Software-Firmen
nicht ans Bein Pinkeln will. Das sich jemand diesen Code zunutze macht, um Registrierungsschlüssel
zu knacken verbiete ich hiermit ausdrücklich. Es soll nur als Lehrmaterial dienen.
Falls das möglich sein sollte. Man kann ja nie wissen.

Gecodet wurde auf SUSE Linux tumbleweed Kernel 4.16.12-2
mit codeblocks und gcc

Noch eins: No warranty!

Viel Spaß
rustyoldguy
Autor
rustyoldguy
Downloads
0
First release
Last update
Bewertung
0,00 Stern(e) 0 Bewertungen
Oben