Как преобразовать строку в int64_t?
Как преобразовать параметр программы из argv
в int64_t
? atoi()
подходит только для 32-битных целых чисел.
Ответы
Ответ 1
Выполняемая C99 попытка.
[edit] used @R. Коррекция
// Note: Typical values of SCNd64 include "lld" and "ld".
#include <inttypes.h>
#include <stdio.h>
int64_t S64(const char *s) {
int64_t i;
char c ;
int scanned = sscanf(s, "%" SCNd64 "%c", &i, &c);
if (scanned == 1) return i;
if (scanned > 1) {
// TBD about extra data found
return i;
}
// TBD failed to scan;
return 0;
}
int main(int argc, char *argv[]) {
if (argc > 1) {
int64_t i = S64(argv[1]);
printf("%" SCNd64 "\n", i);
}
return 0;
}
Ответ 2
Есть несколько способов сделать это:
strtoll(str, NULL, 10);
Это совместимый с POSIX C99.
вы также можете использовать strtoimax; который имеет следующий прототип:
strtoimax(const char *str, char **endptr, int base);
Это хорошо, потому что он всегда будет работать с локальным intmax_t... Это C99, и вам нужно включить <inttypes.h>
Ответ 3
strtoll
преобразует его в long long
, который обычно является 64-битным int.
Ответ 4
Выполнение этой 100% -ной переносимости немного сложно. long long
должен быть не менее 64 бит, но необязательно должен быть дополнением к двум, поэтому он может не представлять -0x7fffffffffffffff-1
, и, таким образом, использование strtoll
может иметь разбитый угловой случай. Эта же проблема относится к strtoimax
. Вместо этого вы должны использовать ведущее пространство (если вы хотите разрешить ведущее пространство) и сначала проверить знак, затем используйте strtoull
или strtoumax
, каждый из которых необходим для поддержки значений до полного положительного диапазона int64_t
. Затем вы можете применить знак:
unsigned long long x = strtoull(s, 0, 0);
if (x > INT64_MAX || ...) goto error;
int64_t y = negative ? -(x-1)-1 : x;
Эта логика написана, чтобы избежать всех случаев переполнения.
Ответ 5
Это сработало для меня с другим типом int64, и мне нравится чистый стиль C++:
std::istringstream iss(argv[i]);
int64_t i64;
iss >> i64;
Вы можете получить ошибку компиляции: operartor <<... не определен.
И я не знаю, что произойдет, если argv [i] содержит "HALLO".
Ответ 6
Пользователи, пришедшие с веб-поиска, также должны учитывать std::stoll
.
Он не дает точного ответа на этот оригинальный вопрос эффективно для const char*
но у многих пользователей в любом случае будет std::string
. Если вы не заботитесь об эффективности, вы должны получить неявное преобразование (на основе пользовательского преобразования с помощью одного аргумента std::string
конструктора) для std::string
, даже если у вас есть const char*
.
Это проще, чем std::strtoll
который всегда требует 3 аргумента.
Он должен бросить, если ввод не число, но посмотрите эти комментарии.