получить значение из строковой переменной, содержащей десятичное число, представляющее значение около 64 гигабайт

0

У меня вопрос в преобразовании String в значение.

Ниже приведен пример кода, который я попробовал.

Я пытаюсь это сделать на C++ Builder XE4.

String strSize = L"64420392960"; // 64GB

size_t size;

size = strSize.ToDouble(); // returns 4290850816

char *end_ptr;
size = strtol(AnsiString(strSize).c_str(), &end_ptr, 10); // returns 0

Оба ToDouble() и strtol() не работали.

Я понимаю, что strtol не работал, потому что длинный тип до 4,3 ГБ.

Есть ли какая-либо функция в C++ Builder XE4, с помощью которой я могу преобразовать значение strSize в значение size_t, когда я обрабатываю 64 ГБ или несколько сотен ГБ (например, 500 ГБ)?

Теги:
string
c++builder
c++builder-xe4

3 ответа

2
Лучший ответ

У вас нет строки размером 64 ГБ, которая будет содержать строку размером 64 гигабайта. У вас есть строка, содержащая десятичное число, представляющее значение около 64 гигабайт.

Стандартная функция, которую вы ищете, - strtoll, которая возвращает long long результат. Это стандартная функция C, поскольку стандарт 1999 года, и если я не ошибаюсь, к 2011 году был добавлен стандарт C++.

(Вопрос в том, поддерживает ли C++ Builder XE4 strtoll.)

Если size_t на вашей системе всего 32 бита, нет никакого способа получить значение size_t которое будет большим. Если это 64 бита, strtoll должен сделать трюк.

  • 0
    Большое спасибо. Функция strtoll поддерживается C ++ Builder XE4. Поэтому я буду использовать strtoll. Также я изменил тип размера на длинный длинный. Тогда это сработало. Я ценю.
  • 0
    Спасибо также за исправление моего английского. Я изменил название этого вопроса. Я надеюсь, что это изменение уменьшит путаницу.
1

Проблема состоит в том, что объект VCL String (который, по-видимому, является псевдонимом класса VCL AnsiString UnicodeString) возвращает double с значением 64420392960.0, которое преобразуется в интегральный тип, но size_t является 32-разрядным беззнаковым типом, поэтому он сохраняет только нижние 32 бита значения.

Вместо типа size_t попробуйте unsigned long long или plain old long long если ваша toolchain поддерживает его.

  • 0
    Большое спасибо. Я не узнал, что size_t - это 32-битный тип без знака. Я буду использовать длинный длинный тип. Итак, используя ToDouble (), тогда static_cast to long long может работать, верно?
  • 0
    В ролях не должно быть необходимости.
Показать ещё 3 комментария
1

Другие люди объяснили, почему ваш исходный код не работает. Существует еще одна альтернатива: используйте __int64 вместо long long. VCL поддерживает __int64, например:

String strSize = L"64420392960";
__int64 size = StrToInt64(strSize);

Не используйте double если вам не нужна точность с плавающей запятой.

  • 0
    Большое спасибо. __int64 проще, чем "long long", делая код более понятным. Кроме того, я согласен не использовать double, если у меня нет причин для этого.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню