Re: "readln" after "readf"
On Thursday, 21 September 2023 at 11:30:02 UTC, Steven Schveighoffer wrote: On Thursday, 21 September 2023 at 09:14:14 UTC, pascal111 wrote: [...] Your readfs are not consuming the newline at the end. Add `\n` to the end of the format text. -Steve It works fine now, thanks!
Re: "readln" after "readf"
On Thursday, 21 September 2023 at 09:14:14 UTC, pascal111 wrote: I've a problem when I'm using "readln" after "readf" that I couldn't see my program rest and the lines of the execution ran fast: module main; import std.stdio; import std.string; import std.conv; int main(string[] args) { char[] yy; int x,y,z; writef("Enter a number: "); readf(" %d",&x); writef("Enter a number: "); readf(" %d",&y); z=x+y; writefln("Hi! %d",z); writef("Enter a number: "); readln(yy); yy = strip(yy); x=to!int(yy); writef("Enter a number: "); readln(yy); yy = strip(yy); y=to!int(yy); z=x+y; writefln("Hi! %d",z); return 0; } Your readfs are not consuming the newline at the end. Add `\n` to the end of the format text. -Steve
"readln" after "readf"
I've a problem when I'm using "readln" after "readf" that I couldn't see my program rest and the lines of the execution ran fast: module main; import std.stdio; import std.string; import std.conv; int main(string[] args) { char[] yy; int x,y,z; writef("Enter a number: "); readf(" %d",&x); writef("Enter a number: "); readf(" %d",&y); z=x+y; writefln("Hi! %d",z); writef("Enter a number: "); readln(yy); yy = strip(yy); x=to!int(yy); writef("Enter a number: "); readln(yy); yy = strip(yy); y=to!int(yy); z=x+y; writefln("Hi! %d",z); return 0; }
Re: Calling readln() after readf
Thanks for the extra info guys! D is one of my favorite languages I'm currently learning. :)
Re: Calling readln() after readf
On 7/5/22 8:14 PM, Gary Chike wrote: On Monday, 20 June 2022 at 16:08:33 UTC, Ali Çehreli wrote: On 6/20/22 07:00, Gary Chike wrote: > Would it be appropriate to forego `readf` > and read input as a string using `readln` ,benefiting from the `strip` > function, then convert to their appropriate datatype Makes sense. The following are related as well: https://dlang.org/library/std/conv/parse.html https://dlang.org/library/std/format/read/formatted_read.html It's interesting from my own experimentation and observation, comparing `parse!int()` vs `to!int()` For instance, I can formulate a statement such as this using `to!int()`: `auto age = to!int(readln.strip());` but the same syntax using `parse!int()` would generate an error: `auto age = parse!int(readln.strip());` So, in order to use `parse!int()`, I would need to separate it into two statements with a variable acting as an intermediary: ``` auto input = readln(); auto age = parse!int(input); Yes, you have 2 orthogonal desires: 1. I want to update the original range or not 2. I want to treat the entire range as representing my conversion type or just the first part. Phobos only handles 2 of the 4 possible scenarios. Well, really one scenario (reading the entire range, and wanting to update the original) is not important. -Steve
Re: Calling readln() after readf
On 7/5/22 17:14, Gary Chike wrote: > So, in order to use `parse!int()`, I would need to separate it into two > statements with a variable acting as an intermediary: > ``` > auto input = readln(); > auto age = parse!int(input); Exactly. parse takes the input by reference (necessitating an lvalue) so that the input is consumed for the next step(s) of parsing. Ali
Re: Calling readln() after readf
On Monday, 20 June 2022 at 16:08:33 UTC, Ali Çehreli wrote: On 6/20/22 07:00, Gary Chike wrote: > Would it be appropriate to forego `readf` > and read input as a string using `readln` ,benefiting from the `strip` > function, then convert to their appropriate datatype Makes sense. The following are related as well: https://dlang.org/library/std/conv/parse.html https://dlang.org/library/std/format/read/formatted_read.html Ali It's interesting from my own experimentation and observation, comparing `parse!int()` vs `to!int()` For instance, I can formulate a statement such as this using `to!int()`: `auto age = to!int(readln.strip());` but the same syntax using `parse!int()` would generate an error: `auto age = parse!int(readln.strip());` So, in order to use `parse!int()`, I would need to separate it into two statements with a variable acting as an intermediary: ``` auto input = readln(); auto age = parse!int(input);
Re: Calling readln() after readf
On Monday, 20 June 2022 at 16:08:33 UTC, Ali Çehreli wrote: Makes sense. The following are related as well: https://dlang.org/library/std/conv/parse.html https://dlang.org/library/std/format/read/formatted_read.html Ali Thank you so much for your input! Cheers! :)
Re: Calling readln() after readf
On 6/20/22 07:00, Gary Chike wrote: > Would it be appropriate to forego `readf` > and read input as a string using `readln` ,benefiting from the `strip` > function, then convert to their appropriate datatype Makes sense. The following are related as well: https://dlang.org/library/std/conv/parse.html https://dlang.org/library/std/format/read/formatted_read.html Ali
Re: Calling readln() after readf
I should have qualified the above with: _ and I will be performing operations on the numeric datatype, since just outputting simply strings, as in the above example, would require nothing more than string data types. :) ```d module hello_world; import std.stdio; import std.string; // strip() import std.conv; // to!int(),to!float() void main() { writeln("Hello world from D!"); write("What is your name? "); auto fname = readln.strip; writeln("It's so nice to meet you ", fname, "!"); write("How old are you? "); auto age = to!int(readln.strip); write("What is your GPA? "); auto gpa = to!float(readln.strip); if (gpa > 4) { writeln("Sorry, 4 is the highest GPA "); gpa = 4; } writeln("So, ", fname, ", you are ", age, " years old and your GPA is ", gpa, ".. stellar!"); writeln("Can you increase your GPA? "); if(gpa == 4) { writeln("Your GPA is already as high as it can be!"); } else { gpa = gpa > 3.5 ? 4 : (gpa + 0.5); writeln("If you study hard, your GPA will likely be ", gpa); age = age + 4; writeln("But that may take 4 years, and you will be ", age, " years old by that time."); } } ```
Re: Calling readln() after readf
On Monday, 20 June 2022 at 00:43:17 UTC, Ali Çehreli wrote: ... But when the program interacts with piped data, there may be multiple \n characters and all of those might have to be ignored before reading the next non-empty line. So you may want to do readln.strip multiple times? I don't know. It all depends on the use case. Ali Thank you for your input, Ali! Would it be appropriate to forego `readf` and read input as a string using `readln` ,benefiting from the `strip` function, then convert to their appropriate datatype as in the following example?: ```d module hello_world; import std.stdio; import std.string; // strip() import std.conv; // to!int(),to!float() void main() { writeln("Hello world from D!"); write("What is your name? "); auto fname = readln.strip; writeln("It's so nice to meet you ", fname, "!"); write("How old are you? "); auto age = to!int(readln.strip); write("What is your GPA? "); auto gpa = to!float(readln.strip); writeln("So, ", fname, ", you are ", age, " years old and your GPA is ", gpa, ".. stellar!"); } ``` Also I signed up with Educative.io to do your interactive D language lessons. It really goes so well with your book :) Cheers, Gary Chike
Re: Calling readln() after readf
On 6/19/22 15:52, Gary Chike wrote: > On Saturday, 24 April 2021 at 22:13:45 UTC, Ali Çehreli wrote: >> On 4/24/21 7:46 AM, PinDPlugga wrote: >> ... >> As a general solution, you can use a function like this: >> >> auto readLine(S = string)(File file = stdin) { >> while (!file.eof) { >> auto line = file.readln!S.strip; >> if (!line.empty) { >> return line; >> } >> } >> >> return null; >> } >> >> Ali > > Hi Ali, > > Being a new D learner, I've noticed this behavior as well. Thank you for > providing the 'readLine' function! Would it be considered poor coding > style to intercept the stream between readf and readln with the > following statement? : > > ```d > auto catcher = readln.strip; > ``` The original program said "Please enter a number: ". If the program was interacting with a human and the human entered a number, then the rest of the line would be understood to be ignored and your method works. On the other hand, the readLine() function would not ignore the rest of the line and use it. But I think yours makes more sense. :) But when the program interacts with piped data, there may be multiple \n characters and all of those might have to be ignored before reading the next non-empty line. So you may want to do readln.strip multiple times? I don't know. It all depends on the use case. > P.S. I love your book on D! :) Thank you! :) > > Cheers, > > Gary Chike > Ali
Re: Calling readln() after readf
On Saturday, 24 April 2021 at 22:13:45 UTC, Ali Çehreli wrote: On 4/24/21 7:46 AM, PinDPlugga wrote: ... As a general solution, you can use a function like this: auto readLine(S = string)(File file = stdin) { while (!file.eof) { auto line = file.readln!S.strip; if (!line.empty) { return line; } } return null; } Ali Hi Ali, Being a new D learner, I've noticed this behavior as well. Thank you for providing the 'readLine' function! Would it be considered poor coding style to intercept the stream between readf and readln with the following statement? : ```d auto catcher = readln.strip; ``` P.S. I love your book on D! :) Cheers, Gary Chike
Re: A possible readf int bug
On Sunday, 27 June 2021 at 20:12:09 UTC, jfondren wrote: On Sunday, 27 June 2021 at 19:50:09 UTC, Matilda wrote: [...] This works with either readf line for me on v2.097.0. Try stracing your program. Okay, thank you. I'll try it out.
Re: A possible readf int bug
On Sunday, 27 June 2021 at 19:50:09 UTC, Matilda wrote: I'm trying to read from stdin and then print an integer value. This is how my code looks like: ```d import std.stdio; import std.conv; import std.string; void main() { writeln("Input your variant (1 - 10):"); int key; //readf(" %d", &key); //readf!" %d"(key); key = readln.strip.to!int; writefln("Your variant is: %d", key); } ``` The problem is that the programme doesn't work if I try to use one of the commented readf functions. It doesn't print the last phrase. There is no error message. It just waits for nothing apparently. It works with the stip.to!int line, so the problem must be with readf. I'm kind of new to this language and I don't have much experience with programming in general, so I have no way to know if it's just me being dumb or I've accidently found a bug. I use DMD32 D Compiler v2.097.0-dirty This works with either readf line for me on v2.097.0. Try stracing your program.
A possible readf int bug
I'm trying to read from stdin and then print an integer value. This is how my code looks like: ```d import std.stdio; import std.conv; import std.string; void main() { writeln("Input your variant (1 - 10):"); int key; //readf(" %d", &key); //readf!" %d"(key); key = readln.strip.to!int; writefln("Your variant is: %d", key); } ``` The problem is that the programme doesn't work if I try to use one of the commented readf functions. It doesn't print the last phrase. There is no error message. It just waits for nothing apparently. It works with the stip.to!int line, so the problem must be with readf. I'm kind of new to this language and I don't have much experience with programming in general, so I have no way to know if it's just me being dumb or I've accidently found a bug. I use DMD32 D Compiler v2.097.0-dirty
Re: Calling readln() after readf
On 4/24/21 7:46 AM, PinDPlugga wrote: > write("Please enter a number: "); > double number; > readf(" %s", number); Just to make sure, this is a common issue for other languages as well. As the explanation, the character ('\n') that you injected into stdin by pressing Enter is not (and should not be) removed by readf. > write("Please enter a string: "); > string input = strip(readln()); Because of that '\n' character, that readln() reads an empty line. There is no way other than reading and discarding all input at stdin but luckily, readf's "formatted" behavior is able to take care of it because any character that match the format string will be read and discarded by readf: readf(" %s\n", number); As a side note, that '\n' should work on all platforms even if the terminal injects two characters. As a general solution, you can use a function like this: auto readLine(S = string)(File file = stdin) { while (!file.eof) { auto line = file.readln!S.strip; if (!line.empty) { return line; } } return null; } Ali
Re: Calling readln() after readf
On Saturday, 24 April 2021 at 14:46:06 UTC, PinDPlugga wrote: I didn't want to necropost, but I ran into the same behaviour as in this post: https://forum.dlang.org/post/yfybveovbknvvxmio...@forum.dlang.org and was just curious to understand it better. [...] https://dlang.org/library/std/string/chomp.html
Calling readln() after readf
I didn't want to necropost, but I ran into the same behaviour as in this post: https://forum.dlang.org/post/yfybveovbknvvxmio...@forum.dlang.org and was just curious to understand it better. If I call readln() after having previously called readf(), it does not behave as expected: ```d import std.stdio, std.string; void main() { write("Please enter a number: "); double number; readf(" %s", number); write("Please enter a string: "); string input = strip(readln()); writefln!("number: %s --- string: %s")(number, input); } ``` Gives me the following: ``` Please enter a number: 1 Please enter a string: number: 1 string: ``` I know I can get this to work replacing the `strin(readln())` with `readf(" %s\n", input)`, but I also found if I just call `strip(readln())` an extra time this worked as well, but what is confusing to me is if I have multiple readf's I still only need to call readln one extra time to get it to work as expected: ```d import std.stdio, std.string; void main() { write("Please enter a number: "); double number1; readf(" %s", number1); write("Please enter a number: "); double number2; readf(" %s", number2); // Handle what should be two \n's from readf? string input = strip(readln()); // Continue as normal write("Please enter a string: "); input = strip(readln()); writefln!("number1: %s --- number2: %s --- string: %s") (number1, number2, input); } ``` And this works. ``` Please enter a number: 1 Please enter a number: 2 Please enter a string: hello number1: 1 --- number2: 2 --- string: hello ``` Could anyone help explain this to me, and also is there a better way to handle this when wanting to use a mix of readf and readln?
Re: Question regarding readf
On Monday, 22 April 2019 at 23:53:59 UTC, Ali Çehreli wrote: On 04/22/2019 03:29 PM, Andre Pany wrote: > I wonder wheter std.stdio is missing a readfln function. Which executes > readln, strips the #10#13 characters and then executes formattedRead. > Does that make sense to you? Makes sense but what we are missing is standard streaming (like C++'s overloaded << and >> operators), which Steven Schveighoffer's iopipe can be a solution for but I haven't played with it myself. Ali Issue created: https://issues.dlang.org/show_bug.cgi?id=19820 Kind regards André
Re: Question regarding readf
Le 23/04/2019 à 00:23, Adam D. Ruppe via Digitalmars-d-learn a écrit : (my personal feeling though is readf is just a pile of confusion and should almost never be used. I hate that it is introduced so early in most tutorials... I'd rather have it in an appendix for special cases only rather than like page 3.) agreed -- diniz {la vita e estranj}
Re: Question regarding readf
On 04/22/2019 03:29 PM, Andre Pany wrote: > I wonder wheter std.stdio is missing a readfln function. Which executes > readln, strips the #10#13 characters and then executes formattedRead. > Does that make sense to you? Makes sense but what we are missing is standard streaming (like C++'s overloaded << and >> operators), which Steven Schveighoffer's iopipe can be a solution for but I haven't played with it myself. Ali
Re: Question regarding readf
On Monday, 22 April 2019 at 22:08:33 UTC, Ali Çehreli wrote: On 04/22/2019 01:45 PM, Andre Pany wrote: Hi, following the example from http://ddili.org/ders/d.en/input.html, I try to read a value from console on windows (powershell and dos console). The code from the example does not work, writeln is never executed. import std; void main() { while(true) { string name; readf("%s", name); writeln(name); } } also this doesn't work: readf(" %s", name); The solution is to use readln, which regrettably comes too late in the book: http://ddili.org/ders/d.en/strings.html Ali I try to rewrite an example from another language. 4 values are read from console. While readln with strip (and in 2 cases to!int) works fine, it just not looks that good in comparison to the other language. I wonder wheter std.stdio is missing a readfln function. Which executes readln, strips the #10#13 characters and then executes formattedRead. Does that make sense to you? Kind regards Andre
Re: Question regarding readf
On Monday, 22 April 2019 at 20:45:54 UTC, Andre Pany wrote: The code from the example does not work, writeln is never executed. For "%s" with a string argument, it reads ALL of stdin into that string. This means you need to send an end-of-file indicator to the program. ctrl+z on Windows does this, and ctrl+d can on Linux (you might have to hit it twice there; it doesn't technically send end of file, but can be read as it by the program if there is no other input pending in the buffer). This is quite bizarre for new users, I agree, but it isn't technically invalid. (my personal feeling though is readf is just a pile of confusion and should almost never be used. I hate that it is introduced so early in most tutorials... I'd rather have it in an appendix for special cases only rather than like page 3.)
Re: Question regarding readf
On 04/22/2019 01:45 PM, Andre Pany wrote: Hi, following the example from http://ddili.org/ders/d.en/input.html, I try to read a value from console on windows (powershell and dos console). The code from the example does not work, writeln is never executed. import std; void main() { while(true) { string name; readf("%s", name); writeln(name); } } also this doesn't work: readf(" %s", name); The solution is to use readln, which regrettably comes too late in the book: http://ddili.org/ders/d.en/strings.html Ali
Question regarding readf
Hi, following the example from http://ddili.org/ders/d.en/input.html, I try to read a value from console on windows (powershell and dos console). The code from the example does not work, writeln is never executed. import std; void main() { while(true) { string name; readf("%s", name); writeln(name); } } also this doesn't work: readf(" %s", name); It only works while changing the line to: readf("%s\n", name); I wonder why the example from Ali is invalid. Did the behavior changed in the past? Kind regards André
Re: Catching std.conv.ConvException in readf causes a buffer overrun
On Wednesday, 27 June 2018 at 02:39:49 UTC, Shigeki Karita wrote: import std.stdio; import std.conv; void main() { int i; try { readf("%d\n", &i); // "a" } catch (ConvException e) { auto s = readln(); writeln(s); // "aa", "aaa" or SEGV ??? } } https://wandbox.org/permlink/NMYNjpOgQtfUprBQ I just want to retry reading if input was invalid. How can I do it? I found that formattedRead!"%d\n"(readln(), i) can avoid the buffer overrun why readf cannot do this? --- import std.stdio; import std.format; import std.stdio; import std.format; void main() { int i; try { formattedRead!"%d\n"(readln(), i); } catch (Exception e) { // writeln(e); auto s = readln(); writeln(s); // "" } }
Catching std.conv.ConvException in readf causes a buffer overrun
import std.stdio; import std.conv; void main() { int i; try { readf("%d\n", &i); // "a" } catch (ConvException e) { auto s = readln(); writeln(s); // "aa", "aaa" or SEGV ??? } } https://wandbox.org/permlink/NMYNjpOgQtfUprBQ I just want to retry reading if input was invalid. How can I do it?
Re: How to call readf
On Sunday, 28 May 2017 at 15:00:30 UTC, Ali Çehreli wrote: On 05/28/2017 07:55 AM, Petras wrote: > Hi, I am learning how to use readf to read integers. I follow the > example in https://dlang.org/library/std/stdio/readf.html > > The sample code use readf in following way > readf!" %d"(a); Providing the format string as a template argument and being able to pass references are both 2.074 features. > It turns out that I can compile the code using ldc2 if I change the line to > readf(" %d", &a); That's the old way that should work with 2.074 as well. Ali Thanks!
Re: How to call readf
On 05/28/2017 07:55 AM, Petras wrote: > Hi, I am learning how to use readf to read integers. I follow the > example in https://dlang.org/library/std/stdio/readf.html > > The sample code use readf in following way > readf!" %d"(a); Providing the format string as a template argument and being able to pass references are both 2.074 features. > It turns out that I can compile the code using ldc2 if I change the line to > readf(" %d", &a); That's the old way that should work with 2.074 as well. Ali
How to call readf
Hi, I am learning how to use readf to read integers. I follow the example in https://dlang.org/library/std/stdio/readf.html The sample code use readf in following way readf!" %d"(a); It works when I use dmd 2.074. However, I got compile error when I switch to ldc2 /usr/include/d/std/stdio.d(3339): Error: tuple A is used as a type b.d(8): Error: template instance std.stdio.readf!" %d" error instantiating It turns out that I can compile the code using ldc2 if I change the line to readf(" %d", &a); So my questions are 1. Should I use ampersand? I search the web and other people use ampersand. But from the doc I guess that I can also pass arguments as ref and do need to use ampersand? 2. I also tried changing the code to readf!" %d"(&a); and ldc2 gives me the same error. I search and the ! does something called template instantiation. Why it does not work here? Thanks for your help!
Re: readf interferes with readln
On Thursday, 27 April 2017 at 08:37:26 UTC, ketmar wrote: Bastiaan Veelo wrote: Hi, I am having trouble explaining the following to someone learning D. Can someone explain why readln has different behaviour when it is preceded by readf? Suppose we want to not end the program before the user presses Enter by having readln at the end of main(): ``` import std.stdio; void main() { int num; write("Give a number "); readf(" %s", num); writeln("Thanks"); readln; readln; } ``` In this example this requires twice readln. When you comment out readf, you need readln only once. Thanks! 'cause your `readf()` stops before consuming `'\n`. i.e. EOL is still in input buffer, and first `readln()` will immediately consume it. Right, of course. Thanks a lot.
Re: readf interferes with readln
Bastiaan Veelo wrote: Hi, I am having trouble explaining the following to someone learning D. Can someone explain why readln has different behaviour when it is preceded by readf? Suppose we want to not end the program before the user presses Enter by having readln at the end of main(): ``` import std.stdio; void main() { int num; write("Give a number "); readf(" %s", num); writeln("Thanks"); readln; readln; } ``` In this example this requires twice readln. When you comment out readf, you need readln only once. Thanks! 'cause your `readf()` stops before consuming `'\n`. i.e. EOL is still in input buffer, and first `readln()` will immediately consume it.
readf interferes with readln
Hi, I am having trouble explaining the following to someone learning D. Can someone explain why readln has different behaviour when it is preceded by readf? Suppose we want to not end the program before the user presses Enter by having readln at the end of main(): ``` import std.stdio; void main() { int num; write("Give a number "); readf(" %s", num); writeln("Thanks"); readln; readln; } ``` In this example this requires twice readln. When you comment out readf, you need readln only once. Thanks!
Re: basic interactive readf from stdin
On Sunday, 27 December 2015 at 02:08:05 UTC, Ali Çehreli wrote: On 12/26/2015 05:15 PM, Karthikeyan wrote: >> The answer is nine chapters later. :) (Use readln() and strip() (or >> chomp())). >> >> http://ddili.org/ders/d.en/strings.html >> >> Ali > > Many thanks Ali. The book says ctrl + D to end input. But I used two > enters to get the output. Any idea why? I guess that means that my understanding was not portable. It requires Ctrl-D on my console environment on Linux. No matter how many Enters I enter :p they become parts of the same string. Ali :) I was on zsh with gnome terminal alike on Linux Mint 15. Thanks for clearing that up.
Re: basic interactive readf from stdin
On 12/26/2015 05:15 PM, Karthikeyan wrote: >> The answer is nine chapters later. :) (Use readln() and strip() (or >> chomp())). >> >> http://ddili.org/ders/d.en/strings.html >> >> Ali > > Many thanks Ali. The book says ctrl + D to end input. But I used two > enters to get the output. Any idea why? I guess that means that my understanding was not portable. It requires Ctrl-D on my console environment on Linux. No matter how many Enters I enter :p they become parts of the same string. Ali
Re: basic interactive readf from stdin
On Sunday, 27 December 2015 at 00:20:51 UTC, Ali Çehreli wrote: On 12/26/2015 12:11 PM, karthikeyan wrote: > I read http://ddili.org/ders/d.en/input.html and inserted a space before %s > but still no use. Am I missing something here with the latest version? The answer is nine chapters later. :) (Use readln() and strip() (or chomp())). http://ddili.org/ders/d.en/strings.html Ali Many thanks Ali. The book says ctrl + D to end input. But I used two enters to get the output. Any idea why? The book was great. Thanks a lot.
Re: basic interactive readf from stdin
On Sunday, 27 December 2015 at 00:20:51 UTC, Ali Çehreli wrote: On 12/26/2015 12:11 PM, karthikeyan wrote: > I read http://ddili.org/ders/d.en/input.html and inserted a space before %s > but still no use. Am I missing something here with the latest version? The answer is nine chapters later. :) (Use readln() and strip() (or chomp())). http://ddili.org/ders/d.en/strings.html Ali Yes, thank you, strip() appears to be more useful than chomp() in this case.
Re: basic interactive readf from stdin
On 12/26/2015 12:11 PM, karthikeyan wrote: > I read http://ddili.org/ders/d.en/input.html and inserted a space before %s > but still no use. Am I missing something here with the latest version? The answer is nine chapters later. :) (Use readln() and strip() (or chomp())). http://ddili.org/ders/d.en/strings.html Ali
Re: basic interactive readf from stdin
On 12/26/2015 11:40 AM, Jay Norwood wrote: Simple VS console app in D. Reading lines to a string variable interactively. Object is to have no extra blank lines in the console output. Seems very broken for this use, requiring two extra "enter" entries before the outputs both appear. Version DMD32 D Compiler v2.069.2 import std.stdio; int main(string[] argv) { string nm; stdin.readf("%s\n",&nm); writeln("nm:",nm); stdin.readf("%s\n",&nm); writeln("nm:",nm); return 0; } io shown below 123 456 nm:123 nm:456 Reading lines with readln works in a Linux console: import std.stdio; import std.string; int main(string[] argv) { string nm; nm = readln.strip; writeln("nm:",nm); nm = readln.strip; writeln("nm:",nm); return 0; } Ali
Re: basic interactive readf from stdin
On Saturday, 26 December 2015 at 20:19:08 UTC, Adam D. Ruppe wrote: On Saturday, 26 December 2015 at 20:11:27 UTC, karthikeyan wrote: I experience the same as the OP on Linux Mint 15 with dmd2.069 and 64 bit machine. I have to press enter twice to get the output. I read http://ddili.org/ders/d.en/input.html and inserted a space before %s but still no use. Am I missing something here with the latest version? Oh, I'm sorry, it isn't buffering, it is readfing into a string here which is weird. Maybe try readln instead of readf. The use of readf into a string is demonstrated in a stdio.d unit test. I assumed it might also work with stdin. string s; auto f = File(deleteme); f.readf("%s\n", &s); assert(s == "hello", "["~s~"]"); f.readf("%s\n", &s); assert(s == "world", "["~s~"]"); = I did get this below to work with readln, although since readln didn't consume the terminator, I had to add the chomp() call. import std.stdio; import std.string; int main(string[] argv) { string nm, nm2; nm=readln('\n'); nm2 = nm.chomp(); writeln("nm:",nm2); nm=readln('\n'); nm2 = nm.chomp(); writeln("nm:",nm2); return 0; }
Re: basic interactive readf from stdin
On Saturday, 26 December 2015 at 20:38:52 UTC, tcak wrote: On Saturday, 26 December 2015 at 20:19:08 UTC, Adam D. Ruppe wrote: On Saturday, 26 December 2015 at 20:11:27 UTC, karthikeyan wrote: I experience the same as the OP on Linux Mint 15 with dmd2.069 and 64 bit machine. I have to press enter twice to get the output. I read http://ddili.org/ders/d.en/input.html and inserted a space before %s but still no use. Am I missing something here with the latest version? Oh, I'm sorry, it isn't buffering, it is readfing into a string here which is weird. Maybe try readln instead of readf. As far as I remember, in C, if I was to be putting "\n" in scanf after %s, that double entering was happening. I guess that's the same problem. Trying same code without \n in readf can fix it I guess. import std.stdio; int main(string[] argv) { string nm; stdin.readf("%s",&nm); writeln("nm:",nm); stdout.flush(); stdin.readf("%s",&nm); writeln("nm:",nm); stdout.flush(); return 0; } ok, I tried above, adding both the stdout.flush() and removing the \n from the format. It didn't write to output even after a couple of enter's. When I entered ctrl-Z, it output below. output running from command prompt 123 456 ^Z nm:123 456 nm:123 456
Re: basic interactive readf from stdin
On Saturday, 26 December 2015 at 19:52:15 UTC, Adam D. Ruppe wrote: On Saturday, 26 December 2015 at 19:40:59 UTC, Jay Norwood wrote: Simple VS console app in D. If you are running inside visual studio, you need to be aware that output will be block buffered, not line buffered, because VS pipes the output making the program think it is talking to another program instead of to an interactive console (well, because it is!) Add a stdout.flush(); after writing to force it to show immediately. I really think the read functions ought to flush output too because this is such a FAQ. (indeed, my terminal.d does flush output when you request input) It doesn't make a difference if I run in VS or from a console window. I had also already tried various forms stdout.flush(). It doesn't make a difference ... still requires two extra enters before it outputs the data. I haven't tried it in linux yet.
Re: basic interactive readf from stdin
On Saturday, 26 December 2015 at 20:19:08 UTC, Adam D. Ruppe wrote: On Saturday, 26 December 2015 at 20:11:27 UTC, karthikeyan wrote: I experience the same as the OP on Linux Mint 15 with dmd2.069 and 64 bit machine. I have to press enter twice to get the output. I read http://ddili.org/ders/d.en/input.html and inserted a space before %s but still no use. Am I missing something here with the latest version? Oh, I'm sorry, it isn't buffering, it is readfing into a string here which is weird. Maybe try readln instead of readf. As far as I remember, in C, if I was to be putting "\n" in scanf after %s, that double entering was happening. I guess that's the same problem. Trying same code without \n in readf can fix it I guess.
Re: basic interactive readf from stdin
On Saturday, 26 December 2015 at 20:11:27 UTC, karthikeyan wrote: I experience the same as the OP on Linux Mint 15 with dmd2.069 and 64 bit machine. I have to press enter twice to get the output. I read http://ddili.org/ders/d.en/input.html and inserted a space before %s but still no use. Am I missing something here with the latest version? Oh, I'm sorry, it isn't buffering, it is readfing into a string here which is weird. Maybe try readln instead of readf.
Re: basic interactive readf from stdin
On Saturday, 26 December 2015 at 19:52:15 UTC, Adam D. Ruppe wrote: On Saturday, 26 December 2015 at 19:40:59 UTC, Jay Norwood wrote: Simple VS console app in D. If you are running inside visual studio, you need to be aware that output will be block buffered, not line buffered, because VS pipes the output making the program think it is talking to another program instead of to an interactive console (well, because it is!) Add a stdout.flush(); after writing to force it to show immediately. I really think the read functions ought to flush output too because this is such a FAQ. (indeed, my terminal.d does flush output when you request input) I experience the same as the OP on Linux Mint 15 with dmd2.069 and 64 bit machine. I have to press enter twice to get the output. I read http://ddili.org/ders/d.en/input.html and inserted a space before %s but still no use. Am I missing something here with the latest version? Code import std.stdio; int main(string[] argv) { string nm; readf(" %s\n",&nm); writeln("nm:",nm); // readf(" %s\n",&nm); // writeln("nm:",nm); return 0; } Output 56 2 nm:56
Re: basic interactive readf from stdin
On Saturday, 26 December 2015 at 19:40:59 UTC, Jay Norwood wrote: Simple VS console app in D. If you are running inside visual studio, you need to be aware that output will be block buffered, not line buffered, because VS pipes the output making the program think it is talking to another program instead of to an interactive console (well, because it is!) Add a stdout.flush(); after writing to force it to show immediately. I really think the read functions ought to flush output too because this is such a FAQ. (indeed, my terminal.d does flush output when you request input)
basic interactive readf from stdin
Simple VS console app in D. Reading lines to a string variable interactively. Object is to have no extra blank lines in the console output. Seems very broken for this use, requiring two extra "enter" entries before the outputs both appear. Version DMD32 D Compiler v2.069.2 import std.stdio; int main(string[] argv) { string nm; stdin.readf("%s\n",&nm); writeln("nm:",nm); stdin.readf("%s\n",&nm); writeln("nm:",nm); return 0; } io shown below 123 456 nm:123 nm:456
Re: User input readline || readf
It also works: - import std.conv; import std.stdio; import std.string; struct Human { string name; ushort age; } void print_human_list(Human[] human_list) { foreach(human; human_list) { writeln(human.name); writeln(human.age); } writeln(); } void add_new_human(ref Human[] human_list) { write("Name: "); string name = readln.strip; write("Age: "); ushort age = readln.strip.to!ushort; Human tmp_human = {name, age}; human_list ~= tmp_human; } void main() { Human[] human_list; for(;;) { writeln("A)dd New Human."); writeln("P)rint Human List."); writeln("Q)uit."); write(": "); char choice = readln.strip.to!char; switch (choice) { case('A'): add_new_human(human_list); break; case('P'): print_human_list(human_list); break; case('Q'): return; default: continue; } } } - http://ideone.com/0cS7Y4
Re: User input readline || readf
On Thursday, 23 April 2015 at 17:18:01 UTC, kerze wrote: Hy, i'm new @ D and i come from python. Sorry for my engish, i understand good, but i write like a cow spanish. I make a little programm to add human's name and age and a function to write out alls humans in the list. Here is the source: http://dpaste.dzfl.pl/0a0da462225d The problem is, it writes instant "Name: Age:" at the standart output. I'm little confuse about readf and readline, what to use. or its the failure in write ? I hope anybody can help me, as long as anybody understand me and my problem. ;) Greetings from Swiss. Kerze I can offer, for example, such an option: - import std.conv; import std.stdio; import std.string; import std.typecons; Tuple!(string, ushort)[] humanList; void printHumanList() { foreach (e; humanList) { writeln(e[0]); writeln(e[1]); } } void addNewHuman(){ write("Age: "); ushort age = readln.strip.to!ushort; write("Name: "); string name = readln.strip; humanList ~= tuple(name, age); } void main(){ char choice; for(;;) { writeln("A)dd New Human."); writeln("P)rint Human List."); writeln("Q)uit."); write(": "); choice = readln.strip.to!char; switch (choice){ case('A'): addNewHuman; break; case('P'): printHumanList; break; case('Q'): return; default: continue; } } }
Re: User input readline || readf
Willkommen in der D Community. ;) So many Thanks @Steven and Jacques, answer's more than a only; "do this" ;)
Re: User input readline || readf
The paste is still there. readf leaves the \n from pressing enter in stdin, which gets read by the next function that's accessing it. I answered a similiar question in another thread: http://forum.dlang.org/post/jwxfaztgsyzwqpzaj...@forum.dlang.org I see two other mistakes in your code as well: 1. I'm pretty sure you want to pass print_human_list and add_new_human a reference to the human_list array. Just add "ref" before "Human[] human_list". void print_human_list(ref Human[] human_list) 2. In D there exists something called switch fallthrough. Just add a "break;" after each case and only the matching block will be executed. case('A'): add_new_human(human_list); break; Willkommen in der D Community. ;)
Re: User input readline || readf
On 4/23/15 1:17 PM, kerze wrote: The problem is, it writes instant "Name: Age:" at the standart output. readf reads the element from the stream, and NOTHING MORE, it leaves the newline on the stream. So the next readf then reads the newline as a string. You can fix this by using readf(" %s"), which means "read any whitespace, then my data". -Steve
Re: User input readline || readf
hmm the paste is away ?!? here i post my source one more time. [code] import std.stdio; import std.string; struct Human { string name; ushort age; }; void print_human_list(Human[] human_list){ foreach(human; human_list){ writeln(human.name); writeln(human.age); } writeln(""); } void add_new_human(Human[] human_list){ ushort age; // write("Name: "); // The Output is string name = strip(stdin.readln()); // Name: Age: write("Age: "); // And the Error readf(" %u", &age); // std.conv.ConvException@/usr/include/dlang/ldc/std/conv.d(1968): Human tmp_human = {name, age};// Unexpected 's' when converting from type LockingTextReader to type uint human_list ~= tmp_human; } int main(){ Human[] human_list; char choice; for(;;){ writeln("A)dd New Human."); writeln("P)rint Human List."); writeln("Q)uit."); write(": "); readf("%c", &choice); switch(choice){ case('A') : add_new_human(human_list); case('P') : print_human_list(human_list); case('Q') : return 0; default : continue; } } } [/code]
User input readline || readf
Hy, i'm new @ D and i come from python. Sorry for my engish, i understand good, but i write like a cow spanish. I make a little programm to add human's name and age and a function to write out alls humans in the list. Here is the source: http://dpaste.dzfl.pl/0a0da462225d The problem is, it writes instant "Name: Age:" at the standart output. I'm little confuse about readf and readline, what to use. or its the failure in write ? I hope anybody can help me, as long as anybody understand me and my problem. ;) Greetings from Swiss. Kerze
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 23:00:46 UTC, Ivan Kazmenko wrote: On Saturday, 21 March 2015 at 16:34:44 UTC, Dennis Ritchie wrote: And why in D copied only the first 32767 characters of the string? I'm more days couldn't understand what was going on... To me, it looks like a bug somewhere, though I don't get where exactly. Is it in bits of DigitalMars C/C++ compiler code glued into druntime? Anyway, as for Codeforces problems, you mostly need to read text input as tokens separated by spaces and/or newlines. For that, D I/O is sufficient, there is no need to use legacy C++ I/O. Usually, readf(" %s", &v) works for every scalar type of variable v (including reals and 64-bit integers) except strings, and readln() does the thing for strings. Don't forget to get rid of the newline sequence on the previous line if you mix the two. Possible leading and trailing spaces in " %s " mean skipping all whitespace before or after the token, respectively, as is the case for scanf in C/C++. As far as I remember, for reading a line of numbers separated by spaces, - auto a = readln.split.map!(to!int).array; - is a bit faster than a loop of readf filling the array, but that hardly matters in the majority of problems. You can see my submissions (http://codeforces.com/submissions/Gassa) for example. If you really feel the need for I/O better suited for the specifics of algorithmic programming contests (as Java people almost always do in their language for some reason), look at Kazuhiro Hosaka's submissions (http://codeforces.com/submissions/hos.lyric). In case you want to go even further and write your own I/O layer for that, I'll point you to a recent discussion of text I/O methods here: http://stackoverflow.com/q/28922323/1488799 (see comments and answers). Thanks.
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 23:00:46 UTC, Ivan Kazmenko wrote: To me, it looks like a bug somewhere, though I don't get where exactly. Is it in bits of DigitalMars C/C++ compiler code glued into druntime? As far as I understand, the bug is in snn.lib's scanf. snn.lib is Digital Mars's implementation of the C standard library (aka C runtime library or just C runtime). By default, some version of the C runtime is linked into every D program, so that you (and phobos and druntime) can use it. snn.lib is used for Windows x86. For other targets, other implementations of the C runtime are used (which don't have that bug).
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 16:34:44 UTC, Dennis Ritchie wrote: And why in D copied only the first 32767 characters of the string? I'm more days couldn't understand what was going on... To me, it looks like a bug somewhere, though I don't get where exactly. Is it in bits of DigitalMars C/C++ compiler code glued into druntime? Anyway, as for Codeforces problems, you mostly need to read text input as tokens separated by spaces and/or newlines. For that, D I/O is sufficient, there is no need to use legacy C++ I/O. Usually, readf(" %s", &v) works for every scalar type of variable v (including reals and 64-bit integers) except strings, and readln() does the thing for strings. Don't forget to get rid of the newline sequence on the previous line if you mix the two. Possible leading and trailing spaces in " %s " mean skipping all whitespace before or after the token, respectively, as is the case for scanf in C/C++. As far as I remember, for reading a line of numbers separated by spaces, - auto a = readln.split.map!(to!int).array; - is a bit faster than a loop of readf filling the array, but that hardly matters in the majority of problems. You can see my submissions (http://codeforces.com/submissions/Gassa) for example. If you really feel the need for I/O better suited for the specifics of algorithmic programming contests (as Java people almost always do in their language for some reason), look at Kazuhiro Hosaka's submissions (http://codeforces.com/submissions/hos.lyric). In case you want to go even further and write your own I/O layer for that, I'll point you to a recent discussion of text I/O methods here: http://stackoverflow.com/q/28922323/1488799 (see comments and answers). Ivan Kazmenko.
Re: The difference in string and char[], readf() and scanf()
On 2015-03-21 at 22:15, FG wrote: On 2015-03-21 at 21:02, Dennis Ritchie wrote: In what universe?! Which OS, compiler and architecture? Windows 8.1 x64, dmd 2.066.1: That's strange. I cannot recreate the problem on Win7 x64 with dmd 2.066.1, neither when compiled for 32- nor 64-bit. I have saved the a's to a file and use input redirect to load it, while the program is as follows: Oh, wait. I was wrong. I have the same problem. It didn't appear before because the file of A's that I used didn't have a \r\n EOL at the end. With those two bytes added it failed. It's the EOL at the end of the input word that's the problem. I tested four different inputs: aaa...aaa OK aaa...aaa\r\n FAIL aaa...aaa bbb OK aaa...aaa bbb\r\n OK
Re: The difference in string and char[], readf() and scanf()
On 2015-03-21 at 21:02, Dennis Ritchie wrote: In what universe?! Which OS, compiler and architecture? Windows 8.1 x64, dmd 2.066.1: That's strange. I cannot recreate the problem on Win7 x64 with dmd 2.066.1, neither when compiled for 32- nor 64-bit. I have saved the a's to a file and use input redirect to load it, while the program is as follows: import std.stdio; void main () { char [10] a; scanf ("%s", a.ptr); printf ("%s\n", a.ptr); } freopen("in.txt", "r", din.file); No, that approach didn't change the result. I still get 1.
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 15:05:56 UTC, Ivan Kazmenko wrote: Generate a 10-character string: - import std.range, std.stdio; void main () {'a'.repeat (10).writeln;} - Try to copy it with D scanf and printf: - import std.stdio; void main () { char [10] a; scanf ("%s", a.ptr); printf ("%s\n", a.ptr); } - Only 32767 first characters of the string are actually copied. That doesn't happen on linux, but I could reproduce it in wine. Seems to be a bug in the C runtime (snn.lib). I filed an issue: https://issues.dlang.org/show_bug.cgi?id=14315
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 19:09:59 UTC, FG wrote: In what universe?! Which OS, compiler and architecture? On Saturday, 21 March 2015 at 19:09:59 UTC, FG wrote: In what universe?! Which OS, compiler and architecture? Windows 8.1 x64, dmd 2.066.1: import std.range, std.stdio; void main () { stdout = File("in.txt", "w"); 'a'.repeat(10).writeln; } import std.stdio; import std.cstream; void main () { freopen("in.txt", "r", din.file); freopen("out.txt", "w", dout.file); char[10] a; scanf("%s", a.ptr); int lenA; foreach (i; 0 .. 10) { if (a[i] == 'a') ++lenA; printf("%c", a[i]); } printf("\n%d\n", lenA); // 32767 } By the way, in Ubuntu 14.04 LTS (dmd 2.066.1) everything works fine: #!/usr/bin/rdmd import std.range, std.stdio; void main () { stdout = File("in.txt", "w"); 'a'.repeat(10).writeln; } #!/usr/bin/rdmd import std.stdio; import std.cstream; void main () { freopen("in.txt", "r", din.file); freopen("out.txt", "w", dout.file); char[10] a; scanf("%s", a.ptr); int lenA; foreach (i; 0 .. 10) { if (a[i] == 'a') ++lenA; printf("%c", a[i]); } printf("\n%d\n", lenA); // 10 }
Re: The difference in string and char[], readf() and scanf()
On 2015-03-21 at 16:05, Ivan Kazmenko wrote: Generate a 10-character string [...] Try to copy it with D scanf and printf: - import std.stdio; void main () { char [10] a; scanf ("%s", a.ptr); printf ("%s\n", a.ptr); } - Only 32767 first characters of the string are actually copied. In what universe?! Which OS, compiler and architecture?
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 15:05:56 UTC, Ivan Kazmenko wrote: On Saturday, 21 March 2015 at 14:31:20 UTC, Dennis Ritchie wrote: In C++ it is fully working: char s[25], t[25]; scanf("%s%s", s, t); Indeed. And why in D copied only the first 32767 characters of the string? I'm more days couldn't understand what was going on... Generate a 10-character string: - import std.range, std.stdio; void main () {'a'.repeat (10).writeln;} - Try to copy it with D scanf and printf: - import std.stdio; void main () { char [10] a; scanf ("%s", a.ptr); printf ("%s\n", a.ptr); } - Only 32767 first characters of the string are actually copied. Thank you very much.
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 14:31:20 UTC, Dennis Ritchie wrote: In C++ it is fully working: char s[25], t[25]; scanf("%s%s", s, t); Indeed. Generate a 10-character string: - import std.range, std.stdio; void main () {'a'.repeat (10).writeln;} - Try to copy it with D scanf and printf: - import std.stdio; void main () { char [10] a; scanf ("%s", a.ptr); printf ("%s\n", a.ptr); } - Only 32767 first characters of the string are actually copied.
Re: The difference in string and char[], readf() and scanf()
In C++ it is fully working: char s[25], t[25]; scanf("%s%s", s, t); http://codeforces.com/contest/527/submission/10376381?locale=en
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 12:08:05 UTC, anonymous wrote: Please go into more detail about how it doesn't work. Task: http://codeforces.com/contest/527/problem/B?locale=en It works: char[200010] s, t; s = readln.strip; t = readln.strip; http://codeforces.com/contest/527/submission/10377392?locale=en It doesn't always work: char[200010] s, t; scanf("%s%s", s.ptr, t.ptr); http://codeforces.com/contest/527/submission/10376852?locale=en P.S. I can't copy test №23 completely.
Re: The difference in string and char[], readf() and scanf()
On Saturday, 21 March 2015 at 08:37:59 UTC, Dennis Ritchie wrote: Tell me, please, why this code works correctly always: [...] And this code works correctly is not always: import std.stdio; readf("%s\n", &n); char[200010] s, t; scanf("%s%s", s.ptr, t.ptr); Please go into more detail about how it doesn't work.
The difference in string and char[], readf() and scanf()
Hi, Tell me, please, why this code works correctly always: import std.stdio; int n; readf("%s\n", &n); string s, t; readf("%s\n%s\n", &s, &t); And this code works correctly is not always: import std.stdio; readf("%s\n", &n); char[200010] s, t; scanf("%s%s", s.ptr, t.ptr); Data is entered only in this format (n - the length of strings str1 and str2, 1 <= n <= 20; only lowercase letters): n str1 str2 For example: 5 cater doger
Re: A specifier readf() for BigInt
On Tuesday, 17 February 2015 at 07:20:19 UTC, Ivan Kazmenko wrote: The readf function does not seem to support reading BigInts directly. However, you can read a string and construct a BigInt from it, either by std.conv.to or directly invoking the constructor: import std.algorithm, std.bigint, std.conv, std.stdio, std.string; void main () { // read a line of space-separated BigInts and print their sum: readln.split.map !(to!BigInt).sum.writeln; // read a line containing one BigInt and print it squared: auto s = BigInt (readln.strip); writeln (s ^^ 2); } Thanks.
Re: A specifier readf() for BigInt
On Monday, 16 February 2015 at 19:52:20 UTC, Dennis Ritchie wrote: Hi. And how to read Data from the input stream? import std.stdio; import std.bigint; void main() { BigInt n; readf(" %?", &n); writeln(n); } The readf function does not seem to support reading BigInts directly. However, you can read a string and construct a BigInt from it, either by std.conv.to or directly invoking the constructor: import std.algorithm, std.bigint, std.conv, std.stdio, std.string; void main () { // read a line of space-separated BigInts and print their sum: readln.split.map !(to!BigInt).sum.writeln; // read a line containing one BigInt and print it squared: auto s = BigInt (readln.strip); writeln (s ^^ 2); }
A specifier readf() for BigInt
Hi. And how to read Data from the input stream? import std.stdio; import std.bigint; void main() { BigInt n; readf(" %?", &n); writeln(n); }
Re: Input error with readf()
On Friday, 30 January 2015 at 15:03:55 UTC, Ali Çehreli wrote: Not the best error message... Saying '5' is unexpected for 'int' is confusing, right? Unfortunately, I can't come up with a good explanation for that error message in the book. :) Maybe just remove the section with the 'incorrect' syntax? The reader will have to take it as read that " %s" is the correct form :D
Re: Input error with readf()
On 01/30/2015 04:49 AM, Paul wrote: > If I run the following example program from the 'Programming in > D' book, the input doesn't 'get stuck' as stated in the book but > instead produces the error message given. Have things changed > since that part of the book was written or is it some other > issue? Apparently, things did change since then. I will change the text accordingly. I would like to add you to the acknowledgments section if you email your full name to acehr...@yahoo.com. Thank you... > The version that uses " %s" in the call to readf works as > expected. > > > import std.stdio; > > void main(){ > > write("How many students are there? "); > int studentCount; > readf("%s", &studentCount); > write("How many teachers are there? "); > int teacherCount; > readf("%s", &teacherCount); > > writeln("Got it: There are ", studentCount, " students", > " and ", teacherCount, " teachers."); > } > > How many students are there? 67 > How many teachers are there? 5 > std.conv.ConvException@/usr/include/dmd/phobos/std/conv.d(1968): > Unexpected '5' when converting from type LockingTextReader to > type int > ... Not the best error message... Saying '5' is unexpected for 'int' is confusing, right? Unfortunately, I can't come up with a good explanation for that error message in the book. :) Ali
Input error with readf()
If I run the following example program from the 'Programming in D' book, the input doesn't 'get stuck' as stated in the book but instead produces the error message given. Have things changed since that part of the book was written or is it some other issue? The version that uses " %s" in the call to readf works as expected. import std.stdio; void main(){ write("How many students are there? "); int studentCount; readf("%s", &studentCount); write("How many teachers are there? "); int teacherCount; readf("%s", &teacherCount); writeln("Got it: There are ", studentCount, " students", " and ", teacherCount, " teachers."); } How many students are there? 67 How many teachers are there? 5 std.conv.ConvException@/usr/include/dmd/phobos/std/conv.d(1968): Unexpected '5' when converting from type LockingTextReader to type int ...
Re: Reading unicode string with readf ("%s")
On Tuesday, 4 November 2014 at 18:09:48 UTC, Ivan Kazmenko wrote: On Monday, 3 November 2014 at 20:10:02 UTC, Gary Willoughby wrote: On Monday, 3 November 2014 at 19:47:17 UTC, Ivan Kazmenko wrote: So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too. Maybe something like this: import std.stdio; import std.array; import std.conv; string text = stdin .byLine(KeepTerminator.yes) .join() .to!(string); And thanks for a short alternative! At first glance, looks like it sacrifices a bit of efficiency on the way: the "remove-line-breaks, then add-line-breaks" path looks redundant. Still, it does not store intermediate splitted representation, so the inefficiency is in fact not catastrophic, right? And sorry, I didn't read that correctly. Using byLine with KeepTerminator.yes and join with nothing, it does not alter line breaks at all. So, the efficiency of this is entirely up to whether optimizer is able to detect that the break/join sequence is a operation.
Re: Reading unicode string with readf ("%s")
On Tuesday, 4 November 2014 at 13:01:48 UTC, anonymous wrote: On Monday, 3 November 2014 at 19:37:20 UTC, Ivan Kazmenko wrote: Hi! The following code does not correctly handle Unicode strings. - import std.stdio; void main () { string s; readf ("%s", &s); write (s); } - Example input ("Test." in cyrillic): - Тест. - (hex: D0 A2 D0 B5 D1 81 D1 82 2E 0D 0A) Example output: - ТеÑÑ. - (hex: C3 90 C2 A2 C3 90 C2 B5 C3 91 C2 81 C3 91 C2 82 2E 0D 0A) Here, the input bytes are handled separately: D0 -> C3 90, A2 -> C2 A2, etc. On the bright side, reading the file with readln works properly. Is this an expected shortcoming of "%s"-reading a string? No. Could it be made to work somehow? Yes. std.stdio.LockingTextReader is to blame: void main() { import std.stdio; auto ltr = LockingTextReader(std.stdio.stdin); write(ltr); } $ echo Тест | rdmd test.d ТеÑÑ LockingTextReader has a dchar front. But it doesn't do any decoding. The dchar front is really a char front. Is it worth a bug report? Yes. Ivan Kazmenko. You nailed it! Reported the bug in original form: https://issues.dlang.org/show_bug.cgi?id=13686 Perhaps your reduction would be useful.
Re: Reading unicode string with readf ("%s")
On Tuesday, 4 November 2014 at 11:46:24 UTC, Kagamin wrote: https://issues.dlang.org/show_bug.cgi?id=12990 this? Similar, but not quite that. Bugs 12990 and 1448 (linked from there) seem to have Windows console as an important part of the process. For me, the example does not work even with files, either redirected via "test.exe two.txt" or using File structs inside D program. Still, thank you for the link!
Re: Reading unicode string with readf ("%s")
On Monday, 3 November 2014 at 20:10:02 UTC, Gary Willoughby wrote: On Monday, 3 November 2014 at 19:47:17 UTC, Ivan Kazmenko wrote: So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too. Maybe something like this: import std.stdio; import std.array; import std.conv; string text = stdin .byLine(KeepTerminator.yes) .join() .to!(string); And thanks for a short alternative! At first glance, looks like it sacrifices a bit of efficiency on the way: the "remove-line-breaks, then add-line-breaks" path looks redundant. Still, it does not store intermediate splitted representation, so the inefficiency is in fact not catastrophic, right?
Re: Reading unicode string with readf ("%s")
On Monday, 3 November 2014 at 20:03:03 UTC, Ali Çehreli wrote: On 11/03/2014 11:47 AM, Ivan Kazmenko wrote: On Monday, 3 November 2014 at 19:37:20 UTC, Ivan Kazmenko wrote: readf ("%s", &s); Worth noting: this reads to end-of-file (not end-of-line or whitespace), and reading the whole file into a string was what I indeed expected it to do. So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too. I don't know the answer to the Unicode issue with readf but you can read the file by chunks: import std.stdio; import std.array; import std.exception; string readAll(File file) { char[666] buffer; char[] contents; char[] piece; do { piece = file.rawRead(buffer); contents ~= piece; } while (!piece.empty); return assumeUnique(contents); } void main () { string s = stdin.readAll(); write (s); } Ali Thank you for suggesting an alternative! Looks like it would be an efficient one, too. I believe it can be made a bit more efficient if using an appender, right? Still, that's a lot of code for a minute scripting task, albeit one has to write the readAll function only once.
Re: Reading unicode string with readf ("%s")
On Monday, 3 November 2014 at 19:37:20 UTC, Ivan Kazmenko wrote: Hi! The following code does not correctly handle Unicode strings. - import std.stdio; void main () { string s; readf ("%s", &s); write (s); } - Example input ("Test." in cyrillic): - Тест. - (hex: D0 A2 D0 B5 D1 81 D1 82 2E 0D 0A) Example output: - ТеÑÑ. - (hex: C3 90 C2 A2 C3 90 C2 B5 C3 91 C2 81 C3 91 C2 82 2E 0D 0A) Here, the input bytes are handled separately: D0 -> C3 90, A2 -> C2 A2, etc. On the bright side, reading the file with readln works properly. Is this an expected shortcoming of "%s"-reading a string? No. Could it be made to work somehow? Yes. std.stdio.LockingTextReader is to blame: void main() { import std.stdio; auto ltr = LockingTextReader(std.stdio.stdin); write(ltr); } $ echo Тест | rdmd test.d ТеÑÑ LockingTextReader has a dchar front. But it doesn't do any decoding. The dchar front is really a char front. Is it worth a bug report? Yes. Ivan Kazmenko.
Re: Reading unicode string with readf ("%s")
https://issues.dlang.org/show_bug.cgi?id=12990 this?
Re: Reading unicode string with readf ("%s")
On Monday, 3 November 2014 at 19:47:17 UTC, Ivan Kazmenko wrote: So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too. Maybe something like this: import std.stdio; import std.array; import std.conv; string text = stdin .byLine(KeepTerminator.yes) .join() .to!(string);
Re: Reading unicode string with readf ("%s")
On 11/03/2014 11:47 AM, Ivan Kazmenko wrote: On Monday, 3 November 2014 at 19:37:20 UTC, Ivan Kazmenko wrote: readf ("%s", &s); Worth noting: this reads to end-of-file (not end-of-line or whitespace), and reading the whole file into a string was what I indeed expected it to do. So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too. I don't know the answer to the Unicode issue with readf but you can read the file by chunks: import std.stdio; import std.array; import std.exception; string readAll(File file) { char[666] buffer; char[] contents; char[] piece; do { piece = file.rawRead(buffer); contents ~= piece; } while (!piece.empty); return assumeUnique(contents); } void main () { string s = stdin.readAll(); write (s); } Ali
Re: Reading unicode string with readf ("%s")
On Monday, 3 November 2014 at 19:37:20 UTC, Ivan Kazmenko wrote: readf ("%s", &s); Worth noting: this reads to end-of-file (not end-of-line or whitespace), and reading the whole file into a string was what I indeed expected it to do. So, if there is an idiomatic way to read the whole file into a string which is Unicode-compatible, it would be great to learn that, too.
Reading unicode string with readf ("%s")
Hi! The following code does not correctly handle Unicode strings. - import std.stdio; void main () { string s; readf ("%s", &s); write (s); } - Example input ("Test." in cyrillic): - Тест. - (hex: D0 A2 D0 B5 D1 81 D1 82 2E 0D 0A) Example output: - ТеÑÑ. - (hex: C3 90 C2 A2 C3 90 C2 B5 C3 91 C2 81 C3 91 C2 82 2E 0D 0A) Here, the input bytes are handled separately: D0 -> C3 90, A2 -> C2 A2, etc. On the bright side, reading the file with readln works properly. Is this an expected shortcoming of "%s"-reading a string? Could it be made to work somehow? Is it worth a bug report? Ivan Kazmenko.
Re: Need som assistense with readf();
Just insert spaces before the format specifiers: import std.stdio; int main(){ long number, number2; write("Enter an integer: "); readf(" %d", &number); write("another no"); readf(" %d", &number2); writeln(number, ' ', number2); return 0; } Ali Thanks very much, that got it sorted,
Re: Need som assistense with readf();
On 07/07/2012 03:35 PM, Mr. P-teo wrote: > Basically whenever i use readf(); to gather console input it wont run > the program if there is code afterwards. readf() does not automatically consume the end-of-line character. > That works fine, but if i try and imput 2 numbers to seperate variables > it doesn't work. > > > import std.stdio; > > int main(){ > long number, number2; > write("Enter an integer: "); > readf("%d", &number); A space character in the format string reads and ignores any number of whitespace at that position. > write("another no"; > readf("%d", &number2); > return 0; Just insert spaces before the format specifiers: import std.stdio; int main(){ long number, number2; write("Enter an integer: "); readf(" %d", &number); write("another no"); readf(" %d", &number2); writeln(number, ' ', number2); return 0; } Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
Need som assistense with readf();
So iv just been getting into D programming, im liking it alot so far but i have come across one issue that i am unable to find a solution for. Basically whenever i use readf(); to gather console input it wont run the program if there is code afterwards. Here is an example: import std.stdio; int main(){ long number, number2; write("Enter an integer: "); readf("%d", &number); return 0; } That works fine, but if i try and imput 2 numbers to seperate variables it doesn't work. import std.stdio; int main(){ long number, number2; write("Enter an integer: "); readf("%d", &number); write("another no"; readf("%d", &number2); return 0; } can anyone help me.
Re: readf with strings
On 06/23/2011 02:27 AM, Dainius (GreatEmerald) wrote: I have a related enhancement request since lot of time: http://d.puremagic.com/issues/show_bug.cgi?id=4716 Bye, bearophile That's exactly what I'd like to see. Voted. After all, D is created with practicality in mind, and doing all that parsing is the opposite of what it's trying to achieve. The goal here is to have semantics for "Read an int from STDIN." I think the difficulty here is this really *should* be "Read a T from a stream." In C++, we have the stream operators ">>" and "<<". I really really really really miss these. I would love to have my stream operators back (and then implement the operators for classes and structs.) I think that "a = stdin.type_read!int();" or "std.type_read!int(&a);" would go a long way in getting there, as long as we could extend the template. I don't like the way python takes input from STDIN with raw_input() and input(). I'm not opposed to having a language support those semantics, but I would rather have a generic stream reader that does the conversion to a type for me that allows me to extend the conversion to include my own types.
Re: readf with strings
> I have a related enhancement request since lot of time: > http://d.puremagic.com/issues/show_bug.cgi?id=4716 > > Bye, > bearophile > That's exactly what I'd like to see. Voted. After all, D is created with practicality in mind, and doing all that parsing is the opposite of what it's trying to achieve.
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: 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: 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...