www.digitalmars.com         C & C++   DMDScript  

D - Question about casts

reply "Steve Adams" <adamss ascinet.com> writes:
Can someone clear this up for me?  The following code doesn't work the way
that I would expect from the description of slices.


int main()
{
  char[] one = "abc\ndef\n";
  char[] two = one[0..3];
  printf( "%s\n", cast(char *) one );
  return( 0 );
}

generates as output

  abc
  def

instead of just
  abc
Mar 18 2003
next sibling parent "John Reimer" <jjreimer telus.net> writes:
"Steve Adams" <adamss ascinet.com> wrote in message
news:b58ekm$1kqe$1 digitaldaemon.com...
 Can someone clear this up for me?  The following code doesn't work the way
 that I would expect from the description of slices.


 int main()
 {
   char[] one = "abc\ndef\n";
   char[] two = one[0..3];
   printf( "%s\n", cast(char *) one );
   return( 0 );
 }

 generates as output

   abc
   def

 instead of just
   abc

Seems correct output to me... Now it may have your expected output if you did: printf("%s\n", cast(char *) two); Am I missing something? Later, John
Mar 18 2003
prev sibling next sibling parent reply "Steve Adams" <adamss ascinet.com> writes:
Sigh.  The printf line should be:

  printf( "%s\n", case(char *)two);


"Steve Adams" <adamss ascinet.com> wrote in message
news:b58ekm$1kqe$1 digitaldaemon.com...
 Can someone clear this up for me?  The following code doesn't work the way
 that I would expect from the description of slices.


 int main()
 {
   char[] one = "abc\ndef\n";
   char[] two = one[0..3];
   printf( "%s\n", cast(char *) one );
   return( 0 );
 }

 generates as output

   abc
   def

 instead of just
   abc

Mar 18 2003
parent reply "John Reimer" <jjreimer telus.net> writes:
:-)

"Steve Adams" <adamss ascinet.com> wrote in message
news:b58fm5$1lke$1 digitaldaemon.com...
 Sigh.  The printf line should be:

   printf( "%s\n", case(char *)two);

Mar 18 2003
parent reply "Steve Adams" <adamss ascinet.com> writes:
Nothing like hitting send too soon.

But, it still doesn't work.  It always prints all the characters in one.


"John Reimer" <jjreimer telus.net> wrote in message
news:b58fs0$1lm4$1 digitaldaemon.com...
 :-)

 "Steve Adams" <adamss ascinet.com> wrote in message
 news:b58fm5$1lke$1 digitaldaemon.com...
 Sigh.  The printf line should be:

   printf( "%s\n", case(char *)two);


Mar 18 2003
next sibling parent reply "John Reimer" <jjreimer telus.net> writes:
Well, I think the reason is because you've taken a slice of array one and
put it in two, and two doesn't have a null terminator in it's slice by
default, so you end up printing until there's a null termination of the
string which, it appears, is in the same address as the string termination
of one..

I didn't realize, though, that a slice seems to be like a pointer to
variable one's memory space, if indeed it has the output you say. Or maybe
it copies the whole string, but only represents the slice.

A convoluted way of saying it, I'm sure... but I think that's the problem.

Later,
John
Mar 18 2003
parent reply "Steve Adams" <adamss ascinet.com> writes:
Seems like it's a pointer and a count (since strings are counted).  Not a
bad model, until
you want to print it out.  I'm working around it with

  printf( "%.*s\n", two.length, (char *)two );

but that seems rather wasteful.  Either the cast should really do a case, or
there should be
a format specifier for the counted strings.

Might be a way to do this with an array copy too I suppose.


"John Reimer" <jjreimer telus.net> wrote in message
news:b58gmo$1m3a$1 digitaldaemon.com...
 Well, I think the reason is because you've taken a slice of array one and
 put it in two, and two doesn't have a null terminator in it's slice by
 default, so you end up printing until there's a null termination of the
 string which, it appears, is in the same address as the string termination
 of one..

 I didn't realize, though, that a slice seems to be like a pointer to
 variable one's memory space, if indeed it has the output you say. Or maybe
 it copies the whole string, but only represents the slice.

 A convoluted way of saying it, I'm sure... but I think that's the problem.

 Later,
 John

