C में int64_t टाइप कैसे प्रिंट करें


298

C99 मानक में बाइट्स आकार के साथ पूर्णांक प्रकार जैसे कि int64_t है। मैं निम्नलिखित कोड का उपयोग कर रहा हूं:

#include <stdio.h>
#include <stdint.h>
int64_t my_int = 999999999999999999;
printf("This is my_int: %I64d\n", my_int);

और मुझे यह संकलक चेतावनी मिली:

warning: format ‘%I64d expects type int’, but argument 2 has type int64_t

मैंने कोशिश की:

printf("This is my_int: %lld\n", my_int); // long long decimal

लेकिन मुझे वही चेतावनी मिलती है। मैं इस संकलक का उपयोग कर रहा हूँ:

~/dev/c$ cc -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5664~89/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5664)

चेतावनी के बिना my_int चर को प्रिंट करने के लिए मुझे किस प्रारूप का उपयोग करना चाहिए?


जवाबों:


419

के लिए int64_tटाइप करें:

#include <inttypes.h>
int64_t t;
printf("%" PRId64 "\n", t);

के लिए uint64_tटाइप करें:

#include <inttypes.h>
uint64_t t;
printf("%" PRIu64 "\n", t);

आप PRIx64हेक्साडेसिमल में प्रिंट करने के लिए भी उपयोग कर सकते हैं ।

cppreference.com में सभी प्रकार के intptr_t( सहित PRIxPTR) के लिए उपलब्ध मैक्रो की पूरी सूची है । स्कैनफ के लिए अलग मैक्रोज़ हैं, जैसे SCNd64


PRIu16 की एक विशिष्ट परिभाषा होगी "hu", इसलिए संकलित स्ट्रिंग-निरंतर संयोजन संकलन समय पर होता है।

आपके कोड के पूरी तरह से पोर्टेबल होने के लिए, आपको PRId32प्रिंटिंग के लिए उपयोग करना होगा int32_t, और "%d"प्रिंटिंग के लिए या इसी तरह int


18
स्थूल स्थिरांक की पूरी सूची: en.cppreference.com/w/cpp/types/integer
मसूद खारी

12
और, अगर लिनक्स पर C ++ का उपयोग कर रहे हैं, तो #define __STDC_FORMAT_MACROSइसमें शामिल होने से पहले सुनिश्चित करें inttypes.h
सीएसएल

17
PRId64एक मैक्रो है जो आंतरिक रूप से अनुवाद करता है "lld"। इसलिए, यह लिखने printf("%lld\n", t);के रूप में अच्छा है विवरण देखें: qnx.com/developers/docs/6.5.0/…
गौरव

24
@ गौरव, यह कुछ प्लेटफार्मों पर सच है, लेकिन सभी पर नहीं। उदाहरण के लिए, मेरे amd64 लिनक्स मशीन पर, PRId64 को परिभाषित किया गया है ld। पोर्टेबिलिटी मैक्रो का कारण है।
एथन टी

10
मुझे लगता है कि कुछ अतिरिक्त प्रयास से वे इसे और भी अधिक अप्रिय बना सकते थे
पावेल पी

65

C99 तरीका है

#include <inttypes.h>
int64_t my_int = 999999999999999999;
printf("%" PRId64 "\n", my_int);

या आप कास्ट कर सकते थे!

printf("%ld", (long)my_int);
printf("%lld", (long long)my_int); /* C89 didn't define `long long` */
printf("%f", (double)my_int);

यदि आप C89 कार्यान्वयन (विशेष रूप से विज़ुअल स्टूडियो) के साथ फंस गए हैं, तो आप शायद एक खुले स्रोत <inttypes.h>(और <stdint.h>) का उपयोग कर सकते हैं : http://code.google.com/p/msinttypes/


जब msinttypes का उपयोग code.google.com लिंक से किया जाता है, तो मुझे __STDC_FORMAT_MACROS को परिभाषित करना होगा। Stackoverflow.com/questions/8132399/how-to-printf-uint64-t देखें ।
ariscris

सिर के लिए धन्यवाद, @ariscris। ऐसा प्रतीत होता है कि मैक्रो केवल C ++ के लिए आवश्यक है। लिंक किए गए कोड में परिभाषाएं एक#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
पीएमजी

19

C99 के साथ %jलंबाई संशोधक भी प्रकार के मूल्यों को मुद्रित करने के लिए कार्यों की printf परिवार के साथ इस्तेमाल किया जा सकता int64_tऔर uint64_t:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
    int64_t  a = 1LL << 63;
    uint64_t b = 1ULL << 63;

    printf("a=%jd (0x%jx)\n", a, a);
    printf("b=%ju (0x%jx)\n", b, b);

    return 0;
}

इस कोड को संकलित करने से gcc -Wall -pedantic -std=c99कोई चेतावनी नहीं मिलती है, और प्रोग्राम अपेक्षित आउटपुट प्रिंट करता है:

a=-9223372036854775808 (0x8000000000000000)
b=9223372036854775808 (0x8000000000000000)

