Ternick
@Ternick

Как решить переписать wtoi лучше?

КОД:
constexpr const int _wcslen(const wchar_t* test) {
	int len = -1;
	do {
		len++;
	} while (*test++ != L'\0');
	return len;
}

constexpr const int getIntFromWchar_t(wchar_t chr) {
	switch (chr)
	{
	case L'0':
		return 0;
	case L'1':
		return 1;
	case L'2':
		return 2;
	case L'3':
		return 3;
	case L'4':
		return 4;
	case L'5':
		return 5;
	case L'6':
		return 6;
	case L'7':
		return 7;
	case L'8':
		return 8;
	case L'9':
		return 9;
	default:
		return 10;
	}
}

constexpr const unsigned long long int pow(int a, int n) {
	if (a != 0) {
		unsigned long long int result = a;
		for (int i = 0; i < n - 1; i++) {
			result *= a;
		}
		return result;
	}
	else {
		if (n == 0) {
			return 1;
		}
		else {
			return 0;
		}
	}
}

constexpr const unsigned long long int wtoi(const wchar_t* str) {
	unsigned long long int result = 0;
	for (int i = 0; i != _wcslen(str); i++) {
		unsigned long long int p = pow(10, _wcslen(str) - i - 1);
		if (p == 0) {
			result += getIntFromWchar_t(str[i]);
		}
		else {
			result += getIntFromWchar_t(str[i]) * p;
		}
	}
	return result;
}

Всё было бы хорошо, если бы не
wtoi(L"35") // => 80

Собственно в этом и вопрос, почему так происходит, хотя по идее всё должно хорошо работать :)
Так же принимаются, всякого рода советы по улучшению конструкции кода :)
  • Вопрос задан
  • 129 просмотров
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
constexpr const unsigned long long int wtoi(const wchar_t* str) {
  unsigned long long int result = 0;
  for (int i = 0; str[i]; i++) {
      int digit = getIntFromWchar_t(str[i]);
      if (digit < 0 || digit > 9)
           break;
      result = result * 10 + digit;
  }
  return result;
}

Обычно делают как-то так, это частный случай схемы Горнера.

constexpr const int getIntFromWchar_t(wchar_t chr) {
  switch (chr)
  {
  case L'0':
    return 0;
  case L'1':
    return 1;
  case L'2':
    return 2;
  case L'3':
    return 3;
  case L'4':
    return 4;
  case L'5':
    return 5;
  case L'6':
    return 6;
  case L'7':
    return 7;
  case L'8':
    return 8;
  case L'9':
    return 9;
  default:
    return 10;
  }
}

Можно переписать так:
int getIntFromWchar_t(wchar_t chr) {
    return chr - L'0';
    static_assert(L'1' == L'0' + 1);
    static_assert(L'2' == L'1' + 1);
    static_assert(L'3' == L'2' + 1);
    static_assert(L'4' == L'3' + 1);
    static_assert(L'5' == L'4' + 1);
    static_assert(L'6' == L'5' + 1);
    static_assert(L'7' == L'6' + 1);
    static_assert(L'8' == L'7' + 1);
    static_assert(L'9' == L'8' + 1);
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы