digitalmars.D.learn - need help
- Boris Wang (14/14) Apr 24 2006 int main( char[][] args )
- Jarrett Billingsley (19/20) Apr 24 2006 Uhh, yes it does. For me, anyway.
- Thomas Kuehne (15/25) Apr 24 2006 -----BEGIN PGP SIGNED MESSAGE-----
- Hasan Aljudy (3/43) Apr 25 2006 or
- Deewiant (28/29) Apr 25 2006 Huh? In what kind of situation are the following two not equivalent?
- xs0 (4/42) Apr 25 2006 func("%s%s%s");
- =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= (27/34) Apr 25 2006 import std.stdio;
- Deewiant (2/4) Apr 25 2006 Ah, of course. Thanks for reminding me, to xs0 as well.
- =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= (18/21) Apr 25 2006 Printf has the same problem. I bet you could trigger some
- BCS (3/14) Apr 25 2006 This has bit me more than once. Maybe there should be a writef that won'...
- Regan Heath (9/23) Apr 24 2006 The first one skips the first arg, to include the first arg use:
- Boris Wang (16/44) Apr 24 2006 This should not be right, it should be :
- Boris Wang (8/57) Apr 24 2006 The suitable explain is :
- Regan Heath (12/79) Apr 25 2006 Or rather, that rightLimit is one past the last item you want to include...
- Regan Heath (50/65) Apr 25 2006 That is not true.
- Boris Wang (4/75) Apr 25 2006 Best regards to you!
- Boris Wang (3/74) Apr 25 2006 Why not a complie error, but a runtime error?
- Regan Heath (7/62) Apr 25 2006 I believe the rationale is that it is not possible for the compiler to
int main( char[][] args ) { foreach( char[] arg; args[1 .. args.length] ) { printf( "%.*s ", arg ); } for ( int i = 0; i < args.length; i++ ) { printf("%.*s ", args[i] ); } return 0; } The first printf can't display the information, and the second do. I use dmd 0.154, XP SP2.
Apr 24 2006
"Boris Wang" <nano.kago hotmail.com> wrote in message news:e2k46n$1dkm$1 digitaldaemon.com...The first printf can't display the information, and the second do.Uhh, yes it does. For me, anyway. But I think the real question here is - why are you using printf instead of writef? ;) int main( char[][] args ) { foreach( char[] arg; args[1 .. args.length] ) { writef( arg, ' ' ); } writefln(); for ( int i = 1; i < args.length; i++ ) { writef( args[i], ' ' ); } return 0; } (These print identical lines for me.)
Apr 24 2006
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jarrett Billingsley schrieb am 2006-04-25:"Boris Wang" <nano.kago hotmail.com> wrote in message news:e2k46n$1dkm$1 digitaldaemon.com...<snip>The first printf can't display the information, and the second do.Uhh, yes it does. For me, anyway. But I think the real question here is - why are you using printf instead of writef? ;)for ( int i = 1; i < args.length; i++ ) { writef( args[i], ' ' ); }That's usually not a good idea(unchecked format strings...), instead use: for ( int i = 1; i < args.length; i++ ) { writef("%s ", args[i]); } Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFETcyD3w+/yD4P9tIRAoLlAJsHZWWhbEADKVfC3blCpG0cY9HStwCeNWZZ IL9fNNCb5TazTmklf8blE3c= =nRGq -----END PGP SIGNATURE-----
Apr 24 2006
Thomas Kuehne wrote:-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jarrett Billingsley schrieb am 2006-04-25:or writef( arg ~ ' ' );"Boris Wang" <nano.kago hotmail.com> wrote in message news:e2k46n$1dkm$1 digitaldaemon.com...<snip>The first printf can't display the information, and the second do.Uhh, yes it does. For me, anyway. But I think the real question here is - why are you using printf instead of writef? ;)for ( int i = 1; i < args.length; i++ ) { writef( args[i], ' ' ); }That's usually not a good idea(unchecked format strings...), instead use: for ( int i = 1; i < args.length; i++ ) { writef("%s ", args[i]); } Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFETcyD3w+/yD4P9tIRAoLlAJsHZWWhbEADKVfC3blCpG0cY9HStwCeNWZZ IL9fNNCb5TazTmklf8blE3c= =nRGq -----END PGP SIGNATURE-----
Apr 25 2006
Thomas Kuehne wrote:That's usually not a good idea(unchecked format strings...)Huh? In what kind of situation are the following two not equivalent? writef("%s", s); writef(s); Regardless of the type of s, these surely work the same way, right? Some test code to argue my point: -- import std.stdio; template func(TYPE) { void func(TYPE s) { writef("'", s, "'"); writef(" and "); writef("'%s'", s); writefln(); }} class Foo { char[] toString() { return "fooclass"; } } void main() { func("asdf"); func(1234); func(true); func('n'); func(0.1234); func(new Foo()); } -- In func's output, what's on the left side of the "and" is the same as on the right, in all six cases.
Apr 25 2006
Deewiant wrote:Thomas Kuehne wrote:func("%s%s%s"); :) xs0That's usually not a good idea(unchecked format strings...)Huh? In what kind of situation are the following two not equivalent? writef("%s", s); writef(s); Regardless of the type of s, these surely work the same way, right? Some test code to argue my point: -- import std.stdio; template func(TYPE) { void func(TYPE s) { writef("'", s, "'"); writef(" and "); writef("'%s'", s); writefln(); }} class Foo { char[] toString() { return "fooclass"; } } void main() { func("asdf"); func(1234); func(true); func('n'); func(0.1234); func(new Foo()); } -- In func's output, what's on the left side of the "and" is the same as on the right, in all six cases.
Apr 25 2006
Deewiant wrote:When the string contains format characters (that would be '%')That's usually not a good idea(unchecked format strings...)Huh? In what kind of situation are the following two not equivalent?writef("%s", s); writef(s); Regardless of the type of s, these surely work the same way, right?import std.stdio; void main() { char[] s = "100%"; writef(s); } ==> Throws an error: 100Error: std.format invalid specifier import std.stdio; void main() { char[] s = "100%"; writef("%s", s); } ==> This works OK. I suggested adding a function "write", that *didn't* parse for format characters (and the matching "writeln" function), but it was ignored... import std.stdio; void main() { char[] s = "100%"; write(s); } http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/15627 --anders
Apr 25 2006
Anders F Bj鰎klund wrote:When the string contains format characters (that would be '%')Ah, of course. Thanks for reminding me, to xs0 as well.
Apr 25 2006
Deewiant wrote:Printf has the same problem. I bet you could trigger some real nice buffer overflows by abusing this "feature"... IMNSHO: Telling newcomers to use printf("Hello") or writef("World") will just make them shoot themselves in the foot later on. Whenever you introduce either, you need to talk about "formats". Which is why it's better if there's an alternative *without* ? Like in C: #include <stdio.h> int main(int argc, char* argv[]) { puts("Hello, World!"); return 0; } But that's just what I thought about the issue, nothing new. (And no, it's not a problem for strings without the percent) --andersWhen the string contains format characters (that would be '%')Ah, of course. Thanks for reminding me, to xs0 as well.
Apr 25 2006
In article <6uu0i3-m2i.ln1 birke.kuehne.cn>, Thomas Kuehne says...Jarrett Billingsley schrieb am 2006-04-25:This has bit me more than once. Maybe there should be a writef that won't do formatting (writefn("%s", 123); prints "%s123")for ( int i = 1; i < args.length; i++ ) { writef( args[i], ' ' ); }That's usually not a good idea(unchecked format strings...), instead use: for ( int i = 1; i < args.length; i++ ) { writef("%s ", args[i]); } Thomas
Apr 25 2006
On Tue, 25 Apr 2006 11:13:58 +0800, Boris Wang <nano.kago hotmail.com> wrote:int main( char[][] args ) { foreach( char[] arg; args[1 .. args.length] ) { printf( "%.*s ", arg ); } for ( int i = 0; i < args.length; i++ ) { printf("%.*s ", args[i] ); } return 0; } The first printf can't display the information, and the second do. I use dmd 0.154, XP SP2.The first one skips the first arg, to include the first arg use: foreach( char[] arg; args[0 .. args.length] ) { printf( "%.*s ", arg ); } Apart from that they produce identical output for me. Regan
Apr 24 2006
You are right, the args array begin from index 0, butforeach( char[] arg; args[0 .. args.length] )This should not be right, it should be : foreach( char[] arg; args[0 .. args.length - 1] ) 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) "Regan Heath" <regan netwin.co.nz> ??????:ops8jr1mr223k2f5 nrage.netwin.co.nz...On Tue, 25 Apr 2006 11:13:58 +0800, Boris Wang <nano.kago hotmail.com> wrote:int main( char[][] args ) { foreach( char[] arg; args[1 .. args.length] ) { printf( "%.*s ", arg ); } for ( int i = 0; i < args.length; i++ ) { printf("%.*s ", args[i] ); } return 0; } The first printf can't display the information, and the second do. I use dmd 0.154, XP SP2.The first one skips the first arg, to include the first arg use: foreach( char[] arg; args[0 .. args.length] ) { printf( "%.*s ", arg ); } Apart from that they produce identical output for me. Regan
Apr 24 2006
The suitable explain is : args[ leftLimit .. rightLimit ] the leftLimit is the first index, and the rightLimit is the last index + 1, just equal with args.length. but we used to write the following code: for ( int i = 0; i < len - 1; i ++ ) .... "Boris Wang" <nano.kago hotmail.com> 写入消息新闻:e2kdlg$1p04$1 digitaldaemon.com...You are right, the args array begin from index 0, butforeach( char[] arg; args[0 .. args.length] )This should not be right, it should be : foreach( char[] arg; args[0 .. args.length - 1] ) 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) "Regan Heath" <regan netwin.co.nz> ??????:ops8jr1mr223k2f5 nrage.netwin.co.nz...On Tue, 25 Apr 2006 11:13:58 +0800, Boris Wang <nano.kago hotmail.com> wrote:int main( char[][] args ) { foreach( char[] arg; args[1 .. args.length] ) { printf( "%.*s ", arg ); } for ( int i = 0; i < args.length; i++ ) { printf("%.*s ", args[i] ); } return 0; } The first printf can't display the information, and the second do. I use dmd 0.154, XP SP2.The first one skips the first arg, to include the first arg use: foreach( char[] arg; args[0 .. args.length] ) { printf( "%.*s ", arg ); } Apart from that they produce identical output for me. Regan
Apr 24 2006
On Tue, 25 Apr 2006 14:10:26 +0800, Boris Wang <nano.kago hotmail.com> wrote:The suitable explain is : args[ leftLimit .. rightLimit ] the leftLimit is the first index, and the rightLimit is the last index + 1, just equal with args.length.Or rather, that rightLimit is one past the last item you want to include. To include the entire array you use 0 and array.length.but we used to write the following code: for ( int i = 0; i < len - 1; i ++ )To access items in the slice args[0..args.length] you would use this for loop: for(int i = 0; i < args.length; i++) {} or one of these foreach statements: foreach(int i, char[] arg; args) {} foreach(char[] arg; args) {} foreach(arg; args) {} Regan"Boris Wang" <nano.kago hotmail.com> 脨 麓脠毛脧没脧垄脨脗脦脜:e2kdlg$1p04$1 digitaldaemon.com...You are right, the args array begin from index 0, butforeach( char[] arg; args[0 .. args.length] )This should not be right, it should be : foreach( char[] arg; args[0 .. args.length - 1] ) 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) "Regan Heath" <regan netwin.co.nz> ??????:ops8jr1mr223k2f5 nrage.netwin.co.nz...On Tue, 25 Apr 2006 11:13:58 +0800, Boris Wang <nano.kago hotmail.com> wrote:int main( char[][] args ) { foreach( char[] arg; args[1 .. args.length] ) { printf( "%.*s ", arg ); } for ( int i = 0; i < args.length; i++ ) { printf("%.*s ", args[i] ); } return 0; } The first printf can't display the information, and the second do. I use dmd 0.154, XP SP2.The first one skips the first arg, to include the first arg use: foreach( char[] arg; args[0 .. args.length] ) { printf( "%.*s ", arg ); } Apart from that they produce identical output for me. Regan
Apr 25 2006
On Tue, 25 Apr 2006 13:55:21 +0800, Boris Wang <nano.kago hotmail.com> wrote:You are right, the args array begin from index 0, butThat 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)foreach( char[] arg; args[0 .. args.length] )This should not be right, it should be : foreach( char[] arg; args[0 .. args.length - 1] )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
Apr 25 2006
Best regards to you! Thanks "Regan Heath" <regan netwin.co.nz> ??????:ops8jx4rqc23k2f5 nrage.netwin.co.nz...On Tue, 25 Apr 2006 13:55:21 +0800, Boris Wang <nano.kago hotmail.com> wrote:You are right, the args array begin from index 0, butThat 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)foreach( char[] arg; args[0 .. args.length] )This should not be right, it should be : foreach( char[] arg; args[0 .. args.length - 1] )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
Apr 25 2006
"Regan Heath" <regan netwin.co.nz> ??????:ops8jx4rqc23k2f5 nrage.netwin.co.nz...On Tue, 25 Apr 2006 13:55:21 +0800, Boris Wang <nano.kago hotmail.com> wrote:Why not a complie error, but a runtime error?You are right, the args array begin from index 0, butThat 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)foreach( char[] arg; args[0 .. args.length] )This should not be right, it should be : foreach( char[] arg; args[0 .. args.length - 1] )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
Apr 25 2006
On Tue, 25 Apr 2006 15:51:03 +0800, Boris Wang <nano.kago hotmail.com> wrote:"Regan Heath" <regan netwin.co.nz> ??????:ops8jx4rqc23k2f5 nrage.netwin.co.nz...I believe the rationale is that it is not possible for the compiler to detect all possible situations with 100% certainty. I suspect Walter came to that conclusion adding this sort of compile time detection to his C/C++ compiler. ReganOn Tue, 25 Apr 2006 13:55:21 +0800, Boris Wang <nano.kago hotmail.com> wrote:Why not a complie error, but a runtime error?You are right, the args array begin from index 0, butThat 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)foreach( char[] arg; args[0 .. args.length] )This should not be right, it should be : foreach( char[] arg; args[0 .. args.length - 1] )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; }
Apr 25 2006