need help

Regan Heath regan at netwin.co.nz
Tue Apr 25 00:08:41 PDT 2006


On Tue, 25 Apr 2006 13:55:21 +0800, Boris Wang <nano.kago at hotmail.com>  
wrote:
> You are right, the args array begin from index 0, but
>
>>   foreach( char[] arg; args[0 .. args.length] )
>
> This should not be right, it should be :
>     foreach( char[] arg; args[0 .. args.length - 1] )

That is not true.

In D, arrays are indexed from 0 and when slicing the start index is  
inclusive and the end index is not. Meaning, for example that:

args[0..2]

is a slice of items 0, and 1, but _not_ 2. If you use args.length-1 you  
will _not_ include the last item of the array in the slice. If you want  
the whole array then the end index must be the array length (AKA the index  
of the item past the end of the array)

> and more, when i run the followed code:
>
> import std.stdio;
>
> int main( char[][] args )
> {
>  foreach( char[] arg; args[0 .. args.length - 1 ] )
>  {
>   printf( "%s ", cast(char*)arg );
>  }
> }
>
> it even produce a assert:
>
> Error: AssertError Failure hello_my.d(10)

The assert has nothing to do with the array slice and everything to do  
with the missing return value in main. Try:

import std.stdio;

int main( char[][] args )
{
  foreach( char[] arg; args[0 .. args.length] )
  {
   printf( "%s ", cast(char*)arg );
  }
  return 0;
}

However, you should be aware that using cast(char*) on a char[] and  
passing the result to printf is dangerous. It's only working in this case  
because the arguments are already null terminated, try this:

import std.file;
import std.string;

int main( char[][] args )
{
  foreach( int i,char[] arg; splitlines(cast(char[])read("bug11.txt")) )
  {
      printf( "%d. %s\n", i,cast(char*)arg );
  }
  return 0;
}

(you'll need to create a bug11.txt containing a few lines of text)

you should notice that the first printf shows the entire file, this is  
because the splitlines array contains non-null terminated char[] arrays.  
To safely pass them to functions expecting char* you should use toStringz,  
eg.

import std.file;
import std.string;

int main( char[][] args )
{
  foreach( int i,char[] arg; splitlines(cast(char[])read("bug11.txt")) )
  {
      printf( "%d. %s\n", i,toStringz(arg) );
  }
  return 0;
}

Regan



More information about the Digitalmars-d-learn mailing list