كيف يمكنك تنسيق int طويل غير موقع باستخدام printf؟
-
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
?
المحلول
استخدم المعدِّل ll (el-el) الطويل مع التحويل u (غير الموقع).(يعمل في ويندوز، جنو).
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
لفترة طويلة (أو __int64) باستخدام MSVS، يجب عليك استخدام %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.
في لينكس هو عليه %llu
وفي ويندوز هو عليه %I64u
على الرغم من أنني وجدت أنه لا يعمل في نظام التشغيل Windows 2000، يبدو أن هناك خطأ ما!
قم بتجميعه كـ x64 مع VS2005:
%llu يعمل بشكل جيد.
الأشياء غير القياسية دائمًا غريبة :)
للجزء الطويل الطويل تحت GNU ، إنه L
, ll
أو q
وتحت النوافذ أعتقد أنه كذلك ll
فقط
عرافة:
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
.
حسنًا، إحدى الطرق هي تجميعه كـ x64 مع VS2008
يعمل هذا كما تتوقع:
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);
يعمل هذا الرمز مع مترجم VS 32 و 64 بت.
من الواضح أنه لم يتوصل أحد إلى حل متعدد المنصات* لـ أكثر من عقد منذ [ال] عام 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
سلسلة تنسيق الطباعة، وهذا يناسبني تحت 32 بت دول مجلس التعاون الخليجي على نظام التشغيل Windows.
*) حسنًا، بالكاد منصة متعددة.في MSVC، تحتاج على ما يبدو _ui64toa()
بدلاً من lltoa()
.