Задать вопрос
@EgaNator
Учусь на программиста

Как в моём классе реализовать перевод из шестнадцатеричной системы счисления в восьмеричную?

Здравствуйте. Я создал класс, в котором изначально введена шестнадцатеричная строка. Так же введена ещё одна строка. И мы проверяем, если строки равны, то выводим 1, если нет, то 0. Затем складываем эти строки и выводим их длину. И нужно перевести эти строки в восьмеричную систему. Последнее у меня и не выходит. Это можно сделать как через наследование так и нет. В СИ знаю, что можно перевести так:
int n;
cout << "Введите шестнадцатеричное число: ";
scanf("%x", &n);
printf("%s %o", "Восьмеричное равно ", n);
Сделать, чтобы это всё работает, не выходит. Подскажите, пожалуйста, как это реализовать.
Вот мой код. Преподаватель сказал, что исправлять ничего не нужно. Только сделать перевод.

String.h
#pragma once
#include <iostream>
#include <cstring>

using namespace std;

class String
{
protected:
  int Length;
  char* Str;
public:
  String();
  String(const char* ptr);
  String(const String& t);
  String& operator = (String& t);
  String& operator += (const String& t);
  bool operator == (const String& t) const;
  bool operator != (const String& t) const;
  bool is_empty() const;
  const char* getStr() const;
  int getLength() const;

  ostream & show(ostream & os) const;
  friend ostream & operator << (ostream & os, const String & s)
  {
    return s.show(os);
  }

  ~String();
};


String.cpp

#include "String.h"
#include <iostream>
#include <cstring>

using namespace std;

String::String()
{
  Str = 0;
  Length = 0;
}

String::String(const char* ptr)
  : Length(strlen(ptr)), Str(new char[Length + 1])
{
  strcpy(Str, ptr);
}

String::String(const String& t)
  : Length(strlen(t.Str)), Str(new char[Length + 1])
{
  strcpy(Str, t.Str);
}
String& String::operator = (String& t)
{
  swap(Length, t.Length);
  swap(Str, t.Str);
  return *this;
}

String& String::operator += (const String& t)
{
  int newLength = Length + t.Length;
  char *newStr = new char[newLength + 1];
  strcpy(newStr, Str);
  strcat(newStr, t.Str);
  delete[] Str;
  Str = newStr;
  Length = newLength;
  return *this;
}

bool String::operator == (const String& t) const
{
  return Length == t.Length && strcmp(Str, t.Str) == 0;
}

bool String::operator != (const String& t) const
{
  return !(operator == (t));
}

bool String::is_empty() const
{
  return Str == 0 || Str[0] == '\0';
}

const char* String::getStr() const
{
  return Str;
}

int String::getLength() const
{
  return Length;
}

ostream & String::show(ostream & os) const
{
  return os << "\"" << (Str ? Str : "") << "\"";
}

String::~String()
{
  Length = 0;
  delete[] Str;
  Str = 0;
}


main.cpp

#include "String.h"
#include <iostream>
#include <conio.h>
#include <cstring>

using namespace std;

int main()
{
  setlocale(LC_ALL, "Russian");

  String s("0 1 2 3 4 5 6 7 8 9 A B C D E F");
  String f("Qwertyy");
  cout << s << endl;
  cout << (s == f) << endl;
  s += f;
  cout << s << endl;

  _getch();
  return 0;
}
  • Вопрос задан
  • 632 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 2
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
Самый простой вариант (и супер не эффективный):
std::string decString("10");
	
std::stringstream buf;
buf << std::oct << std::stoi(decString) << std::endl;
	
std::string octString = buf.str();
std::cout << octString << std::endl;


Вообще, чтобы число перевести десятичное число, например в восьмеричную систему, можно написать простой цикл на 4-5 строчек.
Ответ написан
Комментировать
Если компилятор позволяет, можно использовать itoa, если нет - sprintf. Не C++, но будет работать.
std::string hexString = "0xBAADF00D";
char octString[MAX_BUF];
itoa(std::stoi(hexString, 0, 16 ), octString, 8);


Придумался мне тут интересный велосипед. Так как шестнадцатеричная и восьмеричная системы счисления основаны на степени двойки, это сильно облегчает нам жизнь (схема тут). 12 двоичных разрядов могут быть записаны как три шестнадцатеричные цифры, либо как четыре восьмеричные. Таким образом, для преобразования шестнадцатеричной строки в восьмеричную, нужно все тройки шестнадцатеричных символов (с конца, начало дополнить нулями) заменить соответствующими четвёрками восьмеричных:

#include <cstring>
#include <iostream>

unsigned getHexDigit(char hexChar)
{
	if (hexChar >= '0' && hexChar <= '9')
	{
		return hexChar - '0';
	}
	if (hexChar >= 'A' && hexChar <= 'F')
	{
		return 10 + hexChar - 'A';
	}	
	if (hexChar >= 'a' && hexChar <= 'f')
	{
		return 10 + hexChar - 'a';
	}
	return 0;
}

void getOctQuartet(const char* hex, char* oct)
{
	unsigned number = getHexDigit(hex[0]) << 8 | getHexDigit(hex[1]) << 4 | getHexDigit(hex[2]);
	oct[0] = '0' + (number >> 9 & 07);
	oct[1] = '0' + (number >> 6 & 07);
	oct[2] = '0' + (number >> 3 & 07);
	oct[3] = '0' + (number & 07);
}

char* getOctString(const char* hexString)
{
	const size_t hexStrLen = strlen(hexString);
	const size_t prefixLen = hexStrLen % 3;
	char* octString = new char[(hexStrLen - prefixLen + 3) / 3 * 4 + 1];	
	char* pOct = octString;
	if (prefixLen > 0)
	{
		char hexPrefix[3] = { '0'
			, prefixLen == 2 ? hexString[0] : '0'
			, prefixLen == 2 ? hexString[1] : hexString[0] 
		};
		getOctQuartet(hexPrefix, octString);
		pOct += 4;
	}

	const char* pHex = hexString + prefixLen;
	while(pHex < hexString + hexStrLen)
	{
		getOctQuartet(pHex, pOct);
		pHex += 3;
		pOct += 4;
	}
	*pOct = '\0';

	return octString;
}

int main()
{
	char hexString[] = "123456789ABCDEF";
	char* octString = getOctString(hexString);
	std::cout << octString << std::endl;
	delete[] octString;
	return 0;
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы