如何将程序参数从argv
转换为int64_t
? atoi()
仅适用于32位整数。
答案 0 :(得分:12)
符合C99标准的尝试。
[编辑]使用@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;
}
答案 1 :(得分:10)
有几种方法可以做到:
strtoll(str, NULL, 10);
这符合POSIX C99。
你也可以使用strtoimax;它有以下原型:
strtoimax(const char *str, char **endptr, int base);
这很好,因为它总是可以使用本地的intmax_t ...这是C99,你需要包含<inttypes.h>
答案 2 :(得分:2)
strtoll
将其转换为long long
,通常为64位整数。
答案 3 :(得分:2)
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;
编写此逻辑是为了避免所有溢出情况。
答案 4 :(得分:1)
这对我来说具有不同的int64类型,并且我喜欢干净的C ++风格:
std::istringstream iss(argv[i]);
int64_t i64;
iss >> i64;
您可能会遇到编译错误:操作员<< ...未定义。
如果argv [i]包含“ HALLO”,我不知道会发生什么。
答案 5 :(得分:1)
如何将字符串转换为 int64_t?
最简单的
#include <stdlib.h>
int64_t value = atoll(some_string); // lacks error checking. UB on overflow
更好
long long v = strtoll(s, NULL, 0); // No reported errors, well defined on overflow
健壮:创建一个辅助函数来检测所有问题。
#include <stdbool.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
// Return error flag
bool my_strtoi64(int64_t *value, const char *s) {
// Maybe add a s==NULL, value==NULL checks.
char *endptr;
errno = 0;
long long v = strtoll(s, &endptr, 0);
// Optional code for future growth of `long long`
#if LLONG_MIN < INT64_MIN || LLONG_MAX > INT64_MAX
if (v < INT64_MIN) {
v = INT64_MIN;
errno = ERANGE;
} else if (v > INT64_MAX) {
v = INT64_MAX;
errno = ERANGE;
#endif
*value = (int64_t) v;
if (s == endptr) { // No conversion, *v is 0
return true;
}
if (errno == ERANGE) { // Out of range
return true;
}
if (errno) { // Additional implementations specific errors
return true;
}
while (isspace(*(unsigned char* )endptr)) { // skip trail white-space
endptr++;
}
if (*endptr) { // Non-numeric trailing text
return true;
}
return false; // no error
}
答案 6 :(得分:0)
来自网络搜索的用户还应考虑使用std::stoll
。
对于const char*
,它并不能严格有效地回答这个原始问题,但是无论如何,许多用户还是会有std::string
。如果您不关心效率,那么即使您拥有std::string
,也应该隐式转换(基于使用单参数std::string
构造函数的用户定义转换)到const char*
它比std::strtoll
简单,后者总是需要3个参数。
如果输入的不是数字,则应该抛出该异常,但请参见these comments。