2011-01-26 18 views
7

Tôi cần hàm C trả về độ dài cuối cùng của chuỗi được định dạng để tôi có thể phân bổ đúng chuỗi đích, thay vì tự tính toán độ dài. Có snprintf chỉ làm điều này khi không có khả năng viết toàn bộ chuỗi, nhưng tiếc là không có thay thế char rộng cho nó.Có một phiên bản wchar_t cho asprintf?

swprintf lợi nhuận -1 trong trường hợp lỗi, không phải là chiều dài cần thiết (tại sao không phải là hành vi tương tự?!?)

Tiêu đề đề cập asprintf dường như được giúp đỡ không còn, vì nó cung cấp một tổ chức phi rộng chỉ phiên bản.

_vscwprintf có thể được sử dụng trên cửa sổ, nhưng tôi cần một nền tảng, phiên bản tiêu chuẩn hoặc ít nhất một phiên bản Linux và tôi sẽ #ifdef mã.

Bất kỳ ý tưởng nào? Cảm ơn!

Trả lời

3

POSIX 2008 đã thêm chức năng open_wmemstream, cùng với vfwprintf, thực hiện chính xác những gì bạn cần. Nó trước đây là một phần mở rộng của GNU, vì vậy nó có sẵn trên các hệ thống GNU trong một thời gian dài.

Điều này có thể dễ dàng được sử dụng để tạo một bao bọc awprintf.

+1

Cảm ơn rất nhiều. Điều này hack là tốt đẹp và nó thực sự works.I vẫn không hiểu tại sao những điều đơn giản như vậy 'awprintf' không làm cho nó vào tiêu chuẩn khi các tính năng phức tạp hơn được thêm vào. – gheorghe1800

+0

Có lẽ vì tiêu chuẩn được đề cập là POSIX và hầu như không ai mã hóa cho các hệ thống POSIX sử dụng 'wchar_t' ngoại trừ khi chúng phải ... –

2

Vâng, dường như có một lỗ hổng cơ bản trong kỳ vọng của bạn. Thêm những lên:

  1. Windows có những gì bạn muốn
  2. Linux có một biến thể không rộng (asprintf không có trong tiêu chuẩn nào, nhưng hoàn toàn là một phần mở rộng GNU dành cho Linux và * BSD).
  3. POSIX định nghĩa mọi chuỗi/tệp có liên quan dưới dạng mảng char* vô hiệu, giải thích việc thiếu các phiên bản rộng của khá nhiều chức năng POSIX.
  4. Trên đầu trang của 2, 3 và 4, tất cả các bản phân phối Linux hiện đại đều dựa trên UTF-8, có nghĩa là các phiên bản không rộng là "có nghĩa là được sử dụng".

Thêm những thứ này cho: tại sao bạn cần một cái gì đó như thế này? Chắc chắn bạn không sử dụng wchar_t s trên Unix là bạn ;). Nếu bạn đang có, vẫn còn hai lựa chọn: chuyển sang một giải pháp giống như tchar (nền tảng phụ thuộc typedef) hoặc hoàn toàn chuyển sang UTF-8.

+0

Cảm ơn câu trả lời. Có, tôi kinda phải sử dụng wchar_t và chuyển sang UTF-8 có thể là quá thời gian tốn kém. – gheorghe1800

+0

@ gheorghe1800: phế liệu wchar_t và sử dụng [UTF-8] (http://utf8everywhere.org/). Nếu bạn đã theo dõi nó, câu hỏi này sẽ không xuất hiện. – ybungalobill

3

Có, swprintf. Lưu ý rằng mặc dù tên của nó, swprintf là ký tự rộng tương đương với snprintf, khôngsprintf, trong đó phải có kích thước bộ đệm làm thông số thứ hai; có (may mắn thay) không có phiên bản nhân vật rộng mà không có kích thước bộ đệm.

Ngoài ra, vì nó trả về -1 khi bị tràn, bạn sẽ phải lấy tổng chiều dài của chuỗi theo một cách khác. Cách duy nhất thực sự di động để làm điều này là bắt đầu với một bộ đệm có kích thước nào đó, hãy thử định dạng và xem nó có đủ lớn không và nếu không, hãy tăng kích thước và định dạng lại cho đến khi đủ lớn. Điều này không phải là rất hiệu quả, như bạn có thể tưởng tượng.

+0

Cảm ơn. Đây là những gì tôi đã nghĩ ở nơi đầu tiên, tôi chỉ hy vọng có một giải pháp tốt hơn đã được thực hiện.Cuối cùng, tôi nghĩ rằng tôi sẽ phải tính toán chiều dài bản thân mình, mà dường như lỗi dễ xảy ra trong trường hợp chung, nhưng tôi sẽ đảm bảo để được triệt để. – gheorghe1800

+0

Có một cách tốt hơn; xem câu trả lời của tôi Bạn có thể muốn dự phòng giải pháp của Adam cho các hệ thống trước POSIX-2008. –