У меня вопрос в преобразовании 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 ГБ)?
У вас нет строки размером 64 ГБ, которая будет содержать строку размером 64 гигабайта. У вас есть строка, содержащая десятичное число, представляющее значение около 64 гигабайт.
Стандартная функция, которую вы ищете, - strtoll
, которая возвращает long long
результат. Это стандартная функция C, поскольку стандарт 1999 года, и если я не ошибаюсь, к 2011 году был добавлен стандарт C++.
(Вопрос в том, поддерживает ли C++ Builder XE4 strtoll
.)
Если size_t
на вашей системе всего 32 бита, нет никакого способа получить значение size_t
которое будет большим. Если это 64 бита, strtoll
должен сделать трюк.
Проблема состоит в том, что объект VCL String
(который, по-видимому, является псевдонимом класса VCL AnsiString
UnicodeString
) возвращает double
с значением 64420392960.0, которое преобразуется в интегральный тип, но size_t
является 32-разрядным беззнаковым типом, поэтому он сохраняет только нижние 32 бита значения.
Вместо типа size_t
попробуйте unsigned long long
или plain old long long
если ваша toolchain поддерживает его.
Другие люди объяснили, почему ваш исходный код не работает. Существует еще одна альтернатива: используйте __int64
вместо long long
. VCL поддерживает __int64
, например:
String strSize = L"64420392960";
__int64 size = StrToInt64(strSize);
Не используйте double
если вам не нужна точность с плавающей запятой.