どのようにprintfを使用してunsigned long long intをフォーマットしますか?


379
#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どうですか?


2
コードを(%lluを使用して)gccでコンパイルしたところ、出力は正しいものでした。コンパイラーにオプションを渡しますか?
フアン

2
:サムスンバダのnewlibのは「%のLLD」をサポートしていないと思われることを注意developer.bada.com/forum/...
RZR


stdint.hを使用して、変数のビット数を明示することをお勧めします。32ビットアーキテクチャと64ビットアーキテクチャの間の移行期にあります。「unsigned long long int」は、両方で同じことを意味するわけではありません。
BDはRivenhillで

回答:


483

ll(el-el)long-long修飾子をu(符号なし)変換とともに使用します。(Windows、GNUで動作)。

printf("%llu", 285212672);

11
正確には、それはGNU libc用であり、MicrosoftのCランタイムでは動作しません。
Mark Ba​​ker、

168
これはLinux / UNIXのものではありません。「ll」の長さ修飾子がC99の標準Cに追加されました。「Microsoft C」で機能しない場合は、標準に準拠していないためです。
ロバートギャンブル、

12
VS2008で動作します。さらに、私が覚えている限り、MS Cコンパイラー(ストレートCをコンパイルするように設定されている場合)は、設計によりC90に準拠しているはずです。C99は、誰もが好きではないいくつかのことを紹介しました。
スーパーファミコン

6
ここで覚えておくべきことの1つは、複数のlong long引数を渡して、そのうちの1つに間違った形式printf使用している場合、たとえばの%d代わりに%lld、間違った引数のに出力された引数でさえ完全にオフになる(またはprintfクラッシュする可能性さえある)ことです。 )。基本的に、可変引数はタイプ情報なしでprintfに渡されるため、フォーマット文字列が正しくない場合、結果は予測できません。
dmitrii

1
ハードハーブサッター氏はインタビューで、Microsoftの顧客はC99を求めていないため、純粋なCコンパイラはC90で凍結されていると述べています。これは、Cとしてコンパイルする場合に当てはまります。C++としてコンパイルする場合は、他の人が上記のように言っても問題ないはずです。
ahcox 2012

90

あなたはあなたのような種類を与えるinttypes.hライブラリを使用して試してみたいことがあり int32_tint64_tuint64_tなどあなたが、その後のようなそのマクロを使用することができます。

uint64_t x;
uint32_t y;

printf("x: %"PRId64", y: %"PRId32"\n", x, y);

これは、各データ型のビット数を推測する必要がないためlongunsigned long longなどと同じ問題が発生しないように「保証」されています。


これらの場所PRId64PRId32マクロは定義されましたか?
happy_marmoset 2013

4
@happy_marmoset:それらは次のように定義されていますinttypes.h
Nathan

4
私はあなたが必要だと思うPRIu64し、PRIu32符号なし整数のために。
Lasse Kliemann、2016年

1
あるinttypes.h標準?それはありませんstdint.hか?
MD XF 2017年

2
これらの正確な幅の整数型を持たないアーキテクチャが世の中にあるため、これらの正確な幅のタイプはオプションであることに注意してください。のみと(実際には、示さより広くてもよい)のタイプが必須です。leastXfastX
DevSolar

78

%d->の int

%u->の unsigned int

%ld-> long intまたはlong

%lu-> unsigned long intまたはlong unsigned intまたはunsigned long

%lld-> long long intまたはlong long

%llu-> unsigned long long intまたはunsigned long long


表示する桁数、%lldまたは%lluの左揃えまたは右揃えなどの形式指定子はありますか?
Asam Padeh

40

MSVSを使用するlong long(または__int64)の場合、%I64dを使用する必要があります。

__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b);    //I is capital i

37

これは、%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.

PRIu64への参照のための+1。これは私が見たことがないものですが、PRIu64が「llu」ではなく「lu」に拡張されるため、64ビットLinuxには移植性がないようです。
BDがRivenhillで

8
そして、なぜそれが悪いのでしょうか?64ビットLinuxでは、Windowsを除く他のすべてのOSと同様に、longは64ビット値です。
2012年

@BDatRivenhill Linux / Unixは、長さが64ビットのLP64を使用します
phuclv 2014

1
しかし、それはよりポータブル、使用するようにするint64_tだけでなく、長いよりも長い長い大きなでいくつかの実装があるかもしれないので、代わりに
phuclv

これが一番上に!-1つの小さな更新:エラー:リテラルの無効なサフィックス。C ++ 11では、リテラルと識別子の間にスペースが必要です[-Wreserved-user-defined-literal]
tofutim

14

Linuxでは%lluWindows、Windowsでは%I64u

Windows 2000では動作しないことがわかりましたが、バグがあるようです。


Windowsの場合(または少なくとも、WindowsのMicrosoft Cコンパイラの場合)、%I64d、%I32u、および%I32dもあります
JustJeff

1
Windows 2000と何が関係していますか?Cライブラリは、printfを処理するライブラリです。
CMircea

1
私が観察したものだけです。私はこの構造を使用するアプリを書きましたが、WinXPでは完全に動作しましたが、Win2kではゴミを吐き出しました。たぶん、Cライブラリがカーネルに対して行っているシステムコールに関係しているのかもしれませんし、Unicodeに関係しているのかもしれません。_i64tot()などを使用して回避する必要があったことを覚えています。
アダムピアース

7
MSが「革新の自由」を再び行使しているように聞こえる... ;-)
Dronz

Win2k / Win9xの問題は、unsigned long longデータタイプが比較的新しい(当時はC99標準)が、C89仕様のみをサポートしていた古いMicrosoft Cランタイムを利用するCコンパイラ(MinGW / GCCを含む)が原因である可能性があります。私は本当に古くてかなり最近のWindows APIドキュメントにしかアクセスできません。そのため、I64uサポートがいつドロップされたかを正確に述べることは困難です。しかし、それはXP時代のように思えます。
veganaiZe

8

VS2005でx64としてコンパイルします。

%lluはうまく機能します。


3

人々が何年も前に書いたものに加えて:

  • あなたはgcc / mingwでこのエラーを受け取るかもしれません:

main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]

printf("%llu\n", k);

その場合、お使いのmingwのバージョンはデフォルトでc99になりません。このコンパイラフラグを追加します-std=c99


3

どうやら、2008 から10年以上にわたってマルチプラットフォーム*ソリューションを思い付いた人はいないので、私は😛を付け加えます。Plz upvote。(冗談です。私は気にしません。)

解決: 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()


1
私は持っていませんlltoa
Antti Haapala

1

非標準のものは常に奇妙です:)

GNUでの長い部分はLllまたはq

そして窓の下ではそれllだけだと思います


1

16進数:

printf("64bit: %llp", 0xffffffffffffffff);

出力:

64bit: FFFFFFFFFFFFFFFF

非常に素晴らしい!16進表記でそれを取得する方法を考えていました
0xAK

しかし、ほとんどすべてのC ++およびCコンパイラは警告を出します:警告: 'll'長さ修飾子と 'p'タイプ文字の使用[-Wformat =]
Seshadri R

2
この完全に壊れた答えは、二重に定義されていない振る舞いをしていて、質問に答えることさえしません
Antti Haapala

@AnttiHaapalaこの回答は二重に定義されていない動作で完全に壊れていると言いますが、詳しく説明してもらえますか、それとも削除しますか?それとも良い悪い例としてそれを保ちますか?
lama12345

0

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コンパイラで機能します。


「285212672」の代わりに実際の64ビットの数値を試してください。最初の例が正しく実行され、ターゲットにコンパイルされているとは思いません。
dyasta 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.