FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Why does toString(int) give me different results?

 
Post new topic   Reply to topic     Forum Index -> Tutorials
View previous topic :: View next topic  
Author Message
NeilEBryant



Joined: 08 Aug 2006
Posts: 6

PostPosted: Wed Sep 13, 2006 8:28 am    Post subject: Why does toString(int) give me different results? Reply with quote

I assume I'm doing something wrong; I'm really new to D, and sort of winging my way through.

If I run this code (and I make no claims about it being good code):
Code:
private import std.c.windows.windows;
import std.string;
import std.stdio;

void main(char[][] args)
{
   char[] c = "1";
   writef("test char[]: ?s\n", toString(c[]));
   MessageBoxA(null, toString(c[]), "test char[]", MB_OK);

   int i = 1;
   writef("test int: ?s\n", toString(i));
   MessageBoxA(null, toString(i), "test int", MB_OK);

   char[] s = toString(1);
   writef("test char[]: ?s\n", toString(s[]));
   MessageBoxA(null, toString(s[]), "test char[]", MB_OK);
}


I get the following results via writef():
Code:
test char[]: 1
test int: 1
test char[]: 123456789

On the other hand, MessageBox returns these responses:
Code:
test char[]: 1
test int: 123456789
test char[]: 123456789


I have narrowed it down (I think) to the std.string.toString(int) function. It only happens with single-digit integers, which toString does an array slice on. Instead of returning digits[u .. u+1], sometimes it returns from u to the end of the digits array.

I have the most recent versions of DMD/Phobos, all installed as per instructions, and I didn't see this come up in a search.

I'm in a bit of a newbie-corner, because of the inconsistency; I'm getting different results across character types, but also across caller.

Any guesses where my problem might be coming from?

Thanks,
~Neil
Back to top
View user's profile Send private message
pragma



Joined: 28 May 2004
Posts: 607
Location: Washington, DC

PostPosted: Wed Sep 13, 2006 11:15 am    Post subject: Re: Why does toString(int) give me different results? Reply with quote

NeilEBryant wrote:

Any guesses where my problem might be coming from?

Thanks,
~Neil


The second argument to MessageBoxA is an LPCTSTR, which is more or less just plain 'ol "char*". The problem here is that D implicitly converts a char[] to a char* by returning a pointer to the start of the char[] - it doesn't append a trailing zero.

Simply use the std.string.toStringz() function when passing char[] style strings to C-library function calls (especially win32) and all will be well.
_________________
-- !Eric.t.Anderton at gmail
Back to top
View user's profile Send private message Yahoo Messenger
aldacron



Joined: 05 May 2004
Posts: 1322
Location: Seoul, South Korea

PostPosted: Wed Sep 13, 2006 11:29 am    Post subject: Reply with quote

Here's a modified version of your code that gives the expected output:

Code:

private import std.c.windows.windows;
import std.string;
import std.stdio;

void main(char[][] args)
{
   char[] c = "1";
   writef("test char[]: ?s\n", c);
   MessageBoxA(null, toStringz(c), "test char[]", MB_OK);

   int i = 1;
   writef("test int: ?s\n", toString(i));
   MessageBoxA(null, toStringz(toString(i)), "test int", MB_OK);

   char[] s = toString(1);
   writef("test char[]: ?s\n", s);
   MessageBoxA(null, toStringz(s), "test char[]", MB_OK);
}


Some things to note:

MessageBoxA, being a C function, expects a null-terminated string. When passing a string to a C function, always use toStringz on it to ensure it is null-terminated. And there's no need to pass a copy of the string, since toStringz makes a copy of it anyway.

Also, any function that accepts a string as a parameter can accept the string variable as is. There is no need to call toString on the string, as you were doing here (actually, you were calling toString on a copy of the string by using the [] syntax):

Code:

char[] c = "1";
writef("test char[]: ?s\n", toString(c[]));


Because the variable c is already a string, what does it mean to convert it to a string? That would be like having an int value to a toInt function -- pointless. The real problem is that there is no function in std.string that takes a char[] as an argument. Hoever, there is a version that takes a char* as an argument. This function is intended to convert a null-terminated C-string to a D string. As far as function params go, anything that accepts a char* can accept a char[]. That's ther version you were actually calling. That's probably why you were getting the odd output.
_________________
The One With D | The One With Aldacron | D Bits


Last edited by aldacron on Wed Sep 13, 2006 11:44 pm; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
NeilEBryant



Joined: 08 Aug 2006
Posts: 6

PostPosted: Wed Sep 13, 2006 11:50 am    Post subject: Reply with quote

deleted

Last edited by NeilEBryant on Thu Sep 14, 2006 3:26 pm; edited 1 time in total
Back to top
View user's profile Send private message
NeilEBryant



Joined: 08 Aug 2006
Posts: 6

PostPosted: Wed Sep 13, 2006 11:51 am    Post subject: Reply with quote

Thank you both, very much. Your answers and explanations were helpful, insightful, and exactly what I need =]

~Neil
Back to top
View user's profile Send private message
aldacron



Joined: 05 May 2004
Posts: 1322
Location: Seoul, South Korea

PostPosted: Wed Sep 13, 2006 11:47 pm    Post subject: Reply with quote

I noticed that I still left a mistake in my modified version of the code and fixed it. The last call to MessageBoxA was still passing a copy of the string to toStringz instead of the string reference itself, so instead of toStringz(s[]) it now is toStringz(s) as it should be. Sorry if I confused you.
_________________
The One With D | The One With Aldacron | D Bits
Back to top
View user's profile Send private message Send e-mail
NeilEBryant



Joined: 08 Aug 2006
Posts: 6

PostPosted: Thu Sep 14, 2006 3:05 pm    Post subject: Reply with quote

You didn't . . . although I obviously need to study up on things =]

Thank you for the clarification. I'm learning a lot.
Back to top
View user's profile Send private message
NeilEBryant



Joined: 08 Aug 2006
Posts: 6

PostPosted: Thu Sep 14, 2006 3:25 pm    Post subject: Reply with quote

BTW, it took me some more targetted hunting around, but I found what you guys were talking about. I hadn't picked up that setting a string slice meant making a reference, rather than a copy.

For anybody else in the future, these are helpful:

http://www.digitalmars.com/d/arrays.html#slicing

http://www.digitalmars.com/d/arrays.html#strings
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Tutorials All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group