[英]How to convert string to int64_t?
How to convert program parameter from argv
to int64_t
?如何将程序参数从
argv
转换为int64_t
? atoi()
is suitable only for 32 bit integers. atoi()
仅适用于 32 位整数。
A C99 conforming attempt.符合 C99 的尝试。
[edit] employed @R. [编辑] 使用@R。 correction
更正
// 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;
}
There are a few ways to do it:有几种方法可以做到:
strtoll(str, NULL, 10);
This is POSIX C99 compliant.这是符合 POSIX C99 的。
you can also use strtoimax;你也可以使用 strtoimax; which has the following prototype:
它具有以下原型:
strtoimax(const char *str, char **endptr, int base);
This is nice because it will always work with the local intmax_t ... This is C99 and you need to include <inttypes.h>
这很好,因为它始终与本地 intmax_t 一起使用...这是 C99,您需要包含
<inttypes.h>
strtoll
将其转换为long long
,通常是 64 位 int。
Doing this 100% portably is a little bit tricky. 100% 可移植地执行此操作有点棘手。
long long
is required to be at least 64 bits, but need not necessarily be twos complement, so it might not be able to represent -0x7fffffffffffffff-1
, and thus using strtoll
could have a broken corner case. long long
要求至少为 64 位,但不一定是二进制补码,因此它可能无法表示-0x7fffffffffffffff-1
,因此使用strtoll
可能会出现坏的情况。 The same issue applies to strtoimax
.同样的问题适用于
strtoimax
。 What you could do instead is consume leading space (if you want to allow leading space) and check for the sign first, then use strtoull
or strtoumax
, either of which is required to support values up to the full positive range of int64_t
.您可以做的是消耗前导空间(如果您想允许前导空间)并首先检查符号,然后使用
strtoull
或strtoumax
,这两者都需要支持高达int64_t
的完整正范围的值。 You can then apply the sign:然后,您可以应用该标志:
unsigned long long x = strtoull(s, 0, 0);
if (x > INT64_MAX || ...) goto error;
int64_t y = negative ? -(x-1)-1 : x;
This logic is written to avoid all overflow cases.编写此逻辑是为了避免所有溢出情况。
Users coming from a web search should also consider std::stoll
.来自网络搜索的用户也应该考虑
std::stoll
。
It doesn't strictly answer this original question efficiently for a const char*
but many users will have a std::string
anyways.对于
const char*
它并没有严格有效地回答这个原始问题,但许多用户无论如何都会有一个std::string
。 If you don't care about efficiency you should get an implicit conversion (based on the user-defined conversion using the single-argument std::string
constructor) to std::string
even if you have a const char*
.如果您不关心效率,即使您有
const char*
也应该获得隐式转换(基于使用单参数std::string
构造函数的用户定义转换)到std::string
。
It's simpler than std::strtoll
which will always require 3 arguments.它比
std::strtoll
更简单,后者总是需要 3 个参数。
It should throw if the input is not a number, but see these comments .如果输入不是数字,它应该抛出,但请参阅这些评论。
This worked for me with a different int64 type, and I like the clean C++ style:这对我使用了不同的 int64 类型,我喜欢干净的 C++ 风格:
std::istringstream iss(argv[i]);
int64_t i64;
iss >> i64;
You may get an compile error: operartor<<... is not defined.您可能会收到编译错误:operartor<<... 未定义。
And I don't know what happens, if argv[i] contains "HALLO".如果 argv[i] 包含“HALLO”,我不知道会发生什么。
How to convert string to int64_t?
如何将字符串转换为 int64_t?
The simplest最简单的
#include <stdlib.h>
int64_t value = atoll(some_string); // lacks error checking. UB on overflow
Better更好的
long long v = strtoll(s, NULL, 0); // No reported errors, well defined on overflow
Robust: Create a helper function to detect all problems.健壮:创建一个辅助函数来检测所有问题。
#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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.