digitalmars.D - reading formatted strings: readf("%s", &stringvar)
- Tyro[17] (54/54) Mar 25 2012 I am trying to figure out the cause of my problem in the
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (24/71) Mar 25 2012 I am not sure about the cntrl-d|ctrl-z part though. Since it terminates
- Tyro[17] (18/65) Mar 26 2012 You can achieve the same with:
- Andrei Alexandrescu (12/23) Mar 26 2012 I made the decision for the current behavior while implementing readf.
- Tyro[17] (6/37) Mar 26 2012 Couldn't the state of stdin be checked upon entrance into readf
- Andrei Alexandrescu (6/10) Mar 26 2012 I don't think this is a pitfall. Essentially you don't have a definition...
- Tyro[17] (46/57) Mar 27 2012 But this does:
- Andrei Alexandrescu (12/30) Mar 27 2012 [snip]
- Tyro[17] (11/46) Mar 27 2012 Point taken.
- Matt Peterson (6/41) Mar 27 2012 GDB handles Ctrl-D differently. It doesn't close the input on the
- H. S. Teoh (12/26) Mar 27 2012 [...]
- Matt Peterson (2/37) Mar 27 2012 Ah, nice to know. Thanks.
- Andrei Alexandrescu (4/8) Mar 27 2012 A variety of other programs handle Ctrl-D differently (emacs, vi, etc).
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (31/72) Mar 26 2012 Ah! That's one of the problems. stdin has no idea whether there are more...
- Tyro[17] (20/65) Mar 26 2012 Actually the problem is right here:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (16/33) Mar 26 2012 That doesn't fit the way standard input and output streams work. These
- Tyro[17] (5/42) Mar 27 2012 Thanks for that explanation. I am only now understanding the
- Tyro[17] (18/65) Mar 26 2012 You can achieve the same with:
I am trying to figure out the cause of my problem in the following post: http://forum.dlang.org/thread/qfbugjkrerfboqhvjttw forum.dlang.org and encountered something peculiar about reading strings. Whenever a distinct terminator is indicated in the input format (ex. " %s ", being the terminator), readf() leaves the terminator on the input buffer after reading the data. If no terminator is specified the only way to indicate end of input is to use ctrl-d (ctrl-z on windows), however that causes the eof indicator to be set to true and the stream is marked as empty for all future attempts to access stdin. void main(string[] args) { string s1; double d; string s2; writeln("Enter a terminated string (multiline ok):"); readf(" %s ", &s1); auto arr = s1.split(); if (!stdin.eof()) { writeln("The stream is not empty."); } else { writeln("The stream is empty."); } writeln("Enter another string (terminated with cntrl-d|ctrl-z):"); readf(" %s", &s2); // No matter how many read attempts // are made after this point, none of them will work. // Insert \n after %s to see difference. writeln("Enter a decimal value:"); readf(" %s", &d); //readf(" %s", &d); //readf(" %s", &d); //readf(" %s", &d); //readf(" %s", &d); if (!stdin.eof()) { writeln("The stream is not empty."); } else { writeln("The stream is empty."); } writeln("d = ", d); writeln("arr = ", arr); writeln("s = ", s2); } Is there no way to indicate eof without marking the stream (buffer?) as empty for all future uses after encountering cntrl-d/cntrl-z during string input? I would expect to be able to terminate string input with cntrl-d/cntrl-z without rendering the input stream inaccessible. Thanks, Andrew
Mar 25 2012
On 03/25/2012 06:00 AM, Tyro[17] wrote:I am trying to figure out the cause of my problem in the following post: http://forum.dlang.org/thread/qfbugjkrerfboqhvjttw forum.dlang.orgSorry that I missed your question there. :(and encountered something peculiar about reading strings. Whenever a distinct terminator is indicated in the input format (ex. " %s ", being the terminator), readf() leaves the terminator on the input buffer after reading the data. If no terminator is specified the only way to indicate end of input is to use ctrl-d (ctrl-z on windows), however that causes the eof indicator to be set to true and the stream is marked as empty for all future attempts to access stdin. void main(string[] args) { string s1; double d; string s2; writeln("Enter a terminated string (multiline ok):"); readf(" %s ", &s1); auto arr = s1.split(); if (!stdin.eof()) { writeln("The stream is not empty."); } else { writeln("The stream is empty."); } writeln("Enter another string (terminated with cntrl-d|ctrl-z):");I am not sure about the cntrl-d|ctrl-z part though. Since it terminates the input, the program should not be able to read any more characters.readf(" %s", &s2); // No matter how many read attemptsI advise reading string by readln(). You can call chomp() to get rid of whitespace around it: while (s2.length == 0) { s2 = chomp(readln()); } This has been my understanding of the matter: [1] <quote> There are surprises even when reading strings from the console. Being character arrays, strings can contain control characters like '\n' as well. When reading strings from the input, the control character that corresponds to the Enter key that is pressed at the end of console input becomes a part of the string as well. Further, because there is no way to tell readf() how many characters to read, it continues to read until the end of the entire input. For these reasons, readf() does not work as intended when reading strings: </quote>// are made after this point, none of them will work. // Insert \n after %s to see difference. writeln("Enter a decimal value:"); readf(" %s", &d); //readf(" %s", &d); //readf(" %s", &d); //readf(" %s", &d); //readf(" %s", &d); if (!stdin.eof()) { writeln("The stream is not empty."); } else { writeln("The stream is empty."); } writeln("d = ", d); writeln("arr = ", arr); writeln("s = ", s2); } Is there no way to indicate eof without marking the stream (buffer?) as empty for all future uses after encountering cntrl-d/cntrl-z during string input? I would expect to be able to terminate string input with cntrl-d/cntrl-z without rendering the input stream inaccessible. Thanks, AndrewWith the change above (and assuming that we don't end the stream), the rest of the reads succeed for me. Ali [1] http://ddili.org/ders/d.en/strings.html
Mar 25 2012
First of all thank your very much for your assistance. On Sunday, 25 March 2012 at 15:04:30 UTC, Ali Çehreli wrote:On 03/25/2012 06:00 AM, Tyro[17] wrote:You can achieve the same with: readf(" %s\n", &s2); My goal however, is not to read one line of information. Rather, it is to read multiple lines of information from standard input. I get close to being able to do so if i don't including "\n" as a part of my format string or if I changing your suggestion to while (!stdin.eol()) { s2 = chomp(readln()); } but again I run into the predicament was before, a need to close the the stream with Ctrl-D/Ctrl-Z. AndrewI am trying to figure out the cause of my problem in thefollowing post:http://forum.dlang.org/thread/qfbugjkrerfboqhvjttw forum.dlang.org Sorry that I missed your question there. :(and encountered something peculiar about reading strings.Whenever adistinct terminator is indicated in the input format (ex. "%s ",being the terminator), readf() leaves the terminator on theinput bufferafter reading the data. If no terminator is specified theonly way toindicate end of input is to use ctrl-d (ctrl-z on windows),however thatcauses the eof indicator to be set to true and the stream ismarked asempty for all future attempts to access stdin. void main(string[] args) { string s1; double d; string s2; writeln("Enter a terminated string (multiline ok):"); readf(" %s ", &s1); auto arr = s1.split(); if (!stdin.eof()) { writeln("The stream is not empty."); } else { writeln("The stream is empty."); } writeln("Enter another string (terminated withcntrl-d|ctrl-z):"); I am not sure about the cntrl-d|ctrl-z part though. Since it terminates the input, the program should not be able to read any more characters.readf(" %s", &s2); // No matter how many read attemptsI advise reading string by readln(). You can call chomp() to get rid of whitespace around it: while (s2.length == 0) { s2 = chomp(readln()); }
Mar 26 2012
On 3/26/12 5:55 AM, Tyro[17] wrote:You can achieve the same with: readf(" %s\n", &s2); My goal however, is not to read one line of information. Rather, it is to read multiple lines of information from standard input. I get close to being able to do so if i don't including "\n" as a part of my format string or if I changing your suggestion to while (!stdin.eol()) { s2 = chomp(readln()); } but again I run into the predicament was before, a need to close the the stream with Ctrl-D/Ctrl-Z.I made the decision for the current behavior while implementing readf. Basically I tried to avoid what I think was a mistake of scanf, i.e. that of stopping string reading at the first whitespace character, which is fairly useless. Over the years scanf was improved with %[...] which allows reading strings with any characters in a set. Anyway, if I understand correctly, there's no way to achieve what you want unless you read character-by-character and define your own control character. There's no out-of-band character that means "end of this input, but not that of the file". Andrei
Mar 26 2012
On Monday, 26 March 2012 at 14:41:41 UTC, Andrei Alexandrescu wrote:On 3/26/12 5:55 AM, Tyro[17] wrote:Couldn't the state of stdin be checked upon entrance into readf and reopened if it is already closed? Wouldn't that accomplish the desired effect while avoiding the pitfalls of scanf?You can achieve the same with: readf(" %s\n", &s2); My goal however, is not to read one line of information. Rather, it is to read multiple lines of information from standard input. I get close to being able to do so if i don't including "\n" as a part of my format string or if I changing your suggestion to while (!stdin.eol()) { s2 = chomp(readln()); } but again I run into the predicament was before, a need to close the the stream with Ctrl-D/Ctrl-Z.I made the decision for the current behavior while implementing readf. Basically I tried to avoid what I think was a mistake of scanf, i.e. that of stopping string reading at the first whitespace character, which is fairly useless.Over the years scanf was improved with %[...] which allows reading strings with any characters in a set. Anyway, if I understand correctly, there's no way to achieve what you want unless you read character-by-character and define your own control character. There's no out-of-band character that means "end of this input, but not that of the file". Andrei
Mar 26 2012
On 3/26/12 2:52 PM, Tyro[17] wrote:Couldn't the state of stdin be checked upon entrance into readf and reopened if it is already closed?That won't work.Wouldn't that accomplish the desired effect while avoiding the pitfalls of scanf?I don't think this is a pitfall. Essentially you don't have a definition of what constitutes a chunk of input. Once you get that define, you should be able to express it more or less easily. Andrei
Mar 26 2012
On Tuesday, 27 March 2012 at 00:05:51 UTC, Andrei Alexandrescu wrote:On 3/26/12 2:52 PM, Tyro[17] wrote:But this does: import std.stdio, std.array; extern(C) // As defined for MAC OS X Lion { immutable TCSANOW = 0; immutable NCCS = 20; immutable VEOF = 0; /* ICANON */ int tcgetattr(int fd, termios *termios_p); int tcsetattr(int fd, int actions, termios *termios_p); alias ulong tcflag_t; alias ubyte cc_t; alias ulong speed_t; struct termios { tcflag_t c_iflag; /* input flags */ tcflag_t c_oflag; /* output flags */ tcflag_t c_cflag; /* control flags */ tcflag_t c_lflag; /* local flags */ cc_t c_cc[NCCS]; /* control chars */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ } } void main(string[] args) { termios oldT; tcgetattr(0, &oldT); auto newT = oldT; newT.c_cc[VEOF] = 3; // temporary reassignment of EOF indicator. tcsetattr(0,TCSANOW,&newT); string s1; writeln("Enter Ctrl-D terminated string (multiline ok):"); readf(" %s\x04", &s1); tcsetattr(0,TCSANOW,&oldT); auto arr = s1.split(); writeln(arr); int data; readf(" %s", &data); writeln(i); } Could that technique be used to implement readf for stdin?Couldn't the state of stdin be checked upon entrance into readf and reopened if it is already closed?That won't work.I'm of the opinion that Ctrl-D defines the boundary of that chunk of input. We simply have to prevent it from closing the stream when working with stdin.Wouldn't that accomplish the desired effect while avoiding the pitfalls of scanf?I don't think this is a pitfall. Essentially you don't have a definition of what constitutes a chunk of input. Once you get that define, you should be able to express it more or less easily.Andrei
Mar 27 2012
On 3/27/12 6:54 AM, Tyro[17] wrote:On Tuesday, 27 March 2012 at 00:05:51 UTC, Andrei Alexandrescu wrote:[snip] Very interesting! But then what if people press Ctrl-C? That would end the input instead of ending the program.On 3/26/12 2:52 PM, Tyro[17] wrote:But this does:Couldn't the state of stdin be checked upon entrance into readf and reopened if it is already closed?That won't work.Could that technique be used to implement readf for stdin?I don't think we should pursue this path.You're in a sparse minority at best. Every Unix application out there uses Ctrl-D for end-of-console-input, and your users would be surprised by your exotic use of it. Why not pick any other character for end of chunk - double newline, Ctrl-S, pretty much anything but Ctrl-D? It's a waste of your time to fight a long-established standard. AndreiI'm of the opinion that Ctrl-D defines the boundary of that chunk of input. We simply have to prevent it from closing the stream when working with stdin.Wouldn't that accomplish the desired effect while avoiding the pitfalls of scanf?I don't think this is a pitfall. Essentially you don't have a definition of what constitutes a chunk of input. Once you get that define, you should be able to express it more or less easily.
Mar 27 2012
On Tuesday, 27 March 2012 at 15:14:07 UTC, Andrei Alexandrescu wrote:On 3/27/12 6:54 AM, Tyro[17] wrote:Point taken.On Tuesday, 27 March 2012 at 00:05:51 UTC, Andrei Alexandrescu wrote:[snip] Very interesting! But then what if people press Ctrl-C? That would end the input instead of ending the program.On 3/26/12 2:52 PM, Tyro[17] wrote:But this does:Couldn't the state of stdin be checked upon entrance into readf and reopened if it is already closed?That won't work.Could that technique be used to implement readf for stdin?I don't think we should pursue this path.You're in a sparse minority at best. Every Unix application out there uses Ctrl-D for end-of-console-input, and your users would be surprised by your exotic use of it.I'm of the opinion that Ctrl-D defines the boundary of that chunk of input. We simply have to prevent it from closing the stream when working with stdin.Wouldn't that accomplish the desired effect while avoiding the pitfalls of scanf?I don't think this is a pitfall. Essentially you don't have a definition of what constitutes a chunk of input. Once you get that define, you should be able to express it more or less easily.Why not pick any other character for end of chunk - double newline, Ctrl-S, pretty much anything but Ctrl-D? It's a waste of your time to fight a long-established standard.Thanks for the clarification. That's me just not knowing. I've settled on Ctrl-X (\x018) because i have access to it without doing anything special as opposed to Ctrl-S and no operating system (as far as I know) uses it as a Command line shortcut. Thanks for keeping the conversation going so I could find a solution. Now, is it too much it the standard terminator for string input from stdin?AndreiAndrew
Mar 27 2012
On Tuesday, 27 March 2012 at 15:14:07 UTC, Andrei Alexandrescu wrote:On 3/27/12 6:54 AM, Tyro[17] wrote:GDB handles Ctrl-D differently. It doesn't close the input on the first one, it waits for the second one and then exits. After the first one it acts like you typed 'quit', which asks you if you really want to quit when there's a program still running.On Tuesday, 27 March 2012 at 00:05:51 UTC, Andrei Alexandrescu wrote:[snip] Very interesting! But then what if people press Ctrl-C? That would end the input instead of ending the program.On 3/26/12 2:52 PM, Tyro[17] wrote:But this does:Couldn't the state of stdin be checked upon entrance into readf and reopened if it is already closed?That won't work.Could that technique be used to implement readf for stdin?I don't think we should pursue this path.You're in a sparse minority at best. Every Unix application out there uses Ctrl-D for end-of-console-input, and your users would be surprised by your exotic use of it. Why not pick any other character for end of chunk - double newline, Ctrl-S, pretty much anything but Ctrl-D? It's a waste of your time to fight a long-established standard. AndreiI'm of the opinion that Ctrl-D defines the boundary of that chunk of input. We simply have to prevent it from closing the stream when working with stdin.Wouldn't that accomplish the desired effect while avoiding the pitfalls of scanf?I don't think this is a pitfall. Essentially you don't have a definition of what constitutes a chunk of input. Once you get that define, you should be able to express it more or less easily.
Mar 27 2012
On Tue, Mar 27, 2012 at 08:56:56PM +0200, Matt Peterson wrote:On Tuesday, 27 March 2012 at 15:14:07 UTC, Andrei Alexandrescu wrote:[...][...]You're in a sparse minority at best. Every Unix application out there uses Ctrl-D for end-of-console-input, and your users would be surprised by your exotic use of it. Why not pick any other character for end of chunk - double newline, Ctrl-S, pretty much anything but Ctrl-D? It's a waste of your time to fight a long-established standard.GDB handles Ctrl-D differently. It doesn't close the input on the first one, it waits for the second one and then exits. After the first one it acts like you typed 'quit', which asks you if you really want to quit when there's a program still running.That's because gdb uses libreadline (or something along those lines) with cbreak, so it can intercept control characters without them getting interpreted by the terminal. This requires manual control of terminal functions, which is something outside the scope of readf(). (You'd be better off writing your own terminal handling from scratch, if that's what you want.) T -- This is a tpyo.
Mar 27 2012
On Tuesday, 27 March 2012 at 19:05:19 UTC, H. S. Teoh wrote:On Tue, Mar 27, 2012 at 08:56:56PM +0200, Matt Peterson wrote:Ah, nice to know. Thanks.On Tuesday, 27 March 2012 at 15:14:07 UTC, Andrei Alexandrescu wrote:[...][...]You're in a sparse minority at best. Every Unix application out there uses Ctrl-D for end-of-console-input, and your users would be surprised by your exotic use of it. Why not pick any other character for end of chunk - double newline, Ctrl-S, pretty much anything but Ctrl-D? It's a waste of your time to fight a long-established standard.GDB handles Ctrl-D differently. It doesn't close the input on the first one, it waits for the second one and then exits. After the first one it acts like you typed 'quit', which asks you if you really want to quit when there's a program still running.That's because gdb uses libreadline (or something along those lines) with cbreak, so it can intercept control characters without them getting interpreted by the terminal. This requires manual control of terminal functions, which is something outside the scope of readf(). (You'd be better off writing your own terminal handling from scratch, if that's what you want.) T
Mar 27 2012
On 3/27/12 12:56 PM, Matt Peterson wrote:GDB handles Ctrl-D differently. It doesn't close the input on the first one, it waits for the second one and then exits. After the first one it acts like you typed 'quit', which asks you if you really want to quit when there's a program still running.A variety of other programs handle Ctrl-D differently (emacs, vi, etc). They aren't simple console input programs. Andrei
Mar 27 2012
On 03/26/2012 04:55 AM, Tyro[17] wrote:Ah! That's one of the problems. stdin has no idea whether there are more characters available. eof() being true is not dependable unless an attempt to read a character is made and failed. This is the case in C and C++ as well.void main(string[] args) { string s1; double d; string s2; writeln("Enter a terminated string (multiline ok):"); readf(" %s ", &s1); auto arr = s1.split(); if (!stdin.eof()) {I would like to repeat: ending the stream is not a solution because you want to read more data.writeln("The stream is not empty."); } else { writeln("The stream is empty."); } writeln("Enter another string (terminated withcntrl-d|ctrl-z):"); I am not sure about the cntrl-d|ctrl-z part though. Since it terminates the input, the program should not be able to read any more characters.That's the actual problem, and ironically is already known to you. :) Use a \n at the end of that format string.readf(" %s", &s2); // No matter how many read attemptsThank you. However, that method does not remove trailing whitespace.I advise reading string by readln(). You can call chomp() to get rid of whitespace around it: while (s2.length == 0) { s2 = chomp(readln()); }You can achieve the same with: readf(" %s\n", &s2);My goal however, is not to read one line of information. Rather, it is to read multiple lines of information from standard input. I get close to being able to do so if i don't including "\n" as a part of my formatstringor if I changing your suggestion to while (!stdin.eol()) { s2 = chomp(readln()); } but again I run into the predicament was before, a need to close the the stream with Ctrl-D/Ctrl-Z.If I understand you correctly, the following program works for me: import std.stdio; import std.string; void main(string[] args) { string s1; double d; string s2; writeln("Enter a terminated string (multiline ok):"); readf(" %s ", &s1); auto arr = s1.split(); writeln("Enter a line of string:"); readf(" %s\n", &s2); writeln("Enter a decimal value:"); readf(" %s", &d); writeln("d = ", d); writeln("arr = ", arr); writeln("s = ", s2); } Ali
Mar 26 2012
On Monday, 26 March 2012 at 17:34:37 UTC, Ali Çehreli wrote:On 03/26/2012 04:55 AM, Tyro[17] wrote:Thanks. I'le use chomp(readln()) in the future.That's the actual problem, and ironically is already known to you. :) Use a \n at the end of that format string.readf(" %s", &s2); // No matter how many read attemptsActually the problem is right here:get ridI advise reading string by readln(). You can call chomp() toThank you. However, that method does not remove trailing whitespace.of whitespace around it: while (s2.length == 0) { s2 = chomp(readln()); }You can achieve the same with: readf(" %s\n", &s2);My goal however, is not to read one line of information.Rather, it is toread multiple lines of information from standard input. I getclose tobeing able to do so if i don't including "\n" as a part of myformat stringor if I changing your suggestion to while (!stdin.eol()) { s2 = chomp(readln()); } but again I run into the predicament was before, a need toclose thethe stream with Ctrl-D/Ctrl-Z.If I understand you correctly, the following program works for me: import std.stdio; import std.string; void main(string[] args) { string s1; double d; string s2;writeln("Enter a terminated string (multiline ok):"); readf(" %s ", &s1); auto arr = s1.split();I don't want to provide an explicit terminator, but instead rely on Ctrl-D/Ctrl-Z to do the job while being able to continue processing read request. As explained by Andrei, this is not possible. But in my mind if the stdin stream can be opened once, it can be opened again. What is the negative effect of testing if it is closed and reopening it on entering readf? Especially since there is a unique implementation of readf to deal with input from stdin. What is wrong with implementing reopen() in File for specific use with stdin and then implementing readf like this: uint readf(A...)(in char[] format, A args) { if(stdin.eof) stdin.reopen(); return stdin.readf(format, args); } Andrew
Mar 26 2012
On 03/26/2012 02:12 PM, Tyro[17] wrote:I don't want to provide an explicit terminator, but instead rely on Ctrl-D/Ctrl-Z to do the job while being able to continue processing read request. As explained by Andrei, this is not possible. But in my mind if the stdin stream can be opened once, it can be opened again. What is the negative effect of testing if it is closed and reopening it on entering readf? Especially since there is a unique implementation of readf to deal with input from stdin. What is wrong with implementing reopen() in File for specific use with stdin and then implementing readf like this: uint readf(A...)(in char[] format, A args) { if(stdin.eof) stdin.reopen(); return stdin.readf(format, args); } AndrewThat doesn't fit the way standard input and output streams work. These streams are bound to the application from the environment that has started them. The program itself does not have a way of manipulating how these streams are ended or connected. Imagine that your program's stdin if piped from the output of another process: other | yours Once 'other' finishes with its output, that's the end of the input of 'yours'. 'yours' cannot communicate to the environment that it would like to continue reading more. What you are asking for could be achieved only if both the environment and the program agreed that this would be the case. Maybe I am missing something but that has been standard on many environments. Ali
Mar 26 2012
On Monday, 26 March 2012 at 21:20:00 UTC, Ali Çehreli wrote:On 03/26/2012 02:12 PM, Tyro[17] wrote:Thanks for that explanation. I am only now understanding the problem.I don't want to provide an explicit terminator, but instead rely on Ctrl-D/Ctrl-Z to do the job while being able to continue processing read request. As explained by Andrei, this is not possible. But in my mind if the stdin stream can be opened once, it can be opened again. What is the negative effect of testing if it is closed and reopening it on entering readf? Especially since there is a unique implementation of readf to deal with input from stdin. What is wrong with implementing reopen() in File for specific use with stdin and then implementing readf like this: uint readf(A...)(in char[] format, A args) { if(stdin.eof) stdin.reopen(); return stdin.readf(format, args); } AndrewThat doesn't fit the way standard input and output streams work. These streams are bound to the application from the environment that has started them. The program itself does not have a way of manipulating how these streams are ended or connected. Imagine that your program's stdin if piped from the output of another process: other | yours Once 'other' finishes with its output, that's the end of the input of 'yours'. 'yours' cannot communicate to the environment that it would like to continue reading more.What you are asking for could be achieved only if both the environment and the program agreed that this would be the case.Not really, we can "borrow" Ctrl-D form the OS until our input is complete. Please see response to Andrei.Maybe I am missing something but that has been standard on many environments. Ali
Mar 27 2012
First of all thank your very much for your assistance. On Sunday, 25 March 2012 at 15:04:30 UTC, Ali Çehreli wrote:On 03/25/2012 06:00 AM, Tyro[17] wrote:You can achieve the same with: readf(" %s\n", &s2); My goal however, is not to read one line of information. Rather, it is to read multiple lines of information from standard input. I get close to being able to do so if i don't including "\n" as a part of my format string or if I changing your suggestion to while (!stdin.eol()) { s2 = chomp(readln()); } but again I run into the predicament was before, a need to close the the stream with Ctrl-D/Ctrl-Z. AndrewI am trying to figure out the cause of my problem in thefollowing post:http://forum.dlang.org/thread/qfbugjkrerfboqhvjttw forum.dlang.org Sorry that I missed your question there. :(and encountered something peculiar about reading strings.Whenever adistinct terminator is indicated in the input format (ex. "%s ",being the terminator), readf() leaves the terminator on theinput bufferafter reading the data. If no terminator is specified theonly way toindicate end of input is to use ctrl-d (ctrl-z on windows),however thatcauses the eof indicator to be set to true and the stream ismarked asempty for all future attempts to access stdin. void main(string[] args) { string s1; double d; string s2; writeln("Enter a terminated string (multiline ok):"); readf(" %s ", &s1); auto arr = s1.split(); if (!stdin.eof()) { writeln("The stream is not empty."); } else { writeln("The stream is empty."); } writeln("Enter another string (terminated withcntrl-d|ctrl-z):"); I am not sure about the cntrl-d|ctrl-z part though. Since it terminates the input, the program should not be able to read any more characters.readf(" %s", &s2); // No matter how many read attemptsI advise reading string by readln(). You can call chomp() to get rid of whitespace around it: while (s2.length == 0) { s2 = chomp(readln()); }
Mar 26 2012