printf を使用して unsigned long long int をフォーマットするにはどうすればよいですか?
-
08-06-2019 - |
質問
#include <stdio.h>
int main() {
unsigned long long int num = 285212672; //FYI: fits in 29 bits
int normalInt = 5;
printf("My number is %d bytes wide and its value is %ul. A normal number is %d.\n", sizeof(num), num, normalInt);
return 0;
}
出力:
My number is 8 bytes wide and its value is 285212672l. A normal number is 0.
この予期せぬ結果は、 unsigned long long int
. 。どうやって printf()
の unsigned long long int
?
解決
u (符号なし) 変換では、ll (el-el) long-long 修飾子を使用します。(Windows、GNU で動作します)。
printf("%llu", 285212672);
他のヒント
次のような型を提供する inttypes.h ライブラリを使用してみるとよいでしょう。int32_t
, int64_t
, uint64_t
等その後、次のようなマクロを使用できます。
uint64_t x;
uint32_t y;
printf("x: %"PRId64", y: %"PRId32"\n", x, y);
これは、同じ問題が発生しないことが「保証」されています。 long
, unsigned long long
各データ型のビット数を推測する必要がないためです。
%d
--> のための int
%u
--> のための unsigned int
%ld
--> のための long int
%lu
--> のための unsigned long int
%lld
--> のための long long int
%llu
--> のための unsigned long long int
MSVS を使用する Long Long (または __int64) の場合は、%I64d を使用する必要があります。
__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b); //I is capital i
これは、%llu が Windows では適切に動作せず、%d が 64 ビット整数を処理できないためです。代わりに PRIu64 を使用することをお勧めします。これは Linux にも移植可能であることがわかります。
代わりにこれを試してください:
#include <stdio.h>
#include <inttypes.h>
int main() {
unsigned long long int num = 285212672; //FYI: fits in 29 bits
int normalInt = 5;
/* NOTE: PRIu64 is a preprocessor macro and thus should go outside the quoted string. */
printf("My number is %d bytes wide and its value is %" PRIu64 ". A normal number is %d.\n", sizeof(num), num, normalInt);
return 0;
}
出力
My number is 8 bytes wide and its value is 285212672. A normal number is 5.
Linuxではそれは %llu
そしてWindowsではそれは %I64u
Windows 2000 では動作しないことがわかりましたが、バグがあるようです。
VS2005 を使用して x64 としてコンパイルします。
%llu はうまく機能します。
標準外のものは常に奇妙です:)
GNUの下の長い部分については、それはそうです L
, ll
または q
そして窓の下にあると思います ll
のみ
16 進数:
printf("64bit: %llp", 0xffffffffffffffff);
出力:
64bit: FFFFFFFFFFFFFFFF
何年も前に人々が書いたものに加えて:
- gcc/mingw で次のエラーが発生する可能性があります。
main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("%llu\n", k);
その場合、mingw のバージョンはデフォルトで c99 になりません。次のコンパイラ フラグを追加します。 -std=c99
.
そうですね、1 つの方法は、VS2008 で x64 としてコンパイルすることです。
これは期待どおりに実行されます。
int normalInt = 5;
unsigned long long int num=285212672;
printf(
"My number is %d bytes wide and its value is %ul.
A normal number is %d \n",
sizeof(num),
num,
normalInt);
32 ビット コードの場合は、正しい __int64 形式指定子 %I64u を使用する必要があります。ということになります。
int normalInt = 5;
unsigned __int64 num=285212672;
printf(
"My number is %d bytes wide and its value is %I64u.
A normal number is %d",
sizeof(num),
num, normalInt);
このコードは、32 ビットと 64 ビットの両方の VS コンパイラで機能します。
どうやら、マルチプラットフォーム* ソリューションを考え出した人は誰もいないようです。 10年以上 2008 年以来なので、私のものを追加します 😛。賛成票をお願いします。(冗談です。私は気にしない。)
解決: lltoa()
使い方:
#include <stdlib.h> /* lltoa() */
// ...
char dummy[255];
printf("Over 4 bytes: %s\n", lltoa(5555555555, dummy, 10));
printf("Another one: %s\n", lltoa(15555555555, dummy, 10));
OPの例:
#include <stdio.h>
#include <stdlib.h> /* lltoa() */
int main() {
unsigned long long int num = 285212672; // fits in 29 bits
char dummy[255];
int normalInt = 5;
printf("My number is %d bytes wide and its value is %s. "
"A normal number is %d.\n",
sizeof(num), lltoa(num, dummy, 10), normalInt);
return 0;
}
とは異なり、 %lld
フォーマット文字列を印刷します。これは私にとってはうまくいきます Windows 上の 32 ビット GCC の下で。
*) 良い、 ほとんど マルチプラットフォーム。MSVC では、明らかに必要です _ui64toa()
の代わりに lltoa()
.