อาร์กิวเมนต์สำหรับ printf ที่จัดรูปแบบยาวคืออะไร


489

printfฟังก์ชั่นใช้เวลาประเภทโต้แย้งเช่น%dหรือหา%i signed intอย่างไรก็ตามฉันไม่เห็นอะไรเลยสำหรับlongค่า


อย่าใช้นานมันไม่ได้พกพา stackoverflow.com/questions/16859500/mmh-who-are-you-priu64
มีนาคม

คำตอบ:


634

ใส่l(ตัวอักษรพิมพ์เล็ก L) ลงตรงหน้าตัวระบุ

unsigned long n;
long m;

printf("%lu %ld", n, m);

14
printf("%ld", ULONG_MAX)ส่งออกค่าเป็น -1 ควรเป็นแบบprintf("%lu", ULONG_MAX)ยาวที่ไม่ได้ลงชื่อตามที่ @Blorgbeard ด้านล่าง
jammus

2
ที่จริงแล้วคุณควรเปลี่ยนให้เป็น%ldคำถามที่สอดคล้องกันมากขึ้น
ดร. เบคโก

ใช่ดร. เบคโก; ยิ่งไปกว่านั้นเป็นเพียงแค่%lทริกเกอร์warning: unknown conversion type character 0x20 in format [-Wformat]
Patrizio Bertoni


73

บนแพลตฟอร์มส่วนใหญ่longและintมีขนาดเท่ากัน (32 บิต) ถึงกระนั้นมันก็มีตัวระบุรูปแบบของตัวเอง:

long n;
unsigned long un;
printf("%ld", n); // signed
printf("%lu", un); // unsigned

สำหรับ 64 บิตคุณต้องการlong long:

long long n;
unsigned long long un;
printf("%lld", n); // signed
printf("%llu", un); // unsigned

โอ้และแน่นอนมันแตกต่างใน Windows:

printf("%l64d", n); // signed
printf("%l64u", un); // unsigned

บ่อยครั้งที่ฉันพิมพ์ค่า 64- บิตฉันพบว่ามีประโยชน์ในการพิมพ์เป็นเลขฐานสิบหก (โดยปกติแล้วจะเป็นตัวเลขที่มีขนาดใหญ่

unsigned long long n;
printf("0x%016llX", n); // "0x" followed by "0-padded", "16 char wide", "long long", "HEX with 0-9A-F"

จะพิมพ์:

0x00000000DEADBEEF

Btw, "long" ไม่ได้หมายถึงสิ่งนั้นอีกต่อไป (ในรุ่น 64 หลัก) "int" เป็นขนาดเริ่มต้นของแพลตฟอร์มโดยทั่วไปคือ 32 บิต "ยาว" มักจะมีขนาดเท่ากัน อย่างไรก็ตามพวกเขามีความหมายในการพกพาที่แตกต่างกันบนแพลตฟอร์มเก่า (และแพลตฟอร์มแบบฝังที่ทันสมัย!) "long long" คือหมายเลข 64- บิตและโดยทั่วไปแล้วสิ่งที่ผู้คนต้องการใช้นอกจากว่าพวกเขารู้จริง ๆ ว่าพวกเขากำลังทำการแก้ไขรหัสพกพา x-platform ถึงกระนั้นพวกเขาก็อาจจะใช้มาโครแทนเพื่อจับความหมายของประเภท (เช่น uint64_t)

char c;       // 8 bits
short s;      // 16 bits
int i;        // 32 bits (on modern platforms)
long l;       // 32 bits
long long ll; // 64 bits 

ย้อนกลับไปในวัน "int" คือ 16 บิต คุณคิดว่าตอนนี้จะเป็น 64 บิต แต่ไม่ใช่ว่าจะทำให้เกิดปัญหาการพกพาที่บ้า แน่นอนว่านี่เป็นความจริงที่ทำให้เข้าใจง่ายและเป็นความจริงที่เต็มไปด้วยประวัติศาสตร์ ดูwiki: จำนวนเต็ม


@MM ฉันชี้แจงคำตอบของฉันเพื่อหลีกเลี่ยงความสับสน
Dave Dopson

4
เพื่ออธิบายอย่างชัดเจน: มีสถาปัตยกรรมมากกว่า x86 และ x64 และในสถาปัตยกรรมเหล่านั้นทั้งตัวอักษรตัวหนาสั้นยาวยาวและยาวนั้นมีความหมายที่แตกต่างกัน ตัวอย่างเช่น 32 บิต mcu พร้อมการจัดตำแหน่งหน่วยความจำ 16 บิตสามารถใช้: char = short = int = 16 bit ยาว = 32 บิต ยาวยาว = 64 บิต
AndresR

1
@AndresR - แน่นอนและมันสำคัญมากสำหรับผู้ที่ทำโปรแกรมแบบฝัง (ฉันสร้างโมดูลเคอร์เนลเพื่อแจ้งเตือนควันหนึ่งครั้ง) สงสารวิญญาณที่น่าสงสารเหล่านั้นเมื่อพวกเขาพยายามใช้รหัสที่ไม่ได้เขียนเพื่อการพกพา
Dave Dopson

ฉันไม่แน่ใจว่า "แพลตฟอร์มส่วนใหญ่มีlongขนาด 32" ยังคงเป็นจริง เช่นฉันใน Oracle Linux x86_64 / AMD64 และด้วยคือ 8 ไบต์ nvcclong
ragerdl

"โอ้และแน่นอนมันแตกต่างใน Windows" มีโซลูชันข้ามแพลตฟอร์มหรือไม่
Aaron Franke

17

"%lu"มันขึ้นอยู่ถ้าคุณจะหมายถึงไม่ได้ลงนามยาวตัวอักษรการจัดรูปแบบเป็น "%ld"หากคุณกำลังหมายถึงการเซ็นสัญญายาวตัวอักษรการจัดรูปแบบเป็น



12

ในกรณีที่คุณต้องการพิมพ์unsigned long longเหมือนฉันใช้:

unsigned long long n;
printf("%llu", n);

สำหรับชุดอื่น ๆ ทั้งหมดผมเชื่อว่าคุณใช้ตารางจากคู่มือ printfพาแถวแล้วป้ายชื่อคอลัมน์สำหรับสิ่งที่พิมพ์ที่คุณกำลังพยายามที่จะพิมพ์ (ที่ผมทำอย่างไรกับprintf("%llu", n)ด้านบน)


0

ฉันคิดว่าจะตอบคำถามนี้อย่างแน่นอนจะต้องรู้ชื่อคอมไพเลอร์และรุ่นที่คุณใช้และแพลตฟอร์ม (ประเภท CPU, OS เป็นต้น) ที่รวบรวม


คำตอบของคุณควรเป็นความคิดเห็นและไม่ใช่คำตอบด้วยตัวเอง
Jaime Hablutzel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.