Mar 18 2003
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Steve Adams wrote:

 Seems like it's a pointer and a count (since strings are counted).  Not a
 bad model, until
 you want to print it out.  I'm working around it with

   printf( "%.*s\n", two.length, (char *)two );

 but that seems rather wasteful.  Either the cast should really do a case, or
 there should be
 a format specifier for the counted strings.

 Might be a way to do this with an array copy too I suppose.

This works, but not on Linux. The solution I use (which has a performance hit, unfortunately) is: printf("%s\n", (char*)(two~\0)); Appending to the array causes a copy to be made, so this doesn't overwrite 'one'. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 19 2003
prev sibling parent reply Patrick Down <pat codemoon.com> writes:
"Steve Adams" <adamss ascinet.com> wrote in
news:b58g2f$1lo7$1 digitaldaemon.com: 

 Nothing like hitting send too soon.
 
 But, it still doesn't work.  It always prints all the characters in
 one. 
 
 
 "John Reimer" <jjreimer telus.net> wrote in message
 news:b58fs0$1lm4$1 digitaldaemon.com...
 :-)

 "Steve Adams" <adamss ascinet.com> wrote in message
 news:b58fm5$1lke$1 digitaldaemon.com...
 Sigh.  The printf line should be:

   printf( "%s\n", case(char *)two);



This is a very common mistake. D strings are not null terminated, except for the constant ones defined inline. Try this instead. printf("%.*s\n",two);
Mar 18 2003
next sibling parent "John Reimer" <jjreimer telus.net> writes:
 This is a very common mistake.  D strings are
 not null terminated, except for the constant
 ones defined inline.  Try this instead.

 printf("%.*s\n",two);

Ah, now there's a good answer :-)
Mar 18 2003
prev sibling next sibling parent "Steve Adams" <adamss ascinet.com> writes:
Thanks cleaner.  Thanks.


 news:b58fm5$1lke$1 digitaldaemon.com...
 Sigh.  The printf line should be:

   printf( "%s\n", case(char *)two);



This is a very common mistake. D strings are not null terminated, except for the constant ones defined inline. Try this instead. printf("%.*s\n",two);

Mar 18 2003
prev sibling parent reply "John Reimer" <jjreimer telus.net> writes:
 This is a very common mistake.  D strings are
 not null terminated, except for the constant
 ones defined inline.  Try this instead.

 printf("%.*s\n",two);

Is that a period and an asterisk following the percent sign? Or is it just an asterisk?
Mar 18 2003
parent "Steve Adams" <adamss ascinet.com> writes:
A period and an asterisk.


"John Reimer" <jjreimer telus.net> wrote in message
news:b58hah$1mjl$1 digitaldaemon.com...
 This is a very common mistake.  D strings are
 not null terminated, except for the constant
 ones defined inline.  Try this instead.

 printf("%.*s\n",two);

Is that a period and an asterisk following the percent sign? Or is it just an asterisk?

Mar 18 2003
prev sibling parent "Matthew Wilson" <dmd synesis.com.au> writes:
You need to use the "%.*s" syntax to use only the contents of the slice.
"%s" uses a char * - which you've cast it to - and since the slice is a
copy-on-write view into the original array, you get the rest of the original
because a null-terminator is not contained in the slice.

If you want a slice that you can treat as a ZTS, you need to append the null
terminator with

  two ~= (char)0;

(although I may be wrong - it's been a while)


"Steve Adams" <adamss ascinet.com> wrote in message
news:b58ekm$1kqe$1 digitaldaemon.com...
 Can someone clear this up for me?  The following code doesn't work the way
 that I would expect from the description of slices.


 int main()
 {
   char[] one = "abc\ndef\n";
   char[] two = one[0..3];
   printf( "%s\n", cast(char *) one );
   return( 0 );
 }

 generates as output

   abc
   def

 instead of just
   abc

Mar 18 2003