Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 16, 2004 toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
There is a bug in the toString() function that prevents it from properly converting ints between '0' and '8' to their correct string value. For example, the following program: for(int i = 0; i <= 10; i++) { printf(toString(i)); printf(\n); } produces the output: F:\>tostring 0123456789 123456789 23456789 3456789 456789 56789 6789 789 89 9 10 Obviously this is the incorrect result. The cause of this problem is located at line number 1501 .. 1503 of std.string.d Which reads: if(u < 10) result = digits[u .. u+1]; Solution 1: if (u < 10) result ~= digits[u]; Solution 2: if(u < 10) { result.length = 1; result[0] = digits[u]; } Your choice really! Regards, Andrew |
May 16, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Edwards | Andrew Edwards wrote:
> There is a bug in the toString() function that prevents it from properly converting ints between '0' and '8' to their correct string value.
>
> For example, the following program:
>
> for(int i = 0; i <= 10; i++)
> {
> printf(toString(i));
> printf(\n);
> }
The problem is that you're treating a D string as though it were a C string. Strings are not necessarily null terminated. (string literals seem to happen to have a zero following the last char, but I'm not sure whether that's part of the spec or not)
printf(toStringz(i)); should behave as expected.
What would be nice is a printf overload that accepts a D string as its first argument instead of a C string.
-- andy
|
May 16, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andy Friesen | Andy Friesen wrote: > Andrew Edwards wrote: > >> There is a bug in the toString() function that prevents it from properly converting ints between '0' and '8' to their correct string value. >> >> For example, the following program: >> >> for(int i = 0; i <= 10; i++) >> { >> printf(toString(i)); >> printf(\n); >> } > > > The problem is that you're treating a D string as though it were a C string. Strings are not necessarily null terminated. (string literals seem to happen to have a zero following the last char, but I'm not sure whether that's part of the spec or not) > > printf(toStringz(i)); should behave as expected. I'm afraid you're mistaken ma'boy! Your proposed solution results in: tostring.d(9): function toStringz (char[]string) does not match argument types (int) The other problem is that I didn't treat D string as anything other than a D string. I merely pointed out a flaw in std.string.d and provided two solutions that remedies the problem. As currently implemented the conversion does not work and needs to be patched. You find a better way of doing it and I'd simply say congratulations! Either way it needs to be fixed. Regards, Andrew > What would be nice is a printf overload that accepts a D string as its first argument instead of a C string. > > -- andy |
May 16, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andy Friesen | Andy Friesen wrote: > Andrew Edwards wrote: > >> There is a bug in the toString() function that prevents it from properly converting ints between '0' and '8' to their correct string value. >> >> For example, the following program: >> >> for(int i = 0; i <= 10; i++) >> { >> printf(toString(i)); >> printf(\n); >> } > > > The problem is that you're treating a D string as though it were a C string. Strings are not necessarily null terminated. (string literals seem to happen to have a zero following the last char, but I'm not sure whether that's part of the spec or not) > > printf(toStringz(i)); should behave as expected. One more thing toStringz is intended to convert a D string to a null terminated C string; as such, it does not manipulate numbers. Chao, Andrew > > What would be nice is a printf overload that accepts a D string as its first argument instead of a C string. > > -- andy |
May 16, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Edwards | Andrew Edwards wrote:
> Andy Friesen wrote:
>
>>
>> The problem is that you're treating a D string as though it were a C string. Strings are not necessarily null terminated. (string literals seem to happen to have a zero following the last char, but I'm not sure whether that's part of the spec or not)
>>
>> printf(toStringz(i)); should behave as expected.
>
> I'm afraid you're mistaken ma'boy! Your proposed solution results in:
>
> tostring.d(9): function toStringz (char[]string) does not match argument types (int)
... gah. Right. You need printf("%.s", toString(i));
or printf(toStringz(toString(i)); (ew)
-- andy
|
May 16, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Edwards | Andrew Edwards wrote: > There is a bug in the toString() function that prevents it from properly converting ints between '0' and '8' to their correct string value. > > For example, the following program: > > for(int i = 0; i <= 10; i++) > { > printf(toString(i)); > printf(\n); > } > > produces the output: > > F:\>tostring > 0123456789 > 123456789 > 23456789 > 3456789 > 456789 > 56789 > 6789 > 789 > 89 > 9 > 10 > > Obviously this is the incorrect result. The cause of this problem is located at line number 1501 .. 1503 of std.string.d > > Which reads: > > if(u < 10) > result = digits[u .. u+1]; > > Solution 1: > > if (u < 10) > result ~= digits[u]; > > Solution 2: > > if(u < 10) { > result.length = 1; > result[0] = digits[u]; > } > > Your choice really! > > Regards, > Andrew That's not a bug - it's a feature! I vaguely remember a recent thread where it came up that toString on a digit will just return a slice of the digits string - but I can't find the thread anymore. Anyway, to turn a D string into a C string make sure it is null terminated: printf(toString(i) ~ "\0"); If you want you can change std.string to slice something like "0\x001\x002\x003\x004\x005\x006\x007\x008\x009". |
May 16, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andy Friesen | Andy Friesen wrote: > Andrew Edwards wrote: > >> Andy Friesen wrote: >> >>> >>> The problem is that you're treating a D string as though it were a C string. Strings are not necessarily null terminated. (string literals seem to happen to have a zero following the last char, but I'm not sure whether that's part of the spec or not) >>> >>> printf(toStringz(i)); should behave as expected. >> >> >> I'm afraid you're mistaken ma'boy! Your proposed solution results in: >> >> tostring.d(9): function toStringz (char[]string) does not match argument types (int) > > > .... gah. Right. You need printf("%.s", toString(i)); > or printf(toStringz(toString(i)); (ew) Why should I need to do toStringz(toSring(i)) when toSring(i) already returns a D string? OK... I see the problem, I'm treating printf() as a D function vice what it realy is: a C function. Damn! We need a better IO facility. My apologies! Andrew > -- andy |
May 17, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Edwards | On Sun, 16 May 2004 18:40:12 -0400, Andrew Edwards wrote: > There is a bug in the toString() function that prevents it from properly converting ints between '0' and '8' to their correct string value. > > For example, the following program: > > for(int i = 0; i <= 10; i++) > { > printf(toString(i)); > printf(\n); > } > > produces the output: > > F:\>tostring > 0123456789 > 123456789 > 23456789 > 3456789 > 456789 > 56789 > 6789 > 789 > 89 > 9 > 10 > > Obviously this is the incorrect result. The cause of this problem is located at line number 1501 .. 1503 of std.string.d > > Which reads: > > if(u < 10) > result = digits[u .. u+1]; > > Solution 1: > > if (u < 10) > result ~= digits[u]; > > Solution 2: > > if(u < 10) { > result.length = 1; > result[0] = digits[u]; > } > > Your choice really! > > Regards, > Andrew Is it a bug? Doesn't printf() needs a C string as its first argument, and toString(int) returns a D string? What is annoying is the D compiler's failure to notice this as it does an implicit cast that does not actually convert the D string into a C string. But explictly using printf( toStringz ( toString(i) ) ) will work instead. I was hoping that printf( cast(char [])toString(i) ) might work, but that doesn't do anything either. -- Derek 17/May/04 11:13:05 AM |
May 17, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | On Mon, 17 May 2004 11:24:19 +1000, Derek Parnell wrote: > On Sun, 16 May 2004 18:40:12 -0400, Andrew Edwards wrote: > >> There is a bug in the toString() function that prevents it from properly converting ints between '0' and '8' to their correct string value. >> >> For example, the following program: >> >> for(int i = 0; i <= 10; i++) >> { >> printf(toString(i)); >> printf(\n); >> } >> >> produces the output: >> >> F:\>tostring >> 0123456789 >> 123456789 >> 23456789 >> 3456789 >> 456789 >> 56789 >> 6789 >> 789 >> 89 >> 9 >> 10 >> >> Obviously this is the incorrect result. The cause of this problem is located at line number 1501 .. 1503 of std.string.d >> >> Which reads: >> >> if(u < 10) >> result = digits[u .. u+1]; >> >> Solution 1: >> >> if (u < 10) >> result ~= digits[u]; >> >> Solution 2: >> >> if(u < 10) { >> result.length = 1; >> result[0] = digits[u]; >> } >> >> Your choice really! >> >> Regards, >> Andrew > > Is it a bug? > Doesn't printf() needs a C string as its first argument, and toString(int) > returns a D string? > > What is annoying is the D compiler's failure to notice this as it does an implicit cast that does not actually convert the D string into a C string. > > But explictly using printf( toStringz ( toString(i) ) ) will work instead. > > I was hoping that printf( cast(char [])toString(i) ) might work, but that > doesn't do anything either. This seems to work too, but its a bit limiting... //------------------- import std.string; int printf(char []x) { return std.string.printf( toStringz(x)); } void main() { for(int i = 0; i <= 10; i++) { printf( toString(i)); printf(\n); }; } //------------------- -- Derek 17/May/04 11:47:22 AM |
May 17, 2004 Re: toString(int) bug and two possible solutions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | > What is annoying is the D compiler's failure to notice this as it does an implicit cast that does not actually convert the D string into a C string.
A char* isn't necessarily a C string. When char[] converts to char* it just drops the length, like it does from int[] to int* etc.
|
Copyright © 1999-2021 by the D Language Foundation