Topic: ignore zero or more


Author: jpotter@falcon.lhup.edu (John Potter)
Date: Mon, 26 Apr 2004 01:53:25 +0000 (UTC)
Raw View
On Fri, 23 Apr 2004 23:07:37 +0000 (UTC), francis@robinton.demon.co.uk
(Francis Glassborow) wrote:

> What I want is some way to stabilise an istream object so that it is
> irrelevant whether the last use did or did not remove trailing
> whitespace up to an including a delimiter.

I thought that you first talked about an "ignore zero or more" function.
In the discussion, this has changed to just a way to test whether
anything should be ignored.  Let me take your example from an earlier
post which called one of two functions.  I think that you wanted to
be sure that the line had been cleared whether >> or getline was used
within the function.  If I understand your problem, the following does
the trick with Bcc32/dos, g++2.95/aix and G++3.2/cygwin|linux.

#include <iostream>
#include <string>
using namespace std;
string foo(istream& is) {
    string s;
    is >> s;
    return s;
    }
string bar(istream& is) {
    string s;
    getline(is, s);
    return s;
    }
int main(int argc, char**) {
    bool source(argc > 1);
    string data;
    data = source ? foo(cin) : bar(cin);
    if (cin.unget().get() != '\n')
        cin.ignore(numeric_limits<int>::max(), '\n');
    string more_data;
    getline(cin, more_data);
    cin.ignore(numeric_limits<int>::max());
    cout << data << "\n";
    cout << more_data << "\n";
    }

Using an input file with:

hello junk
world
trash

the second line of output is world in both cases.

Will this work or am I missing the problem?

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 26 Apr 2004 17:41:43 +0000 (UTC)
Raw View
In article <_2Wic.2373$g31.2326@newsread2.news.atl.earthlink.net>, John
Potter <jpotter@falcon.lhup.edu> writes
>#include <iostream>
>#include <string>
>using namespace std;
>string foo(istream& is) {
>    string s;
>    is >> s;
>    return s;
>    }
>string bar(istream& is) {
>    string s;
>    getline(is, s);
>    return s;
>    }
>int main(int argc, char**) {
>    bool source(argc > 1);
>    string data;
>    data = source ? foo(cin) : bar(cin);
>    if (cin.unget().get() != '\n')
>        cin.ignore(numeric_limits<int>::max(), '\n');
>    string more_data;
>    getline(cin, more_data);
>    cin.ignore(numeric_limits<int>::max());
>    cout << data << "\n";
>    cout << more_data << "\n";
>    }
>
>Using an input file with:
>
>hello junk
>world
>trash
>
>the second line of output is world in both cases.

But not when I tested it on MinGW. But is_avail() as a solution to the
problem also works on the compilers you listed.

This leads me to suspect that the problem lies in the option MinGW has
chosen for implementing cin. Assuming that conforms to the current
Standard perhaps the solution to the problem is to change the Standard
so that that is not a valid option.

>
>Will this work or am I missing the problem?

I think your answer is just one of several that appear as if they will
work, and actually do work with many implementations. However AFAIK it
is not required to work. Perhaps we should require that they do so at
least in the case of the default buffering for such object as std::cin.

Anyway, thanks for taking the time to look at the problem and help me
get a better idea as to exactly what may be getting in the way of a
portable solution.


--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Mon, 26 Apr 2004 21:38:05 +0000 (UTC)
Raw View
On Mon, 26 Apr 2004 17:41:43 +0000 (UTC), francis@robinton.demon.co.uk
(Francis Glassborow) wrote:

> In article <_2Wic.2373$g31.2326@newsread2.news.atl.earthlink.net>, John
> Potter <jpotter@falcon.lhup.edu> writes

> >the second line of output is world in both cases.

> But not when I tested it on MinGW. But is_avail() as a solution to the
> problem also works on the compilers you listed.

I note that in_avail() would not be a solution with input redirected
from a file.  I'm not sure what you want, but I would want the same
result from a file as from the keyboard.

The MinGW version does work like the others when redirecting the input.

After the >>, peek shows the space.  The unget().get() skips over the
rest of the line and gets the w from the next line.  I can't find any
justification for this behavior in the standard.  I think this is just
a bug in MinGW.

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Thu, 22 Apr 2004 17:45:16 +0000 (UTC)
Raw View
On Tue, 20 Apr 2004 20:55:24 +0000 (UTC), francis@robinton.demon.co.uk
(Francis Glassborow) wrote:

> Currently if the programmer knows that there is trash in cin's input
> buffer they can clear it out with a suitable call of cin.ignore

I think I understand your problem, but not its statement.  What if cin
is unbuffered?  What buffer are you talking about?  What if I am on a
un*x box and type a ^D rather than an <enter> to send the data to the
program?

> The
> problem occurs when the programmer does not know if the program flow has
> left cin's buffer with anything in it (this happens when there may or
> may not have been a call to getline).

My feeling is that a programmer who does not know how the program flows
is beyond help.

> If the buffer is empty any call
> will simply wait for input. I do not think the programmer can fix this
> (if they can I have not found the way).

Are you looking for some kind of kbhit?  Where is this "buffer"?

