fwprintf does not output wide characters

1.4k Views Asked by At

I want to output wide characters to a file, and fwprintf doesn't do it, even though it's described as doing just that. Sample code:

const char *testFileName = "/Users/jdmuys/wideTestFile.txt";
FILE *wideTestFile;
wideTestFile = fopen(testFileName, "w");
fwide(wideTestFile, 1);
fwprintf(wideTestFile, L"12345");
fclose(wideTestFile);

After which my file "wideTestFile.txt" contains precisely 5 bytes: 31 32 33 34 35 according to my hex dump utility.

I suspect some issue with the current locale, as perhaps fwprintf calls upon fwprintf_l, which takes a locale as an additional argument.

I have been reading on how use that last call, but I can't manage to understand what I need to pass as a locale. The documentation is rather obscure on that (or perhaps I fail to understand it).

Any explanation why fwprintf doesn't behave as documented? and any example of use for fwprintf_l?

Many thanks,

JD

This is with Xcode 4.5.1 under Mac OS X 10.8.2 targetting iOS 6.0 from Objective-C code. But none of that should really matter.

2

There are 2 best solutions below

2
On

I'm going to take a guess here.

It's saving in UTF-8. Now, for most ASCII characters, the representation in ASCII and the representation in UTF-8 is exactly the same. Now, in UTF-8, the upper bits of the first byte encode the length of the "character". As an example, everything up to 0x7F fits in one byte (i.e. standard ASCII), 0x7FF in two bytes, and on and on. See http://en.wikipedia.org/wiki/UTF-8#Description for more details.

To "fix" your problem, simply use a character from higher up the UTF-8 table.

To rip some examples from the aforementioned Wikipedia page:

  • $ should fit in a single byte
  • ¢ in two bytes
  • € in three
  • in four
2
On

Your locale is probably some variation of UTF-8, which means that the output will only be wide when printing wide characters (i.e. characters outside of the ascii code 0 - 127).

If you want to force wide printing (e.g. UTF-16LE) then you need to use libiconv. This answer kind of illustrates why it doesn't tend to do what you think it does.