2012-08-25 32 views
33

Tôi đang cố gắng in uint16_t và uint32_t giá trị nhưng nó không phải là cho o/p mong muốn.Làm cách nào để in giá trị biến uint32_t và uint16_t?

#include<stdio.h> 
#include <netinet/in.h> 

int main() 
{ 
    uint32_t a=12,a1; 
    uint16_t b=1,b1; 
    a1=htonl(a); 
    printf("%d---------%d",a1); 
    b1=htons(b); 
    printf("\n%d-----%d",b,b1); 
    return 0; 
} 

Tôi cũng sử dụng

printf("%"PRIu32, a); 

được hiển thị một lỗi.

Làm thế nào để in những giá trị và những gì sẽ là o mong muốn/p

+3

Sẽ hữu ích hơn nếu hiển thị thông báo lỗi (chính xác!) Thay vì chỉ nói rằng đó là "hiển thị lỗi". Và thay vì chỉ "không đưa ra mong muốn o/p", cho chúng ta thấy đầu ra thực tế (và đánh vần từ "đầu ra" thay vì viết "o/p"). –

Trả lời

53

Bạn cần phải bao gồm inttypes.h nếu bạn muốn tất cả những specifiers định dạng mới tiện lợi cho intN_t loại và các anh em của họ, và đó sự chính xác (ví dụ, di động) cách để làm điều đó, miễn là trình biên dịch của bạn tuân thủ C99. Bạn không nên sử dụng các tiêu chuẩn như %d hoặc %u trong trường hợp các kích thước khác với những gì bạn nghĩ.

Nó bao gồm stdint.h và mở rộng nó với một số thứ khác, chẳng hạn như các macro có thể được sử dụng cho họ gọi printf/scanf. Điều này được đề cập trong phần 7.8 của tiêu chuẩn ISO C99.

Ví dụ, chương trình sau đây:

#include <stdio.h> 
#include <inttypes.h> 
int main (void) { 
    uint32_t a=1234; 
    uint16_t b=5678; 
    printf("%" PRIu32 "\n",a); 
    printf("%" PRIu16 "\n",b); 
    return 0; 
} 

kết quả đầu ra:

1234 
5678 
12

Các macro được định nghĩa trong <inttypes.h> là cách chính xác nhất để in các giá trị của các loại uint32_t, uint16_t, và vân vân - - nhưng chúng không phải là cách duy nhất.

Cá nhân, tôi thấy những macro này khó nhớ và khó xử khi sử dụng. (Với cú pháp của một chuỗi định dạng printf, điều đó có thể là không thể tránh khỏi; Tôi không tuyên bố rằng tôi có thể đưa ra một hệ thống tốt hơn.)

Một cách khác là đưa giá trị vào một loại được xác định trước và sử dụng định dạng cho loại đó.

loại intunsigned int được đảm bảo bởi các ngôn ngữ có ít nhất 16 bit rộng, và do đó để có thể giữ bất kỳ giá trị chuyển đổi của loại int16_t hoặc uint16_t, tương ứng. Tương tự, longunsigned long có chiều rộng tối thiểu 32 bit và long longunsigned long long rộng ít nhất 64 bit.

Ví dụ, tôi có thể viết chương trình của bạn như thế này (với một vài tinh chỉnh bổ sung):

#include <stdio.h> 
#include <stdint.h> 
#include <netinet/in.h> 

int main(void) 
{ 
    uint32_t a=12, a1; 
    uint16_t b=1, b1; 
    a1 = htonl(a); 
    printf("%lu---------%lu\n", (unsigned long)a, (unsigned long)a1); 
    b1 = htons(b); 
    printf("%u-----%u\n", (unsigned)b, (unsigned)b1); 
    return 0; 
} 

Một ưu điểm của phương pháp này là nó có thể làm việc ngay cả với hiện thực-C99 trước không hỗ trợ <inttypes.h>. Việc triển khai như vậy rất có thể sẽ không có cả <stdint.h>, nhưng kỹ thuật này hữu ích cho các loại số nguyên khác.

+1

Có một trường hợp rất nhỏ cạnh ở đây, nếu ký int không phải là hai bổ sung. Trong trường hợp đó, nó sẽ không giữ đúng giá trị bổ sung của hai giá trị âm. VERY nhỏ, tôi sẽ thừa nhận nhưng một cái gì đó để xem ra cho nếu bạn muốn tính di động tối đa. – paxdiablo

+1

@paxdiablo: Các loại 'intN_t' được yêu cầu là hai bổ sung không có bit đệm. Nếu 'int' không phải là phần bổ sung của hai, thì các kiểu' intN_t' có thể sẽ không được định nghĩa * trừ khi * việc triển khai cũng hỗ trợ các kiểu bổ sung hai riêng biệt. Điểm tốt, nhưng tôi nghĩ rằng đó là một trường hợp cạnh nhỏ hơn nhiều so với bạn đề nghị. –

+1

Không nghi ngờ gì. Tôi nghi ngờ bạn sẽ gặp khó khăn trong việc tìm kiếm một cỗ máy trên hành tinh thể thao các loại tích phân mới nhưng vẫn có một bổ sung hoặc dấu/cường độ 'int' type :-) – paxdiablo

-2

Trong trường hợp của tôi, tôi chỉ sử dụng %u để xuất giá trị với loại uint32_t. Nó hoạt động.

ví dụ:

uint32_t i = 31 - __builtin_clz(mask); 

    D("read i= %u ", __FUNCTION__, i); 
+2

Điều này sẽ gây ra hành vi không xác định trên các hệ thống mà' sizeof (unsigned int)! = sizeof (uint32_t) '. – user694733

+0

Cảm ơn bro. Và tôi cũng thấy rằng chúng ta có thể sử dụng '% 08x' để trình bày nó. Nó sẽ được hiển thị dưới dạng nhị phân. –

+1

Sử dụng '% 08x' có cùng vấn đề với'% u'. Ngoài ra, nó sẽ hiển thị giá trị dưới dạng số thập lục phân; không có specifier nhị phân trong printf C chuẩn. – user694733

Các vấn đề liên quan