> However I think the Standard
> Library could do so by providing a version so that

> cin.ignore(numeric_limits<int>::max(),'\n');

Is this only when the delimeter is '\n'?

> returns if there is nothing to ignore rather than waiting to ignore the
> next line of input if there is nothing currently waiting.

Is there a race condition?  What if I type some stuff, but not the
<enter>?  Should it wait for more and the <enter> or continue?

> I realise this is quite awkward, but it is very much easier for the
> library implementor than for the user.

What if I redirect from a file.  Does the behavior change?  Your library
implementors must be much more powerful than I gave them credit. ;-)

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 22 Apr 2004 19:07:08 +0000 (UTC)
Raw View
In article <tuPhc.6442$gH6.3624@newsread3.news.atl.earthlink.net>, John
Potter <jpotter@falcon.lhup.edu> writes
>On Tue, 20 Apr 2004 20:55:24 +0000 (UTC), francis@robinton.demon.co.uk
>(Francis Glassborow) wrote:
>
>> Currently if the programmer knows that there is trash in cin's input
>> buffer they can clear it out with a suitable call of cin.ignore
>
>I think I understand your problem, but not its statement.  What if cin
>is unbuffered?  What buffer are you talking about?  What if I am on a
>un*x box and type a ^D rather than an <enter> to send the data to the
>program?

While I know it can be done, typing and eof (its CTRL Z on a windows
box) to send data to a program is another complication but at least you
can tell you user not to do that.

>
>> The
>> problem occurs when the programmer does not know if the program flow has
>> left cin's buffer with anything in it (this happens when there may or
>> may not have been a call to getline).
>
>My feeling is that a programmer who does not know how the program flows
>is beyond help.

string foo(istream&);
string bar(istream&);

int main(){
  string data;
  bool source;
// code initialising source
  data = source ?  foo(cin) : bar(cin);
  string more_data;
  getline(cin, more_data);  // A
// rest of program
}

Now how can the programmer know the state of cin without knowing how
foo() and bar() leave it?

>
>> If the buffer is empty any call
>> will simply wait for input. I do not think the programmer can fix this
>> (if they can I have not found the way).
>
>Are you looking for some kind of kbhit?  Where is this "buffer"?

No (though adding a raw keyboard read might further complicate the issue
of the state of cin.

>
>> However I think the Standard
>> Library could do so by providing a version so that
>
>> cin.ignore(numeric_limits<int>::max(),'\n');
>
>Is this only when the delimeter is '\n'?

I think that is all that is necessary.

>
>> returns if there is nothing to ignore rather than waiting to ignore the
>> next line of input if there is nothing currently waiting.
>
>Is there a race condition?  What if I type some stuff, but not the
><enter>?  Should it wait for more and the <enter> or continue?

That is the point, it shouldn't. The problem is that getline can and
usually does clear trailing whitespace up to and including a '\n' while
other extraction techniques such as operator >> do not.

>
>> I realise this is quite awkward, but it is very much easier for the
>> library implementor than for the user.
>
>What if I redirect from a file.  Does the behavior change?
No. The minimum requirement is that cin keeps a status (perhaps just
remembering the last char it 'used' would be enough because the
programmer could then just check if that was '\n' and act accordingly.

> Your library
>implementors must be much more powerful than I gave them credit. ;-)

No they just have to understand the problem. Now I think of it,
requiring all input streams to remember the last character extracted
could have small but general utility. Perhaps I was being too
minimalist. Requiring buffered input for cin might also solve the
problem.



--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Fri, 23 Apr 2004 04:53:08 +0000 (UTC)
Raw View
On Thu, 22 Apr 2004 19:07:08 +0000 (UTC), francis@robinton.demon.co.uk
(Francis Glassborow) wrote:

> In article <tuPhc.6442$gH6.3624@newsread3.news.atl.earthlink.net>, John
> Potter <jpotter@falcon.lhup.edu> writes
> >On Tue, 20 Apr 2004 20:55:24 +0000 (UTC), francis@robinton.demon.co.uk
> >(Francis Glassborow) wrote:

> >> Currently if the programmer knows that there is trash in cin's input
> >> buffer they can clear it out with a suitable call of cin.ignore

> >I think I understand your problem, but not its statement.  What if cin
> >is unbuffered?  What buffer are you talking about?  What if I am on a
> >un*x box and type a ^D rather than an <enter> to send the data to the
> >program?

> While I know it can be done, typing and eof (its CTRL Z on a windows
> box) to send data to a program is another complication but at least you
> can tell you user not to do that.

I think you may be confused.  Typing ^Z on a windows box is typing
a character and it does nothing until the line is terminated.  It may be
erased by ^H.  Typing a ^D on a un*x box sends the current data to the
program and may not be recovered.  If there is no data sent, it is
interpreted as EOF.  The ^D is not sent, it is interpreted by the
system and never reaches the program.

Consider the following program.

#include <iostream>
#include <string>
using namespace std;
int main () {
    string s;
    while (cin >> s)
        cout << s << endl;
    }

If I run this on a un*x box and then type:

  Hello ^Dworld^M

Hello is output as soon as I type ^D.  How do you expect your desire
to be implemented on this system?  Replace the ^D by ^Z on a dos box
and nothing happens until the ^M.

By the sound of the rest of your post, you may be reconsidering just
what should happen and when.  Is there a difference between
cin.getline(s) and (cin >> s).get() when there is only one word and
a newline?  Hope this helps.

It seems that you want a function which ignores all characters up to
a newline unless the last character extracted was a newline.  Are you
sure that is what you want?

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Fri, 23 Apr 2004 23:07:37 +0000 (UTC)
Raw View
In article <cY_hc.19002$l75.17899@newsread2.news.atl.earthlink.net>,
John Potter <jpotter@falcon.lhup.edu> writes
>It seems that you want a function which ignores all characters up to
>a newline unless the last character extracted was a newline.  Are you
>sure that is what you want?

No to your last question, else I would write a proposal for such. Thank
you for the explanation of ^D on unix boxes; I had not fully appreciated
what it did and results in added complexity because if I understand
correctly, however logical as a design it results in a difficult to
cater for difference between unix console input and that used by
MSWindows (which behaviour, IIRC, traces its origins back to CP/M).

What I want is some way to stabilise an istream object so that it is
irrelevant whether the last use did or did not remove trailing
whitespace up to an including a delimiter. So far after a year of
searching and talking to people who might know a solution I have failed
to find one.

--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dSpam@arcor.de (Dietmar Schindler)
Date: Fri, 23 Apr 2004 23:07:57 +0000 (UTC)
Raw View
John Potter wrote:
> It seems that you want a function which ignores all characters up to
> a newline unless the last character extracted was a newline.  Are you
> sure that is what you want?

Of course I am not in a position to say what Mr. Glassborow wants, but I
think he would be content if in_avail() would work as it is supposed to,
like in the example in

http://www.cplusplus.com/ref/iostream/streambuf/in_avail.html

I just tried it with my gcc version 3.2, and just as on the compilers
Mr. Glassborow has tried, it didn't work. But this has to be fixed by
the library writers, I think, and there is nothing wrong or missing with
the standard.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Tue, 20 Apr 2004 20:55:24 +0000 (UTC)
Raw View
Currently if the programmer knows that there is trash in cin's input
buffer they can clear it out with a suitable call of cin.ignore The
problem occurs when the programmer does not know if the program flow has
left cin's buffer with anything in it (this happens when there may or
may not have been a call to getline). If the buffer is empty any call
will simply wait for input. I do not think the programmer can fix this
(if they can I have not found the way). However I think the Standard
Library could do so by providing a version so that

