web-dev-qa-db-ja.com

文字列をint64_tに変換する方法は?

プログラムパラメータをargvから_int64_t_に変換する方法atoi()は、32ビット整数にのみ適しています。

18
pmichna

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;
}
12
chux

それを行うにはいくつかの方法があります:

  strtoll(str, NULL, 10);

これはPOSIX C99に準拠しています。

strtoimaxを使用することもできます。次のプロトタイプがあります。

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

常にローカルのintmax_tで動作するため、これは素晴らしいです。これはC99であり、<inttypes.h>を含める必要があります。

10
Ahmed Masud

Web検索から来たユーザーも std::stoll を検討する必要があります。

const char*については、この元の質問に効率的に厳密に回答するわけではありませんが、とにかく多くのユーザーがstd::stringを使用します。効率を気にしない場合は、std::stringがある場合でも、(単一引数std::stringコンストラクターを使用したユーザー定義の変換に基づく)const char*への暗黙的な変換を取得する必要があります。

これは std::strtoll よりも簡単で、常に3つの引数が必要になります。

入力が数値でない場合はスローする必要がありますが、 これらのコメント を参照してください。

2
davidvandebunte

これを100%移植性のある方法で行うには、少し注意が必要です。 long longは少なくとも64ビットである必要がありますが、必ずしも2の補数である必要はないため、-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;

このロジックは、すべてのオーバーフローのケースを回避するために作成されています。

2
R..

strtoll は、通常64ビットの整数であるlong longに変換します。

2
Kninnug

これは別のint64型で私のために働きました、そして私はきれいなC++スタイルが好きです:

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

コンパイルエラーが発生する場合があります:operartor << ...が定義されていません。

そして、argv [i]に "HALLO"が含まれている場合、どうなるかわかりません。

1
Fritz Pom