Re: Reading a line from stdin

2011-03-16 Thread Gerrit Wichert

Am 16.03.2011 11:09, schrieb spir:

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.

This is a very interesting statement and absolute contrary to my 
experience. I think It is never a design bug  for
a standart function to forward as much information as possible. 
Suppressing unwanted information is very easy,
but getting back some information that has been cut off by a courteous 
tool is an awful job.
That data comes in via stdin doesn't mean is is typed in by the user. 
It's perfectly possible that it is piped in and
 that the line endings should not be touched. You must be a very lucky 
person if you have never been bitten by

such a courteous piece of over engineered software.

I hope you can continue being lucky for a long time. :-)

Gerrit



Re: Reading a line from stdin

2011-03-16 Thread Jesse Phillips
Kai Meyer Wrote:

> Second, D doesn't seem to have a graceful way of reading an endless 
> stream of  delimited by  delimiting character>. I think readf is rigid, and works great in some 
> cases. I would greatly appreciate something more flexible like C++'s 
> extraction operator (operator>>) though. For example:

There is interest in getting a CSV parser in D. Of which I was hoping to be 
able to make use of a ForwardRange with Slicing... but could not find a way 
turn a buffered input range into a forward range. This made my second attempt 
useless for input ranges.

https://github.com/he-the-great/JPDLibs/tree/csv

https://github.com/he-the-great/JPDLibs/tree/separator

The benefit of the second is that you can using string to make a separator, or 
would be if startsWith worked as I want. But started working on the first to 
make it closer to what should be available in the standard library.


Re: Reading a line from stdin

2011-03-16 Thread Kai Meyer

On 03/16/2011 07:54 AM, Ali Çehreli wrote:

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


I think there are two issues here. First, I think is perfectly 
reasonable to let the programmer use a simple mechanism like 
"string.chomp(stdin.readline())" or simply "chomp(readln())" when they 
don't want the new line.


Second, D doesn't seem to have a graceful way of reading an endless 
stream of  delimited by delimiting character>. I think readf is rigid, and works great in some 
cases. I would greatly appreciate something more flexible like C++'s 
extraction operator (operator>>) though. For example:

int i = 0;
while(cin >> i)
{
//Do something
}
// Done doing something


Re: Reading a line from stdin

2011-03-16 Thread Kagamin
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.


Re: Reading a line from stdin

2011-03-16 Thread Jesse Phillips
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.


Re: Reading a line from stdin

2011-03-16 Thread Ali Çehreli

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


Re: Reading a line from stdin

2011-03-16 Thread Kagamin
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?


Re: Reading a line from stdin

2011-03-16 Thread Lars T. Kyllingstad
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


Re: Reading a line from stdin

2011-03-16 Thread spir

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



Re: Reading a line from stdin

2011-03-16 Thread spir

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



Re: Reading a line from stdin

2011-03-15 Thread Jonathan M Davis
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


Re: Reading a line from stdin

2011-03-15 Thread Jesse Phillips
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.


Reading a line from stdin

2011-03-15 Thread Ali Çehreli
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