Re: readf with strings
Ali Çehreli: > "oku" means "read": > > // Read into an existing variable > double d; > oku("Please enter a double: ", &d); > > // Read and return a value > int i = oku!int("Please enter an int: "); I have a related enhancement request since lot of time: http://d.puremagic.com/issues/show_bug.cgi?id=4716 Bye, bearophile
Re: readf with strings
On 06/22/2011 09:30 AM, Ali Çehreli wrote: On Wed, 22 Jun 2011 14:57:57 +, GreatEmerald wrote: This should be a very elementary question. How do you get a string off stdin? Or an integer, or a boolean, for that matter? If I use this: float MyFloat; string MyString; readf("%f",&MyFloat); writeln(MyFloat); readf("%s",&MyString); writeln(MyString); I get the float printed correctly, but when it asks to input the string, whatever I input gets ignored - I can't reach the writeln part in any way and I have to forcibly close the program. The same thing is with ints - if I enter an int, it acts as if I didn't enter anything at all. But floats work fine for some reason. Any thoughts about what is happening there? I'm using openSUSE 11.4 and DMD 2.053. Reading from an input stream is sometimes confusing. Things to remember: - Use %s for any type unless there is reason not to - The line terminator from the previous entry is still in the input. (You may call readf(" ") to flush those white space characters. (I've just discovered this.)) - string can hold any character including space and the line terminator. That's why pressing the Enter doesn't terminate reading a string. - Use a space character before any format specifier to ignore zero or more whitespace characters before the previous input: " %s". - To read a string (actually a line), use chomp(readln()) - I don't know whether this is intended and I don't think that we should routinely use this: The EOF (Ctrl-D on Unix consoles, Ctrl-Z on Windows) terminates reading the string but strangely not the entire input. import std.stdio; import std.string; void main() { float MyFloat; readf(" %s",&MyFloat); writeln(MyFloat); readf(" "); string MyString = chomp(readln()); writeln(MyString); } Ali Remember that readf is reading characters, and converting them to types for you. I've just gotten in the habbit of reading in the string, and then parsing the string on my own. Readf doesn't grant me anything special that I can't do on my own. It's easy enough to do something like this: [kai.meyer@kai-rhel6 sandbox]$ cat d_read.d import std.stdio; import std.string; import std.conv; void main() { string[] buffer; int a; float b; string c; buffer = chomp(readln()).split(" "); a = to!(int)(buffer[0]); b = to!(float)(buffer[1]); c = buffer[2..$].join(" "); writef("Read in: '%d' '%f' '%s'\n", a, b, c); } If I type: 1 1.3 this is a string On the command line after the execution, I get this back: Read in: '1' '1.30' 'this is a string' It's not very stream-ish, because readln breaks on a new line. You could call the "buffer = chomp..." line again if (buffer.length == 0) before you attempt another conversion.
Re: readf with strings
On Wed, 22 Jun 2011 13:45:56 -0500, Jimmy Cao wrote: > On Wed, Jun 22, 2011 at 1:31 PM, Ali Çehreli wrote: > >> On Wed, 22 Jun 2011 20:17:39 +0200, Andrej Mitrovic wrote: >> >> > This library has some nice user-input methods for D2: >> > https://github.com/he-the-great/JPDLibs/tree/cmdln >> >> Thanks! :) >> >> The Turkish D community has experimented with a similar solution: >> >> http://ddili.org/forum/post/2960 > The design of this community site is quite splendid. Thank you! :) We have three books too: - D Programming Language (complete, except special memory management like emplace(), the 'new' and 'delete' operators, interacting with the garbage collector, etc. That chapter is being written as we speak) - GtkD (needs work) - Game Programming with SDL (freshly started; moving on pretty well) http://ddili.org/ders/index.html > So D has three > major language sub-communities: German, Japanese, and Turkish? The wiki lists others: http://www.prowiki.org/wiki4d/wiki.cgi Ali
Re: readf with strings
On Wed, Jun 22, 2011 at 1:31 PM, Ali Çehreli wrote: > On Wed, 22 Jun 2011 20:17:39 +0200, Andrej Mitrovic wrote: > > > This library has some nice user-input methods for D2: > > https://github.com/he-the-great/JPDLibs/tree/cmdln > > Thanks! :) > > The Turkish D community has experimented with a similar solution: > > http://ddili.org/forum/post/2960 > > "oku" means "read": > >// Read into an existing variable >double d; >oku("Please enter a double: ", &d); > >// Read and return a value >int i = oku!int("Please enter an int: "); > > Ali > The design of this community site is quite splendid. So D has three major language sub-communities: German, Japanese, and Turkish?
Re: readf with strings
I didn't know there was a Turkish D community. :)
Re: readf with strings
On Wed, 22 Jun 2011 20:17:39 +0200, Andrej Mitrovic wrote: > This library has some nice user-input methods for D2: > https://github.com/he-the-great/JPDLibs/tree/cmdln Thanks! :) The Turkish D community has experimented with a similar solution: http://ddili.org/forum/post/2960 "oku" means "read": // Read into an existing variable double d; oku("Please enter a double: ", &d); // Read and return a value int i = oku!int("Please enter an int: "); Ali
Re: An effort at creating a free ebook for learning D
I've done some major restructuring to the ebook. Now, the link to the first lesson is: http://en.wikibooks.org/wiki/D_(The_Programming_Language)/d2/Phobos/Lesson_1 There are 7 lessons currently. Lesson 3 (Functions) and 9 (Slicing) are not written as of now. If you contribute, please add yourself to: http://en.wikibooks.org/wiki/D_(The_Programming_Language)/Contributors Please, do feel free to add content, tips, and code. There's no errata; just fix it, that's all. Anybody know a good idea for a picture to put in the index page: http://en.wikibooks.org/wiki/D_(The_Programming_Language) ? Thanks Jimmy
Re: readf with strings
On Wed, 22 Jun 2011 20:59:46 +0300, Dainius (GreatEmerald) wrote: > I see. Using %s does indeed work with ints, and chomp(readln()) works > with strings. It's rather counter-intuitive, though. There are many counter intuitive bits and imperfect modelling in stream I/ O. For example "42a" is perfectly fine when reading an int because the reader decides that the '4' and '2' characters make up the int and 'a' must be for something else. Why? :) What if I really meant that "42a" should be read as int. It should be an error! I think strings are special because they are powerful to take any character. Additionally output and input are not symmetrical: The ints 1 and 2 would be written as 12 back to back but they can't be read as two ints. > I wonder why there > isn't a simpler way to do this, something like writeln() - you could > input the variables as parameters and it would automatically read > them... I know that the insistence on the space character to munch white space is intentional. Andrei commented on a bug that this is more consistent than scanf()'s implicit munching. There is that is being (is?) deprecated. It reads simpler like writeln: import std.cstream; void main() { double d; int i; din.readf(&d, &i); dout.writefln("d: %s, i: %s", d, i); } It would still be problematic with strings. How many characters should be a part of it? Ali
Re: readf with strings
This library has some nice user-input methods for D2: https://github.com/he-the-great/JPDLibs/tree/cmdln
Re: An effort at creating a free ebook for learning D
On Mon, 20 Jun 2011 16:13:37 -0600, Kai Meyer wrote: > I wrote some code a while back that was intended to be portable (between > windows and linux anyway). I used 'writef("Hello\n");' a lot, and those > always printed correctly on windows. Does writef do something different > than write with the '\n' character? (I can't see Jose Armando Garcia's answer to this question. For some reason it appears empty in my news reader (Pan 0.133).) As far as I know, "text mode" file access already translates those characters. '\n' always means "new line" to be replaced with each platform's correct code sequence. Ali
Re: readf with strings
I see. Using %s does indeed work with ints, and chomp(readln()) works with strings. It's rather counter-intuitive, though. I wonder why there isn't a simpler way to do this, something like writeln() - you could input the variables as parameters and it would automatically read them...
Re: Implicit conversion of unique objects to mutable and immutable
On Wed, 22 Jun 2011 15:58:02 +, Timon Gehr wrote: > On Wed, 22 Jun 2011 00:02:55 +, Ali Çehreli wrote: > >> I wonder whether a UniqueRef object could be returned, which could >> allow a single casting of its data to mutable or immutable at the call >> site. Further casts could throw, but that would be a runtime solution. >> :-/ > > Further casts should return null. I thought about that too but if null is a valid value itself and if the value should be casted only once, throwing seemed a better choice. > Timon Ali
Re: Implicit conversion of unique objects to mutable and immutable
On Wed, 22 Jun 2011 00:02:55 +, Ali Çehreli wrote: > I wonder whether a UniqueRef object could be returned, which could allow > a single casting of its data to mutable or immutable at the call site. > Further casts could throw, but that would be a runtime solution. :-/ Further casts should return null. Timon
Re: readf with strings
On Wed, 22 Jun 2011 14:57:57 +, GreatEmerald wrote: > This should be a very elementary question. How do you get a string off > stdin? Or an integer, or a boolean, for that matter? If I use this: > > float MyFloat; > string MyString; > readf("%f", &MyFloat); > writeln(MyFloat); > readf("%s", &MyString); > writeln(MyString); > > I get the float printed correctly, but when it asks to input the string, > whatever I input gets ignored - I can't reach the writeln part in any > way and I have to forcibly close the program. The same thing is with > ints - if I enter an int, it acts as if I didn't enter anything at all. > But floats work fine for some reason. Any thoughts about what is > happening there? > > I'm using openSUSE 11.4 and DMD 2.053. Reading from an input stream is sometimes confusing. Things to remember: - Use %s for any type unless there is reason not to - The line terminator from the previous entry is still in the input. (You may call readf(" ") to flush those white space characters. (I've just discovered this.)) - string can hold any character including space and the line terminator. That's why pressing the Enter doesn't terminate reading a string. - Use a space character before any format specifier to ignore zero or more whitespace characters before the previous input: " %s". - To read a string (actually a line), use chomp(readln()) - I don't know whether this is intended and I don't think that we should routinely use this: The EOF (Ctrl-D on Unix consoles, Ctrl-Z on Windows) terminates reading the string but strangely not the entire input. import std.stdio; import std.string; void main() { float MyFloat; readf(" %s", &MyFloat); writeln(MyFloat); readf(" "); string MyString = chomp(readln()); writeln(MyString); } Ali
readf with strings
This should be a very elementary question. How do you get a string off stdin? Or an integer, or a boolean, for that matter? If I use this: float MyFloat; string MyString; readf("%f", &MyFloat); writeln(MyFloat); readf("%s", &MyString); writeln(MyString); I get the float printed correctly, but when it asks to input the string, whatever I input gets ignored - I can't reach the writeln part in any way and I have to forcibly close the program. The same thing is with ints - if I enter an int, it acts as if I didn't enter anything at all. But floats work fine for some reason. Any thoughts about what is happening there? I'm using openSUSE 11.4 and DMD 2.053.
Re: Implicit conversion of unique objects to mutable and immutable
On Tue, 21 Jun 2011 20:31:19 -0400, Jonathan M Davis wrote: On 2011-06-21 16:50, Ali Çehreli wrote: On Tue, 21 Jun 2011 23:02:43 +, Jonathan M Davis wrote: > On 2011-06-21 15:25, Ali Çehreli wrote: >> (Note: I have a feeling that this must be related to the old 'unique' >> discussions, which I had somehow managed to stay out of. If so, I >> apologize for repeating an old story.) >> >> It is most useful for a function to return the most mutable type unless >> there is good reason not to. Do you agree? > > No. In a lot of cases, what you generally want is immutable, not > mutable. In particular, if you're talking about strings, we favor > string, wstring, and dstring over char[], wchar[], or dchar[] unless you > actually need to alter the string. I agree with all of that, but it should not be the function that restricts the caller. The function should return immutable only when the result is really immutable. If the returned object is mutable and unique, it is pretentious of the function to evangelically return immutable. :) Besides, the caller can't know whether it was actually mutable but was returned as immutable because it was the right thing to do. Otherwise the caller could cast to mutable to save a copy. > immutable is preferred, because it's generally more efficient. Not in this case because the caller must make a copy to mutate further. If the function could return 'unique mutable' and if that could be casted to immutable implicitly, then all would be fine. As I said, in Phobos, when a new string must be allocated, the type returned is generally string (so it's immutable), whereas if the result of the function is likely to be slice of the string passed in, then the function is templated to return the same type of string as was passed to it. There's no extraneous copying going on in order to return string. The _only_ case where it's arguably forced on the caller is in the case where a copy _must_ be made, in which case the function returns string rather than char[]. The issue is that newly-allocated data can be considered unique. It would be advantageous for this to implicitly cast to mutable *or* immutable. In other words, imposing the immutable limitation is artificial, and in some cases makes things less usable. Think about dup and idup. Wouldn't it be more straightforward if you just did dup and assigned it to whatever type you wanted? Wouldn't it be more universal if all functions that create new data didn't have to have a mutable and immutable version? If it's a slice of the input, it should be using inout, but inout is broken. I think the clear path here is to use strong-pure functions to implicitly cast to immutable. Such functions would have to return char[] because if it returns const(char)[] or immutable(char)[], it's possible the result is a slice of the input. For example, the following function can only return a newly-allocated char[] (without using casts): pure char[] foo(immutable(char)[] arg1, const(char)[] arg2)) {...} So it is safe to assume the return is unique. To answer Ali, we can add unique to the language, but this adds yet another type of const (unique has to do with const). This might not go over well in a language with already 4 types of const (const, mutable, immutable, inout). Where it does help quite a bit is for sharing mutable data, but of course, we can start building library constructs that allow that. -Steve