On Sunday, April 08, 2012 07:08:09 dnewbie wrote: > I have a wchar[] and I want to convert it to UTF8 > then append a string. This is my code. > > import std.c.windows.windows; > import std.string; > import std.utf; > > int main() > { > wchar[100] v; > v[0] = 'H'; > v[1] = 'e'; > v[2] = 'l'; > v[3] = 'l'; > v[4] = 'o'; > v[5] = 0; > string s = toUTF8(v) ~ ", world!"; > MessageBoxA(null, s.toStringz, "myapp", MB_OK); > return 0; > } > > I want "Hello, world!", but the result is "Hello" only. Please help me.
D strings are not null-terminated, so v[5] = 0 doesn't do anything to terminate that string. The whole point of toStringz is to put a null character on the end of a string (and allocate a new string if need be) and return a pointer to it. C code will then use the null character to indicate the end of the string, but D won't. What you've done with string s = toUTF8(v) ~ ", world!"; is create a string that is ['H', 'e', 'l', 'l', 'o', '\0', '\0', '\0', ...] (all of the characters up to the v[99] are '\0') and append [',', ' ', 'w', 'o', 'r', 'l', 'd', '!'] to it. The result is a string whith is 108 characters long with a ton of null characters in the middle of it. When you call toStringz on it, it may or may not allocate a new string, but in the end, you have a string which is 109 characters long with the last character being '\0' (still with all of the null characters in the middle) which you get an immutable char* pointing to. So, when the C code operates on it, it naturally stops processing when it hits the first null character, since that's how C determines the end of a string. You can embed null characters in a string and expect C to operate on the whole thing. And since D strings aren't null-terminated, you can't expect that setting any of it their elements to null will do anything to terminate the string in D or stop D functions from operating on the whole string. You have to slice the static wchar array with the exact elements that you want if you intend to terminate it before its end. - Jonathan M Davis