2012-04-03 9 views
5

Ive có một dự án đa nền tảng biên dịch tuyệt vời trên mac, nhưng trên windows tất cả các cuộc gọi swprintf của tôi với một% s đang tìm kiếm một wchar_t thay vì char * im đi qua nó. Hóa ra M $ nghĩ rằng nó sẽ là buồn cười để làm cho% s đứng cho một cái gì đó khác hơn char * trong chức năng nhân vật rộng ... http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspxvisual studio swprintf là làm cho tất cả các% s formatters của tôi muốn wchar_t * thay vì char *

Dù sao tôi đang tìm kiếm một mẹo mã hóa sáng tạo tốt hơn là đặt ifdef khác kết thúc xung quanh mọi chuỗi gọi rộng

Trả lời

4

Visual Studio 14 CTP1 và sau đó sẽ luôn coi %s là một chuỗi hẹp (char*) trừ khi bạn xác định _CRT_STDIO_LEGACY_WIDE_SPECIFIERS. Nó cũng bổ sung phần mở rộng công cụ sửa đổi độ dài T ánh xạ tới những gì MS gọi là chiều rộng "tự nhiên". Đối với sprintf%Tschar* và cho swprintf%Tswchar_t*.


Trong Visual Studio 13 và trước đó %s/%c được ánh xạ tới độ rộng tự nhiên của hàm/chuỗi định dạng và %S/%C được ánh xạ tới các đối diện của tự nhiên với:

printf("%c %C %s %S\n", 'a', L'B', "cd", L"EF"); 
wprintf(L"%c %C %s %S\n", L'a', 'B', L"cd", "EF"); 

Bạn cũng có thể buộc chiều rộng cụ thể bằng cách sử dụng công cụ sửa đổi độ dài: %ls, %lc, %ws%wc luôn có nghĩa là wchar_t%hs%hc là một lways char. (Dự liệu cho VS2003 here và VC6 here (Không chắc về %ws và khi nó đã thực sự gia tăng))

Mapping %s để chiều rộng tự nhiên của hàm được thực sự tiện dụng trở lại trong những ngày của Win9x vs WinNT, bằng cách sử dụng các tchar.h header bạn có thể tạo các bản phát hành hẹp và rộng từ cùng một nguồn. Khi _UNICODE được định nghĩa các chức năng trong tchar.h bản đồ để các chức năng rộng và TCHARwchar_t, nếu không chức năng hẹp được sử dụng và TCHARchar:

_tprintf(_T("%c %s\n"), _T('a'), _T("Bcd")); 

Có một quy ước tương tự được sử dụng bởi các tập tin tiêu đề của Windows SDK và một số hàm định dạng tồn tại ở đó (wsprintf, wvsprintf, wnsprintf và wvnsprintf) nhưng chúng được kiểm soát bởi UNICODETEXT và không phải _UNICODE_T/_TEXT.

Bạn có thể có 3 lựa chọn để thực hiện một công việc dự án đa nền tảng trên Windows nếu bạn muốn hỗ trợ các trình biên dịch Windows cũ hơn:

1) Compile như một dự án chuỗi hẹp trên Windows, có lẽ không phải là một ý tưởng tốt và trong trường hợp của bạn, swprintf sẽ vẫn xử lý% s là wchar_t *.

2) Sử dụng định nghĩa tùy chỉnh tương tự như cách thức kiểu inttypes.định dạng h chuỗi hoạt động:

#ifdef _WIN32 
#define PRIs "s" 
#define WPRIs L"hs" 
#else 
#define PRIs "s" 
#define WPRIs L"s" 
#endif 
printf("%" PRIs " World\n", "Hello"); 
wprintf(L"%" WPRIs L" World\n", "Hello"); 

3) Tạo phiên bản tùy chỉnh của riêng bạn swprintf và sử dụng nó với Visual Studio 13 và trước đó.

+0

Im thực sự không chắc chắn làm thế nào để sử dụng này, trong các thử nghiệm của tôi khi _UNICODE được xác định hoặc không được xác định hành vi là swprintf cùng% s hy vọng một wchar_t và không phải là một char *. Đối với các phần mở rộng MS bạn có biết nếu có một cách để có được gcc để sử dụng chúng? – Medran

+0

Bạn có chắc chắn rằng môi trường của bạn không định nghĩa nó cho bạn (Trong cài đặt dự án trong VS)? Nếu bằng gcc bạn có nghĩa là MinGW thì có, MinGW có thể sử dụng thời gian chạy MS C, xem http://stackoverflow.com/questions/6729013/mingw-printf-size-specification-character-h – Anders

+0

không có gcc trên mac ... Trong cài đặt dự án, bạn chỉ định loại ký tự là 'không được định nghĩa' hoặc 'sử dụng unicode' hoặc 'sử dụng multibyte'. Nếu bạn nói 'not defined' thì _UNICODE không được định nghĩa, nếu bạn nói 'use unicode' thì _UNICODE được định nghĩa. – Medran

2

Sử dụng định dạng %ls luôn có nghĩa là wchar_t*.

+0

của nó không phải là một vấn đề với wchar_t được coi là char * một vấn đề với char * được coi là wchar_t. Plus tôi không nghĩ rằng% ls hoạt động trên các xưởng phim trực quan cũ ... Cảm ơn anyways neil. – Medran

+0

Xin lỗi, tôi không thể tìm thấy một cách tương thích để chỉ định một 'char *', nhưng tôi thực sự đã tìm kiếm% ls trên tài liệu VS7.1, vì vậy đó là một cách khá ngược lại. – Neil

+0

Yup Tôi có thể xác nhận rằng% ls hoạt động ít nhất là xa như VS2008, đó là những gì tôi đang sử dụng, cảm ơn vì điều đó. Tôi cũng tìm thấy nó trong tài liệu và rõ ràng những gì tôi nên có được sử dụng thay vì% S tất cả cùng như tôi đoán% S là điều rất không chuẩn. Nhưng thực sự những gì có thể được nhiều tiêu chuẩn hơn làm cho% s bằng một wchar_t. Điều duy nhất tôi nghĩ là chuyển hướng tất cả * wprint * của tôi đến một hàm bao bọc mà tôi có thể viết mà sẽ thay đổi% s là cần thiết. – Medran