سؤال

لدي بعض رمز C (++) الذي يستخدم SprintF لتحويل UINT_64 إلى سلسلة. هذا يجب أن يكون محمولًا لكل من Linux و Solaris.

على Linux نستخدم ٪ Ju ، ولكن لا يبدو أن هناك أي مكافئ على Solaris. الأقرب الذي يمكنني العثور عليه هو ٪ LU ، ولكن هذا ينتج إخراج غير صحيح. بعض رمز العينة:

#include <stdio.h>
#include <sys/types.h>

#ifdef SunOS
typedef uint64_t u_int64_t;
#endif

int main(int argc, char **argv) {
    u_int64_t val = 123456789123L;

#ifdef SunOS
    printf("%lu\n", val);
#else
    printf("%ju\n", val);
#endif
}

على Linux ، الناتج كما هو متوقع ؛ على Solaris 9 (لا تسأل) ، إنه "28"

ماذا يمكنني استخدام؟

هل كانت مفيدة؟

المحلول

إذا كان لديك inttypes.h ، فيمكنك استخدام وحدات الماكرو التي توفرها:

printf(  "%" PRIu64 "\n", val);

ليست جميلة (يبدو أنني أقول ذلك كثيرًا مؤخرًا) ، لكنها تعمل.

نصائح أخرى

على نظام متوافق C99:

#include <inttypes.h>

uint64_t big = ...;
printf("%" PRIu64 "\n", big);

انظر القسم 7.8 من معيار C99.

المحددات هي {pri ، scn} [diouxx] {n ، unsernn ، max ، fastn ، ptr}

عندما تكون PRI لعائلة printf () ، فإن SCN مخصصة لعائلة Scanf () ، D و I لأنواع لا يتجزأ الموقعة ؛ o ، u ، x ، x هي لأنواع متكاملة غير موقعة مثل الثمن ، العشري ، السداسي ، و hex ؛ N هي واحدة من العروض المدعومة. على الأقل وسريعة تتوافق مع تلك المعدلات. PTR هو ل intptr_t ؛ و Max هو ل Intmax_T.

تعتمد الإجابة على ما إذا كان الرمز الخاص بك هو C أو C ++ بالفعل. في C ، يجب أن تستخدم unsigned long long بدلاً من نوع آخر (هذا يتوافق مع المعيار الحالي ، و long long شائع جدًا فيما يتعلق بدعم C99) ، إلحاق ULL بدلاً من L إلى ثابت ، واستخدام (كما ذكر) %llu كحديد الخاص بك. إذا لم يكن هناك دعم لـ C99 ، فقد ترغب في التحقق من وثائق المترجم ، حيث لا توجد طريقة قياسية أخرى للقيام بذلك. long long تم ضغوطه ليكون 64 بت على الأقل.

يمكنك استخدام %llu لفترة طويلة. ومع ذلك ، هذا ليس محمولًا جدًا أيضًا ، لأن long long ليس مضمون أن يكون 64 بت. :-)

يمكنك الحصول uint64_t من stdint.h إذا كنت ترغب في تجنب typedef الشرطي Sunos.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top