unix 如何将字符串转换为int64_t?

gmol1639  于 2022-11-04  发布在  Unix
关注(0)|答案(7)|浏览(253)

如何将程序参数从argv转换为int64_tatoi()仅适用于32位整数。

rjjhvcjd

rjjhvcjd1#

有几种方法可以做到这一点:

strtoll(str, NULL, 10);

这与POSIX C99兼容。
您还可以使用strtoimax;其具有如下原型:

strtoimax(const char *str, char**endptr, int base);

这很好,因为它将始终与本地intmax_t一起工作...这是C99,您需要包含<inttypes.h>

iovurdzv

iovurdzv2#

一次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;
}
k75qkfdt

k75qkfdt3#

来自网络搜索的用户也应该考虑std::stoll
对于const char*,它并没有严格有效地回答这个原始问题,但许多用户无论如何都会有一个std::string。如果你不关心效率,你应该得到一个隐式转换(基于用户定义的转换,使用单参数std::string构造函数)到std::string,即使你有一个const char*
它比std::strtoll简单,std::strtoll总是需要3个参数。
如果输入的不是数字,它应该会掷回,但请参阅这些注解。

gzszwxb4

gzszwxb44#

strtoll将其转换为long long,它通常是64位int。

ltskdhd1

ltskdhd15#

100%可移植地实现这一点有点棘手。long long要求至少为64位,但不一定是二进制补码,因此它可能无法表示-0x7fffffffffffffff-1,因此使用strtoll时可能会有一个不完整的角大小写。(如果要允许前导空格)并首先检查符号,然后使用strtoullstrtoumax,这两种方法都需要支持最大为int64_t的整个正值范围的值。然后可以应用符号:

unsigned long long x = strtoull(s, 0, 0);
if (x > INT64_MAX || ...) goto error;
int64_t y = negative ? -(x-1)-1 : x;

编写此逻辑是为了避免所有溢出情况。

a11xaf1n

a11xaf1n6#

如何将字符串转换为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.

Robust:创建一个帮助函数来检测所有问题。


# 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 trailing white-space
    endptr++;
  }
  if (*endptr) { // Non-numeric trailing text
    return true;
  }
  return false; // no error
}
5tmbdcev

5tmbdcev7#

这对我使用不同的int64类型是有效的,我喜欢干净的C++风格:

std::istringstream iss(argv[i]);
int64_t i64;
iss >> i64;

您可能会收到编译错误:运算符〈〈...未定义。
如果argv[i]包含“HALLO”,我不知道会发生什么。

相关问题