cin.ignore(numeric_limits<int>::max(),'\n');

returns if there is nothing to ignore rather than waiting to ignore the
next line of input if there is nothing currently waiting.

I realise this is quite awkward, but it is very much easier for the
library implementor than for the user.

--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Wed, 21 Apr 2004 15:07:29 +0000 (UTC)
Raw View
Francis Glassborow wrote:
>
> cin.ignore(numeric_limits<int>::max(),'\n');
>
> returns if there is nothing to ignore rather than waiting to ignore the
> next line of input if there is nothing currently waiting.
>

if(cin.rdbuf()->in_avail())
   cin.ignore(numeric_limits<int>::max(),'\n');

(sorry for the previous post, there was an "rdbuf()->" missing)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Wed, 21 Apr 2004 18:17:25 +0000 (UTC)
Raw View
In article <Eprhc.14537$Qc.586378@twister1.libero.it>, Alberto Barbati
<AlbertoBarbati@libero.it> writes
>Francis Glassborow wrote:
>>  cin.ignore(numeric_limits<int>::max(),'\n');
>>  returns if there is nothing to ignore rather than waiting to ignore
>>the next line of input if there is nothing currently waiting.
>>
>
>if(cin.rdbuf()->in_avail())
>  cin.ignore(numeric_limits<int>::max(),'\n');
>
>(sorry for the previous post, there was an "rdbuf()->" missing)

Does not work, or at least it does not on the compilers I have tried.

--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Wed, 21 Apr 2004 19:32:39 +0000 (UTC)
Raw View
Francis Glassborow wrote:
>
> cin.ignore(numeric_limits<int>::max(),'\n');
>
> returns if there is nothing to ignore rather than waiting to ignore the
> next line of input if there is nothing currently waiting.
>

if(cin.in_avail())
   cin.ignore(numeric_limits<int>::max(),'\n');

Wouldn't this suffice?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 22 Apr 2004 05:12:26 +0000 (UTC)
Raw View
In article <ilrhc.138097$Kc3.4595353@twister2.libero.it>, Alberto
Barbati <AlbertoBarbati@libero.it> writes
>Francis Glassborow wrote:
>>  cin.ignore(numeric_limits<int>::max(),'\n');
>>  returns if there is nothing to ignore rather than waiting to ignore
>>the  next line of input if there is nothing currently waiting.
>>
>
>if(cin.in_avail())
>  cin.ignore(numeric_limits<int>::max(),'\n');
>
>Wouldn't this suffice?

Yes, if it worked but ASFICT it doesn't.

--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]