Thread overview | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 28, 2005 to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Greetings! I am getting a little annoyed with printf. But, I am more concerned with d, than with printf. Let us admired this complicated piece of code: import std.stdio; import std.string; int main(char[][] args) { char[] tt = "Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version: 1.0Set-Cookie:"; char[][] temp = std.string.split(tt,"MIME"); writefln(temp[0]); printf(temp[0]); return (0); } results in this output: 15:29:20.09>test0 Web Server 2.1.2.56 created 8/14/01 6:33 PM Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version: 1.0Set-Cookie: which is very weird to me. Why? Well, because temp[0] should have the splited part that result that writefln prints out. Why is printf still looking at tt? Or even a better question: why is temp[0] referring to tt when printf is calling temp[0]? These are questions that need answers. :-) so, printf is going to be my last result from now on. All of my print-outs will be done with writef. Please help me understand this. thanks, josé |
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to jicman | "jicman" <jicman_member@pathlink.com> wrote in message news:cvvv03$im1$1@digitaldaemon.com... > > Greetings! > > I am getting a little annoyed with printf. But, I am more concerned with > d, > than with printf. Let us admired this complicated piece of code: > > import std.stdio; > import std.string; > int main(char[][] args) > { > char[] tt = "Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version: > 1.0Set-Cookie:"; > char[][] temp = std.string.split(tt,"MIME"); > writefln(temp[0]); > printf(temp[0]); > return (0); > } > > results in this output: > > 15:29:20.09>test0 > Web Server 2.1.2.56 created 8/14/01 6:33 PM > Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version: 1.0Set-Cookie: > > which is very weird to me. Why? Well, because temp[0] should have the > splited > part that result that writefln prints out. Why is printf still looking at > tt? > Or even a better question: why is temp[0] referring to tt when printf is > calling > temp[0]? These are questions that need answers. :-) split returns slices of the original string and printf prints until it hits 0. If you are going to use printf try printf("%.*s",temp[0]); see http://www.digitalmars.com/d/faq.html#printf > > so, printf is going to be my last result from now on. All of my > print-outs will > be done with writef. good idea. > Please help me understand this. > > thanks, > > josé > > |
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle |
Thanks Ben. Me and my lack of reading... :-)
Ben Hinkle says...
>
>
>"jicman" <jicman_member@pathlink.com> wrote in message news:cvvv03$im1$1@digitaldaemon.com...
>>
>> Greetings!
>>
>> I am getting a little annoyed with printf. But, I am more concerned with
>> d,
>> than with printf. Let us admired this complicated piece of code:
>>
>> import std.stdio;
>> import std.string;
>> int main(char[][] args)
>> {
>> char[] tt = "Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version:
>> 1.0Set-Cookie:";
>> char[][] temp = std.string.split(tt,"MIME");
>> writefln(temp[0]);
>> printf(temp[0]);
>> return (0);
>> }
>>
>> results in this output:
>>
>> 15:29:20.09>test0
>> Web Server 2.1.2.56 created 8/14/01 6:33 PM
>> Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version: 1.0Set-Cookie:
>>
>> which is very weird to me. Why? Well, because temp[0] should have the
>> splited
>> part that result that writefln prints out. Why is printf still looking at
>> tt?
>> Or even a better question: why is temp[0] referring to tt when printf is
>> calling
>> temp[0]? These are questions that need answers. :-)
>
>
>split returns slices of the original string and printf prints until it hits
>0. If you are going to use printf try
>printf("%.*s",temp[0]);
>see http://www.digitalmars.com/d/faq.html#printf
>
>>
>> so, printf is going to be my last result from now on. All of my
>> print-outs will
>> be done with writef.
>
>good idea.
>
>> Please help me understand this.
>>
>> thanks,
>>
>> josé
>>
>>
>
>
|
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to jicman | On Mon, 28 Feb 2005 20:29:55 +0000 (UTC), jicman wrote: > Greetings! > > I am getting a little annoyed with printf. But, I am more concerned with d, than with printf. Let us admired this complicated piece of code: > > import std.stdio; > import std.string; > int main(char[][] args) > { > char[] tt = "Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version: > 1.0Set-Cookie:"; > char[][] temp = std.string.split(tt,"MIME"); > writefln(temp[0]); > printf(temp[0]); > return (0); > } > > results in this output: > > 15:29:20.09>test0 > Web Server 2.1.2.56 created 8/14/01 6:33 PM > Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version: 1.0Set-Cookie: > > which is very weird to me. Why? Well, because temp[0] should have the splited part that result that writefln prints out. Why is printf still looking at tt? Or even a better question: why is temp[0] referring to tt when printf is calling temp[0]? These are questions that need answers. :-) > > so, printf is going to be my last result from now on. All of my print-outs will be done with writef. > > Please help me understand this. I'll give it a go ;-) My advice firstly though is to stop using printf, just use writef. Second advice, if you are writing out the contents of strings, always use a %s. This will help avoid embedded '%' in your input string. writefln("%s", temp[0]); Ok, printf assumes that strings are ASCII and zero-terminated. writef however uses D strings, and they look like a type of struct ... struct DString { uint length; char* data } So if you supply a D string to printf, it stops outputting when it finally reaches a zero 'char'. Now the split() routine returns a sliced string, that is it returns a D string that is actually pointing to the original string in tt but with a different length. split() is not returning a *copy* of tt, but a new reference to tt. However, this is not a problem for writef() because that uses the length information, but printf() does not use the length info. For example, let's say that tt look like this { 72; #07DE4E90 }. That is, it has a length of 72 and an address pointer to #07DE4E90. When you do the split() call, then temp[][] is now an array of two D strings... [ { 43; #07DE4E90 }, { 25; #07DE4EBF } ] No extra RAM has been used up by copying string data, instead you now have two new references into the original string. We don't have to concern ourselves with the true D string format as D does all this for us. -- Derek Melbourne, Australia |
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek |
Lovely! (The explanation, that is. :-))
thanks.
Derek says...
>
>On Mon, 28 Feb 2005 20:29:55 +0000 (UTC), jicman wrote:
>
>> Greetings!
>>
>> I am getting a little annoyed with printf. But, I am more concerned with d, than with printf. Let us admired this complicated piece of code:
>>
>> import std.stdio;
>> import std.string;
>> int main(char[][] args)
>> {
>> char[] tt = "Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version:
>> 1.0Set-Cookie:";
>> char[][] temp = std.string.split(tt,"MIME");
>> writefln(temp[0]);
>> printf(temp[0]);
>> return (0);
>> }
>>
>> results in this output:
>>
>> 15:29:20.09>test0
>> Web Server 2.1.2.56 created 8/14/01 6:33 PM
>> Web Server 2.1.2.56 created 8/14/01 6:33 PMMIME-version: 1.0Set-Cookie:
>>
>> which is very weird to me. Why? Well, because temp[0] should have the splited part that result that writefln prints out. Why is printf still looking at tt? Or even a better question: why is temp[0] referring to tt when printf is calling temp[0]? These are questions that need answers. :-)
>>
>> so, printf is going to be my last result from now on. All of my print-outs will be done with writef.
>>
>> Please help me understand this.
>
>I'll give it a go ;-)
>
>My advice firstly though is to stop using printf, just use writef. Second advice, if you are writing out the contents of strings, always use a %s. This will help avoid embedded '%' in your input string.
>
> writefln("%s", temp[0]);
>
>Ok, printf assumes that strings are ASCII and zero-terminated. writef however uses D strings, and they look like a type of struct ...
>
>struct DString { uint length; char* data }
>
>So if you supply a D string to printf, it stops outputting when it finally reaches a zero 'char'.
>
>Now the split() routine returns a sliced string, that is it returns a D
>string that is actually pointing to the original string in tt but with a
>different length. split() is not returning a *copy* of tt, but a new
>reference to tt. However, this is not a problem for writef() because that
>uses the length information, but printf() does not use the length info.
>
>For example, let's say that tt look like this { 72; #07DE4E90 }. That is, it has a length of 72 and an address pointer to #07DE4E90. When you do the split() call, then temp[][] is now an array of two D strings...
> [ { 43; #07DE4E90 },
> { 25; #07DE4EBF }
> ]
>
>No extra RAM has been used up by copying string data, instead you now have two new references into the original string.
>
>We don't have to concern ourselves with the true D string format as D does all this for us.
>
>--
>Derek
>Melbourne, Australia
|
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek | Derek wrote: > Ok, printf assumes that strings are ASCII and zero-terminated. writef > however uses D strings, and they look like a type of struct ... > > struct DString { uint length; char* data } Side note: Note that a D array is really: { size_t length; void* data; } That is, the "length" type of an array is *not* equal to uint! Not that the distinction is important on a 32-bit machine, but it will be once the language starts targetting 64-bits... Same goes for .sizeof and .alignof, and array indexes. Better get in the habit of writing size_t already ? See http://www.digitalmars.com/d/portability.html --anders |
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to jicman | "jicman" <jicman_member@pathlink.com> wrote in message news:d0026v$mcl$1@digitaldaemon.com... > > Thanks Ben. Me and my lack of reading... :-) Don't worry about it. Every single person new to D does it. You'll find that the use of slices is one of the unique things that makes D truly (potentially) great. AFAIUI, Kris' Mango is able to do huge amounts of performance-sensitive stuff without allocating any memory as a consequence of it! |
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek | On Tue, 1 Mar 2005 08:25:23 +1100, Derek <derek@psych.ward> wrote: > Second > advice, if you are writing out the contents of strings, always use a %s. > This will help avoid embedded '%' in your input string. > > writefln("%s", temp[0]); IIRC all parameters of writefln are treated as format strings, meaning, if temp[0] above contains a %s, another parameter is expected. The only way around this is to process every string you print with the write functions, changing % to %%. On one hand this is bad(tm). You have to process all strings, there are many potential bugs/problems. On the other hand this is good(tm). You are able to use a format string anywhere eg. writefln("%5s",a,b,i,"%.6f",f); if probably more easily understood, and less prone to bugs (wrong format specifier) than: writefln("%5s %s %d %.6f",a,b,i,f); If the write functions could somehow tell a format string apart from a normal string. eg. char[] a = "%s and %s"; char[] b = "pass"; char[] c = "fail" writefln(f"%s and %s",b,c); writefln(format(a),b,c); this seems to be a pain to me, someone might forget to use format() on a var, of forget to prefix with f and wonder why it's not working. Perhaps the opposite is better. char[] a = "%s and %s"; char[] b = "pass"; char[] c = "fail" writefln("%s and %s",noformat(b),noformat(c)); writefln(a,noformat(b),noformat(c)); but then, it's more likely you have less format strings, so neither of these options seem very nice to me. Does anyone have any good ideas? Regan |
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anders F Björklund | On Mon, 28 Feb 2005 23:06:57 +0100, Anders F Björklund wrote: > Derek wrote: > >> Ok, printf assumes that strings are ASCII and zero-terminated. writef however uses D strings, and they look like a type of struct ... >> >> struct DString { uint length; char* data } > > Side note: > Note that a D array is really: { size_t length; void* data; } > That is, the "length" type of an array is *not* equal to uint! > > Not that the distinction is important on a 32-bit machine, but it will be once the language starts targetting 64-bits... Anders is correct (of course). And the reason is found in object.d ... version (AMD64) { alias ulong size_t; alias long ptrdiff_t; } else { alias uint size_t; alias int ptrdiff_t; } On the other hand, if I have to start dealing with strings that have 18,446,744,073,709,551,616 characters in them, I'm sure I'm already in big trouble. ;-) -- Derek Melbourne, Australia 1/03/2005 9:59:15 AM |
February 28, 2005 Re: to printf or to writef? That is the question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath wrote: > IIRC all parameters of writefln are treated as format strings, meaning, if temp[0] above contains a %s, another parameter is expected. Not all parameters. *At every position*. But if one is "%s", the next is a string. So this is cool: writefln("%s", "%"); This is not: writefln("%s", "%", "%"); > The only way around this is to process every string you print with the write functions, changing % to %%. You don't need to change the strings, just the formats. > On one hand this is bad(tm). You have to process all strings, there are many potential bugs/problems. Nope. "Only" the format ones (which is bad enough...) > Does anyone have any good ideas? I wrote a patch for a "writeln" function that was the same as writefln, but without the formats. (i.e. all strings are normal, no need to double up the percentages anywhere) writefln("Hello!"); writeln("100%"); It's working just great. You can still use variadic args: writeln(100, "%"); --anders |
Copyright © 1999-2021 by the D Language Foundation