argv
からint64_t
にプログラムパラメータを変換する方法はありますか? atoi()
は32ビット整数にのみ適しています。文字列をint64_tに変換するには?
答えて
A 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は 'sscanf'を使うという賢明な考え方ですが、あなたが必要とするのは' PRId64'ではなく 'SCNd64'です。私はまた、 'sscanf'がオーバーフローでうまく動作しなければならないかどうか不明です。 –
@R .. 'scanf()'ファミリは 'strtol()'のような機能を持つように指定されていると思います。後者の場合、範囲エラーによって 'eranno'に' ERANGE'が格納されます。 (C11ドラフト7.8.2.3.3)。したがって、 'errno'テストを組み込むことができます。 – chux
@chux本当ですか? [this](http://pubs.opengroup.org/onlinepubs/009604599/basedefs/inttypes.h.html)によると 'SCNd64'は' scanf'、 'PRId64'は' printf'です。 – pmichna
strtoll
は、通常は64ビットのintであるlong long
に変換されます。
それを行うには、いくつかの方法があります。
strtoll(str, NULL, 10);
これは、POSIX C99の準拠しています。
strtoimaxも使用できます。次のプロトタイプ持っている:それは常にローカルintmax_t型で動作しますので、
strtoimax(const char *str, char **endptr, int base);
これはいいです...これはC99ですが、あなたはこの100%をやっ<inttypes.h>
そのキャストの必要はありません... –
@OliCharlesworthあなたは正しいですが、キャストは、OPがそれを解析したい場合、ヒントとして、文字列へのポインタで置き換えることができますすべて。 –
@AhmedMasudそれがドキュメントの目的です。あるいはコメントかもしれない。余計なキャストを入れてはいけません。重複していて、隠れエラーを隠すかもしれません。**最も重要なのは、読みやすさが低下することです。** –
を含める必要がポータブルに少しはありますトリッキー。 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;
このロジックは、すべてのオーバーフローケースを避けるために書かれています。
しかし、 'int64_t'は2の補数とは異なる符号付き表現を持つシステムで定義されているとは限りません。また、これは、整数型の整数型がオプションである主な理由の1つと考えられます。 – ouah
私はPOSIXが必要と思っていましたが、実際にはPOSIXは8,16,32ビットの正確なサイズの型しか必要としません。 'int64_t'と' uint64_t'はPOSIXではオプションです。ですから、 'long'や' long long'が適切でないシステムでは、 'int64_t'が存在しそうにないと私は同意します。 –
「すべてのオーバーフローのケースを避けるためにロジックがどのように書かれているか」は不明です。 ' - (x-1)-1'や' -x'は 'x'と同じ働きをします。 – chux
- 1. int64_tをtime_durationに変換する
- 2. int64_tをdoubleに変換する
- 3. 文字列[]を文字列に変換するには?
- 4. C - 文字列(文)を文字列リストに変換する
- 5. 文字列をJavaの文字列配列に変換する
- 6. intを文字列に変換する方法doubleを文字列に変換するには?
- 7. Pythonは文字列リテラルを文字列に変換します
- 8. 文字列配列要素を文字列に変換するには?
- 9. 文字配列を文字列配列に変換するには?
- 10. 文字列をJavaの文字列配列に変換するには?
- 11. バイナリ文字列をテキスト文字列に変換する
- 12. 文字列を一連の文字列に変換する
- 13. 文字列を文字列に変換する
- 14. 文字列[] []を文字列に変換する
- 15. jsonの文字列をJavaの文字列に変換する
- 16. 文字列を文字列に変換する
- 17. Pythonの文字列リストを文字列に変換する
- 18. C++文字列[4]を文字列に変換する
- 19. 狭い文字列をワイド文字列に変換する
- 20. []文字列を...文字列に変換する方法
- 21. 文字列を文字列に変換する
- 22. Haskellの文字列を文字列に変換する
- 23. JavaFX文字列を文字列に変換する
- 24. 文字列を文字配列に変換する
- 25. 文字列をオプションに変換する[文字列]
- 26. JavaScript文字列をハッシュ文字列に変換する
- 27. ユニコード文字列をバイト文字列に変換する
- 28. ASCIIの文字列を文字列に変換する
- 29. 文字列と文字列をgettextに変換するPO
- 30. 標準のC++文字列を文字列に変換する^
'int64_t'が' long'と同じプラットフォームでは、すばやくハッキリなやり方は['atol()'](http://en.cppreference.com/w)です。/c/string/byte/atoi)。 –
int64_tに一致する指定子でsscanfを使用すると、プラットフォームに依存しない方法が提供されます。 – chux
ちょっとしたポイント:あなたが求めているのは、 'char *'を 'int64_t'に変換する方法ではありません(単純なキャストは答えになります)。代わりに' char * 'は、十進数の文字列のような人間指向のテキスト形式の数値を' int64_t'に変換します。 –