इस के अनुसार है printf(3)मेरी Linux सिस्टम पर (आदमी पेज विशेष रूप से कहा गया है कि jएक को ही रूपांतरण इंगित करने के लिए प्रयोग किया जाता है intmax_tया uintmax_t, मेरे stdint.h में, दोनों int64_tऔर intmax_tठीक उसी तरह, और इसी के लिए में typedef'd कर रहे हैं uint64_t)। मुझे यकीन नहीं है कि यह अन्य प्रणालियों के लिए पूरी तरह से पोर्टेबल है।


12
यदि %jdprnts intmax_t, सही आह्वान होगा printf("a=%jd (0x%jx)", (intmax_t) a, (intmax_t) a)। इसकी कोई गारंटी नहीं है कि है int64_tऔर intmax_tएक ही प्रकार के हैं, और यदि वे नहीं हैं, व्यवहार अपरिभाषित है।
user4815162342

4
आप portably उपयोग कर सकते हैं %jdमुद्रित करने के लिए int64_tमूल्यों को अगर आप उन्हें स्पष्ट करने के लिए कनवर्ट intmax_tकरने के लिए उन्हें पार करने से पहले printf: printf("a=%jd\n", (intmax_t)a)। यह (IMHO) <inttypes.h>मैक्रोज़ की बदसूरती से बचा जाता है । बेशक यह मानता है कि अपने कार्यान्वयन का समर्थन करता है %jd, int64_tऔर intmax_tहै, जो सभी C99 द्वारा जोड़ा गया था।
कीथ थॉम्पसन

2
@KeithThompson 'Ugliness' इसे अब तक बहुत दूर तक दयालु दोस्त बना रहा है। यह बिलकुल छिपा हुआ है। यह भयावह है। यह अशुभ है। यह शर्मनाक है कि यह क्या है। या कम से कम उन्हें शर्मिंदा होना चाहिए, बहुत कुछ जिसने इसे पेश किया। मैंने कभी इन मैक्रों को नहीं देखा है, लेकिन यह जवाब और टिप्पणी - आपका शामिल - सुझाव क्या करते हैं।
22

@Pryftan मैं नहीं है काफी उन्हें काफी के रूप में बदसूरत आप कर के रूप में लगता है - और मैं सभी को यकीन है कि वे किस तरह की भाषा परिवर्तन के बिना एक कम बदसूरत ढंग से परिभाषित किया जा सकता है पर नहीं हूँ।
कीथ थॉम्पसन

@KeithThompson वैसे मैं शुक्रगुज़ार हूं कि आपने कम से कम 'काफी' शब्द पर जोर दिया। वास्तव में इससे कोई फर्क नहीं पड़ता। मैं यह नहीं देखता कि मैक्रों को वहाँ क्यों होना है। जैसा कि आप कहते हैं कि आप आंशिक रूप से कर सकते हैं ... आदि। लेकिन फिर मुझे यह भी पता चलता है कि कीवर्ड की संख्या में वृद्धि हाथ से बाहर हो गई है।
प्रातः

12

एम्बेडेड दुनिया से आ रहा है, जहां यूक्लिब भी हमेशा उपलब्ध नहीं है, और जैसे कोड

uint64_t myval = 0xdeadfacedeadbeef; printf("%llx", myval);

क्या आप बकवास कर रहे हैं या बिल्कुल काम नहीं कर रहे हैं - मैं हमेशा एक छोटे सहायक का उपयोग करता हूं, जो मुझे ठीक से डंप करने की अनुमति देता है:

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

char* ullx(uint64_t val)
{
    static char buf[34] = { [0 ... 33] = 0 };
    char* out = &buf[33];
    uint64_t hval = val;
    unsigned int hbase = 16;

    do {
        *out = "0123456789abcdef"[hval % hbase];
        --out;
        hval /= hbase;
    } while(hval);

    *out-- = 'x', *out = '0';

    return out;
}

यदि आप एक एम्बेडेड एप्लिकेशन के लिए इस समस्या का सामना कर रहे हैं, तो यह वही है जो आप देख रहे हैं। इस समाधान ने मेरे लिए काम किया। Thnx @ataraxic।
लोगन859

8

विंडोज़ वातावरण में, का उपयोग करें

%I64d

लिनक्स में, उपयोग करें

%lld

18
%lldके लिए प्रारूप है long long int, जो जरूरी नहीं के रूप में ही है int64_t<stdint.h>के लिए सही प्रारूप के लिए एक मैक्रो है int64_t; देख ouah का जवाब
कीथ थॉम्पसन

@KeithThompson हालांकि, चूंकि long longकम से कम 64-बिट है, इसलिए printf("%lld", (long long)x);काम करना चाहिए, शायद -0x8000000000000000 के लिए छोड़कर, जो long longकि प्रतिनिधित्व करने योग्य नहीं हो सकता है क्योंकि वह प्रकार दो के पूरक का उपयोग नहीं कर रहा है।
पास्कल कुओक

@ पास्कलुक: हाँ, इसे कलाकारों के साथ काम करना चाहिए (और आपके द्वारा उल्लिखित अपवाद बहुत ही संभावना नहीं है, केवल एक सिस्टम पर लागू होता है जो दो-पूरक का समर्थन करता है लेकिन इसके लिए उपयोग नहीं करता है long long)।
कीथ थॉम्पसन

-3

//VC6.0 (386 और बेहतर)

    __int64 my_qw_var = 0x1234567890abcdef;

    __int32 v_dw_h;
    __int32 v_dw_l;

    __asm
        {
            mov eax,[dword ptr my_qw_var + 4]   //dwh
            mov [dword ptr v_dw_h],eax

            mov eax,[dword ptr my_qw_var]   //dwl
            mov [dword ptr v_dw_l],eax

        }
        //Oops 0.8 format
    printf("val = 0x%0.8x%0.8x\n", (__int32)v_dw_h, (__int32)v_dw_l);

सादर।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.