Tôi đang cố gắng in các loại như off_tvà size_t. Giữ chỗ chính xác cho printf() đó là di động là gì?
Hoặc có một cách hoàn toàn khác để in các biến đó?
Tôi đang cố gắng in các loại như off_tvà size_t. Giữ chỗ chính xác cho printf() đó là di động là gì?
Hoặc có một cách hoàn toàn khác để in các biến đó?
Câu trả lời:
Bạn có thể sử dụng zcho size_t và tcho ptrdiff_t như trong
printf("%zu %td", size, ptrdiff);
Nhưng trang của tôi nói rằng một số thư viện cũ đã sử dụng một ký tự khác zvà không khuyến khích sử dụng nó. Tuy nhiên, nó được chuẩn hóa (theo tiêu chuẩn C99). Đối với những người intmax_tvà int8_tcủa stdint.hvà như vậy, có macro bạn có thể sử dụng, như câu trả lời khác nói:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
Chúng được liệt kê trong trang của inttypes.h.
Cá nhân, tôi sẽ chỉ đưa ra các giá trị unsigned longhoặc longgiống như một câu trả lời khác khuyến nghị. Nếu bạn sử dụng C99, thì dĩ nhiên, bạn có thể (và nên) chuyển sang unsigned long longhoặc long longvà sử dụng các định dạng %lluhoặc %lldđịnh dạng tương ứng.
%zdvới a size_tlà hành vi không xác định do sự không phù hợp về chữ ký (C99 7.19.6.1 # 9). Nó phải như vậy %zu.
%zdvới một size_thành vi không xác định từ đoạn đó hoặc từ bất kỳ khác. Trong thực tế, định nghĩa của %z# 7 cho phép rõ ràng %dvới size_tvà loại đã ký tương ứng và §6.2.5 # 9 cho phép sử dụng rõ ràng các giá trị của các loại không dấu trong đó loại được ký tương ứng được dự kiến, miễn là giá trị là giá trị không âm hợp lệ của loại đã ký.
Để in off_t:
printf("%jd\n", (intmax_t)x);
Để in size_t:
printf("%zu\n", x);
Để in ssize_t:
printf("%zd\n", x);
Xem 7.19.6.1/7 trong tiêu chuẩn C99 hoặc tài liệu mã định dạng POSIX thuận tiện hơn:
http://pub.opengroup.org/onlinepub/009695399/fifts/fprintf.html
Nếu việc triển khai của bạn không hỗ trợ các mã định dạng đó (ví dụ vì bạn đang sử dụng C89), thì bạn có một chút vấn đề vì AFAIK không có loại số nguyên trong C89 có mã định dạng và được đảm bảo là lớn như những loại này. Vì vậy, bạn cần phải làm một cái gì đó cụ thể thực hiện.
Ví dụ: nếu trình biên dịch của bạn có long longvà thư viện chuẩn của bạn hỗ trợ %lld, bạn có thể tự tin mong đợi rằng nó sẽ phục vụ thay thế intmax_t. Nhưng nếu không, bạn sẽ phải quay lại long, điều này sẽ thất bại đối với một số triển khai khác vì nó quá nhỏ.
ssize_tcó cùng kích thước size_t, vì vậy mã thực sự di động nên chuyển đổi nó thành intmax_tvà in %jdgiống như vậy off_t.
Đối với Microsoft, câu trả lời là khác nhau. VS2013 phần lớn tuân thủ C99 nhưng "[t] he hh, j, z và t tiền tố không được hỗ trợ." Đối với size_t "nghĩa là, không dấu __int32 trên nền tảng 32 bit, không dấu __int64 trên nền tảng 64 bit" sử dụng tiền tố I (con mắt vốn) với công cụ xác định loại o, u, x hoặc X. Xem thông số Kích thước VS2013
Đối với off_t, nó được định nghĩa là dài trong VC \ include \ sys \ type.h.
off_tluôn luôn longlà nó sẽ làm cho nó 32 bit (thậm chí Windows 64 bit sử dụng 32 bit cho long).
Bạn đang sử dụng phiên bản nào của C?
Trong C90, thông lệ tiêu chuẩn là chuyển sang ký dài hoặc không dấu, nếu phù hợp và in tương ứng. Tôi đã thấy% z cho size_t, nhưng Harbison và Steele không đề cập đến nó trong printf () và trong mọi trường hợp sẽ không giúp bạn với ptrdiff_t hoặc bất cứ điều gì.
Trong C99, các loại _t khác nhau đi kèm với các macro printf của riêng chúng, vì vậy một số thứ như "Size is " FOO " bytes." tôi không biết chi tiết, nhưng đó là một phần của định dạng số khá lớn bao gồm tệp.
Bạn sẽ muốn sử dụng các macro định dạng từ inttypes.h.
Xem câu hỏi này: Chuỗi định dạng nền tảng chéo cho các biến loại size_t?
off_tloại lớn hơn một con trỏ trên bất kỳ hệ thống 32-bit hỗ trợ các file lớn (đó là hầu hết các hệ 32-bit những ngày này).
Nhìn man 3 printfvào Linux, OS X và OpenBSD đều hiển thị hỗ trợ %zcho size_tvà %tchoptrdiff_t (cho C99), nhưng không ai trong số đó đề cập đến off_t. Các đề xuất trong tự nhiên thường cung cấp %uchuyển đổi cho off_t, "đủ chính xác" theo như tôi có thể nói (cả hai unsigned intvà off_tkhác nhau giữa các hệ thống 64 bit và 32 bit).
unsigned intvà 64 bit off_t. Vì vậy, các diễn viên sẽ làm mất dữ liệu.
Tôi đã thấy bài đăng này ít nhất hai lần, bởi vì câu trả lời được chấp nhận là khó nhớ đối với tôi (tôi hiếm khi sử dụng zhoặc gắn jcờ và chúng dường như không độc lập với nền tảng ).
Các tiêu chuẩn không bao giờ nói rõ chiều dài dữ liệu chính xác của size_t, vì vậy tôi đề nghị đầu tiên bạn nên kiểm tra chiều dài size_ttrên nền tảng của bạn sau đó chọn một trong số họ:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
Và tôi đề nghị sử dụng stdintcác loại thay vì các loại dữ liệu thô cho thống nhất.
%zucó thể được sử dụng để in size_tcác giá trị. Người ta phải chắc chắn không phải nghỉ mát để sử dụng một uint32_t/ uint64_tformat specifier in một size_t, như không có gì bảo đảm rằng những loại tương thích.
Như tôi nhớ, cách di động duy nhất để làm điều đó là sử dụng kết quả thành "unsign long int" và sử dụng %lu.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
long longkhông tồn tại trong tiêu chuẩn C ++, và do đó vốn dĩ không thể mang theo được.
fopen,fseekvv trên Mac OS X.off_tđược sử dụng để bù đắp.