簡體   English   中英

如何將字符串轉換為 int64_t?

[英]How to convert string to int64_t?

如何將程序參數從argv轉換為int64_t atoi()僅適用於 32 位整數。

符合 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;
}

有幾種方法可以做到:

  strtoll(str, NULL, 10);

這是符合 POSIX C99 的。

你也可以使用 strtoimax; 它具有以下原型:

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

這很好,因為它始終與本地 intmax_t 一起使用...這是 C99,您需要包含<inttypes.h>

strtoll將其轉換為long long ,通常是 64 位 int。

100% 可移植地執行此操作有點棘手。 long long要求至少為 64 位,但不一定是二進制補碼,因此它可能無法表示-0x7fffffffffffffff-1 ,因此使用strtoll可能會出現壞的情況。 同樣的問題適用於strtoimax 您可以做的是消耗前導空間(如果您想允許前導空間)並首先檢查符號,然后使用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;

編寫此邏輯是為了避免所有溢出情況。

來自網絡搜索的用戶也應該考慮std::stoll

對於const char*它並沒有嚴格有效地回答這個原始問題,但許多用戶無論如何都會有一個std::string 如果您不關心效率,即使您有const char*也應該獲得隱式轉換(基於使用單參數std::string構造函數的用戶定義轉換)到std::string

它比std::strtoll更簡單,后者總是需要 3 個參數。

如果輸入不是數字,它應該拋出,但請參閱這些評論

這對我使用了不同的 int64 類型,我喜歡干凈的 C++ 風格:

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

您可能會收到編譯錯誤:operartor<<... 未定義。

如果 argv[i] 包含“HALLO”,我不知道會發生什么。

如何將字符串轉換為 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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM