printf + uint_64 على Solaris 9؟
سؤال
لدي بعض رمز 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.