ตัวระบุรูปแบบสำหรับ int สั้นที่ไม่ได้ลงชื่อคืออะไร


125

ฉันมีโปรแกรมดังต่อไปนี้

#include <stdio.h>

int main(void)
{
    unsigned short int length = 10; 

    printf("Enter length : ");
    scanf("%u", &length);

    printf("value is %u \n", length);

    return 0;
}

ซึ่งเมื่อคอมไพล์โดยใช้gcc filename.cคำเตือนต่อไปนี้ (ในscanf()บรรทัด)

warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 2 has type ‘short unsigned int *’ [-Wformat]

จากนั้นผมก็อ้างถึงC99 specification - 7.19.6 Formatted input/output functionsและไม่สามารถเข้าใจรูปแบบตัวระบุที่ถูกต้องเมื่อใช้การปรับเปลี่ยนความยาว (เช่นshort, longฯลฯ ) ด้วยunsignedสำหรับintชนิดข้อมูล

คือ%uตัวระบุที่ถูกต้องunsigned short int? ถ้าเป็นเช่นนั้นเหตุใดฉันจึงได้รับคำเตือนดังกล่าวข้างต้น!

แก้ไข: ส่วนใหญ่แล้วฉันพยายาม%uhและยังคงให้คำเตือนอยู่


2
printf("%u\n", (unsigned int)length); //ใช้งานได้เสมอเนื่องจากข้อมูลจำเพาะ C99 ที่คุณอ่านรับประกันได้ว่าsizeof(short) <= sizeof(int)(แต่คำตอบที่แท้จริงสำหรับคำถามด้านล่างนี้ดีกว่ามาก)
Philip

1
ไม่จำเป็นต้องมีนักแสดง โปรโมชั่นเริ่มต้นจะดูแลมัน
R .. GitHub STOP HELPING ICE

คำตอบ:


156

ลองใช้"%h"ตัวปรับแต่ง:

scanf("%hu", &length);
        ^

ISO / IEC 9899: 201x - 7.21.6.1-7

ระบุว่าต่อไปนี้ D, I, O, U, X, X, หรือ n แปลงระบุนำไปใช้กับทะเลาะกับพิมพ์ที่ชี้ไปยังสั้นหรือลงนามสั้น


47

สำหรับscanfคุณต้องใช้%huเนื่องจากคุณกำลังส่งตัวชี้ไปยังunsigned shortไฟล์. สำหรับprintfมันเป็นไปไม่ได้ที่จะผ่านunsigned shortเนื่องจากการเริ่มต้นโปรโมชั่น (มันจะได้รับการเลื่อนตำแหน่งให้เป็นintหรือunsigned intขึ้นอยู่กับว่าintมีอย่างน้อยเป็นบิตค่าเป็นจำนวนมากunsigned shortหรือไม่) เพื่อให้%dหรือ%uจะปรับ คุณสามารถใช้งานได้ฟรี%huหากต้องการ


8

จากหน้าคู่มือ Linux:

h การแปลงจำนวนเต็มต่อไปนี้สอดคล้องกับอาร์กิวเมนต์ int สั้น ๆ หรือไม่ได้ลงนามสั้น ๆ หรือโฟล
       การลด n การแปลงสอดคล้องกับตัวชี้ไปยังอาร์กิวเมนต์ int สั้น ๆ

"%hu"ดังนั้นในการพิมพ์เป็นจำนวนเต็มสั้นที่ไม่ได้ลงชื่อสตริงรูปแบบที่ควรจะเป็น


ฉันไม่คิดว่านั่นเป็นวิธีที่คุณ "printf" short ints เพราะได้รับการเลื่อนขั้นเป็น ints โดยอัตโนมัติ (เช่นเดียวกับตัวอักษร)
Alexey Frunze

2
@Alex% hu /% hd ใน printf ใช้งานได้ เป็น% hhu /% hhd ที่มีให้เริ่มต้นด้วย C99 เท่านั้น % h และ% hh หมายถึง a & 0xFFFF resp & 0xFF บนจำนวนเต็มที่ผ่าน
jørgensen

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