Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 16, 2011 Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
I am going over some sample programs in a text of mine and replacing std.cstream references with std.stdio. There are non-trivial differences with formatted input. The following program may be surprising to the novice: import std.stdio; void main() { write("What is your name? "); string name = readln(); writeln("Hi ", name, "!"); } The newline character is read as a part of the input: What is your name? Ali Hi Ali ! <-- this is outputted on the next line because of the newline character A solution is to strip the line after reading: import std.string; // ... string name = strip(readln()); Right? Is there a better way that I am missing? Thank you, Ali |
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Çehreli Wrote:
> Right? Is there a better way that I am missing?
>
> Thank you,
> Ali
No better way, the stated reason IIRC is that it is easier to remove the new line then to append it back on.
|
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Tuesday 15 March 2011 22:05:37 Ali Çehreli wrote:
> I am going over some sample programs in a text of mine and replacing std.cstream references with std.stdio. There are non-trivial differences with formatted input.
>
> The following program may be surprising to the novice:
>
> import std.stdio;
>
> void main()
> {
> write("What is your name? ");
> string name = readln();
> writeln("Hi ", name, "!");
> }
>
> The newline character is read as a part of the input:
>
> What is your name? Ali
> Hi Ali
> ! <-- this is outputted on the next line
> because of the newline character
>
> A solution is to strip the line after reading:
>
> import std.string;
> // ...
> string name = strip(readln());
>
> Right? Is there a better way that I am missing?
I don't think that it's all that odd from the newline to be left in. It _was_ in the original input, after all. I don't recall what the typical thing to do is in other languages though, since I don't do a lot with input from stdin. I can understand why you would think that it's odd, but I think that it's fine as is. It's a matter of preference really, and as Jesse points out, it's easier to just leave it in and allow the programmer to remove it than to remove it and make the programmer put it back if they want it (especially since that would require a reallocation whereas the other does not).
- Jonathan M Davis
|
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 03/16/2011 06:05 AM, Ali Çehreli wrote: > I am going over some sample programs in a text of mine and replacing > std.cstream references with std.stdio. There are non-trivial differences with > formatted input. > > The following program may be surprising to the novice: > > import std.stdio; > > void main() > { > write("What is your name? "); > string name = readln(); > writeln("Hi ", name, "!"); > } > > The newline character is read as a part of the input: > > What is your name? Ali > Hi Ali > ! <-- this is outputted on the next line > because of the newline character This is a design bug. 99% of the time one does not want the newline, which is not part of the string data, instead just a terminator. Even more on stdin where it is used by the user to say "I"m done!". If the text is written back to the output /and/ newline is needed, it's easy to add it or use writeln. Also, to avoid using strip --which is costly and may remove other significant whitespace at start and end of line, one would have to manually check for CR and/or LF, and remove it, *twice*. A solution may be to have a boolean param "keepNewLine" beeing false in standard. > A solution is to strip the line after reading: > > import std.string; > // ... > string name = strip(readln()); > > Right? Is there a better way that I am missing? Dunno. Denis -- _________________ vita es estrany spir.wikidot.com |
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On 03/16/2011 06:41 AM, Jesse Phillips wrote: > Ali Çehreli Wrote: > >> Right? Is there a better way that I am missing? >> >> Thank you, >> Ali > > No better way, the stated reason IIRC is that it is easier to remove the new line then to append it back on. May be stated, but it is very wrong! I guess: s = s ~ '\n'; versus if ((str[$-1] == '\n') || (str[$-1] == '\r')) { str = str[0..$-1]; if ((str[$-1] == '\n') || (str[$-1] == '\r')) { str = str[0..$-1]; } } And it's not what programmers want in most cases, anyway. Actually, when does one need it? Denis -- _________________ vita es estrany spir.wikidot.com |
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to spir | On Wed, 16 Mar 2011 11:20:43 +0100, spir wrote:
> On 03/16/2011 06:41 AM, Jesse Phillips wrote:
>> Ali Çehreli Wrote:
>>
>>> Right? Is there a better way that I am missing?
>>>
>>> Thank you,
>>> Ali
>>
>> No better way, the stated reason IIRC is that it is easier to remove the new line then to append it back on.
>
> May be stated, but it is very wrong! I guess:
>
> s = s ~ '\n';
> versus
> if ((str[$-1] == '\n') || (str[$-1] == '\r')) {
> str = str[0..$-1];
> if ((str[$-1] == '\n') || (str[$-1] == '\r')) {
> str = str[0..$-1];
> }
> }
That comparison seems a bit biased. :) This one is more fair:
import std.path;
...
s ~= linesep;
versus
import std.string;
...
s = s.chomp;
-Lars
|
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Ç¥hreli Wrote:
> The following program may be surprising to the novice:
>
> import std.stdio;
>
> void main()
> {
> write("What is your name? ");
> string name = readln();
> writeln("Hi ", name, "!");
> }
What if the user typed leading spaces? Will the program operate as you expect?
|
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On 03/16/2011 05:49 AM, Kagamin wrote:
> Ali ǥhreli Wrote:
>
>> The following program may be surprising to the novice:
>>
>> import std.stdio;
>>
>> void main()
>> {
>> write("What is your name? ");
>> string name = readln();
>> writeln("Hi ", name, "!");
>> }
>
> What if the user typed leading spaces? Will the program operate as you expect?
I would not like the leading spaces either, and that's another issue: contrary to readln(), readf() leaves the newline character in the input. I was about to start adopting the guideline of using " %s" (note the space) when reading formatted unless there is a reason not to. Most of the time the newline left from the previous input has nothing to do with the next read.
Otherwise the following program gets stuck:
import std.stdio;
void main()
{
int i, j;
readf("%s%s", &i, &j);
}
As a result, my current guideline is "put a space before every format specifier":
readf(" %s %s", &i, &j);
This is a departure from C's scanf but is more consistent.
I don't want to accept and teach buggy behavior and that's why I asked on the D forum. Unfortunately I failed to attract interest there.
After accepting the above, I wanted to readf() lines too:
import std.stdio;
void main()
{
string s;
readf(" %s", &s);
writeln(s);
}
As another departure from C, readf() does not stop at the first whitespace. It reads until the end of the input. Ok, I like that behavior but it's not useful for "What is your name? " like inputs.
So it led me to readln().
I don't have a problem with whitespace being left in the line, I just want to know whether that's the intended or accepted behavior.
Ali
|
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to spir | spir Wrote: > On 03/16/2011 06:41 AM, Jesse Phillips wrote: > > Ali Çehreli Wrote: > > > >> Right? Is there a better way that I am missing? > >> > >> Thank you, > >> Ali > > > > No better way, the stated reason IIRC is that it is easier to remove the new line then to append it back on. > > May be stated, but it is very wrong! I guess: Sorry what I believe it refers to is that it is easier for the computer. There is no need to allocate or reallocate any memory. > And it's not what programmers want in most cases, anyway. Actually, when does one need it? I do not know of an actual use case for needing the new line. In fact you could argue that splitlines should keep the end line character, but no one would see that. |
March 16, 2011 Re: Reading a line from stdin | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ali Çehreli Wrote:
> I don't have a problem with whitespace being left in the line, I just want to know whether that's the intended or accepted behavior.
AFAIK, it is. It was intended to preserve eols while reading and writing lines.
|
Copyright © 1999-2021 by the D Language Foundation