Topic: Suggested new operator>> for istreams
Author: shachar@lingnu.com
Date: Sun, 4 May 2014 11:14:43 -0700 (PDT)
Raw View
------=_Part_1986_12188671.1399227283355
Content-Type: text/plain; charset=UTF-8
std::istream is supposed to replace C's scanf. Unfortunately, it lacks
power in two respects, making it much much much less useful.
The first respect, and one not addressed with this idea, is that scanf
returns the number of arguments successfully parsed. istream only has a
boolean meaning whether ALL arguments were successfully parsed or not.
Frankly, for my particular use cases, this is less of an issue.
The second respect is that scanf allows specifying characters to appear
verbatim in the input sequence, to be consumed by scanf. Please consider my
open source program, fakeroot-ng. It stores a state file that has the
following syntax:
dev=fe07,ino=6074857,mode=100644,uid=0,gid=1000,rdev=0
Reading it in is done with the following line[1]:
while( (params=fscanf(file, "dev=" DEV_F ", ino=" INODE_F ", mode=%o, uid=%d, gid=%d, rdev=" DEV_F " \n", &override.dev, &override.inode,
&override.mode, &override.uid, &override.gid, &override.dev_id ))==6 )
It seems C++ has no reasonable alternatives.
I suggest the following three functions should be added to the standard
library:
std::istream &operator>>( std::istream &stream, const char &chr );
std::istream &operator>>( std::istream &stream, const char *string );
std::istream &operator>>( std::istream &stream, const std::string &string );
Each one will consume the relevant characters from the input stream,
setting fail (or throwing, if so configured) in case the characters don't
match. If the stream is set to ignore white spaces, the last two overloads
should also ignore white spaces in their input.
This makes simple parsing sane again on C++[2].
Feedback welcome,
Shachar
1 - http://sourceforge.net/p/fakerootng/source/ci/0.18/tree/file_lie.cpp#l67
2 -
http://sourceforge.net/p/fakerootng/source/ci/multithreaded_debugger/tree/file_lie.cpp#l162
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1986_12188671.1399227283355
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">std::istream is supposed to replace C's scanf. Unfortunate=
ly, it lacks power in two respects, making it much much much less useful.<b=
r><br>The first respect, and one not addressed with this idea, is that scan=
f returns the number of arguments successfully parsed. istream only has a b=
oolean meaning whether ALL arguments were successfully parsed or not. Frank=
ly, for my particular use cases, this is less of an issue.<br><br>The secon=
d respect is that scanf allows specifying characters to appear verbatim in =
the input sequence, to be consumed by scanf. Please consider my open source=
program, fakeroot-ng. It stores a state file that has the following syntax=
:<br>dev=3Dfe07,ino=3D6074857,mode=3D100644,uid=3D0,gid=3D1000,rdev=3D0<br>=
<br>Reading it in is done with the following line[1]:<br><pre><div style=3D=
"background-color: rgb(255, 255, 153);" id=3D"l67" class=3D"code_block"> =
<span class=3D"k">while</span><span class=3D"p">(</span> <span class=3D"p"=
>(</span><span class=3D"n">params</span><span class=3D"o">=3D</span><span c=
lass=3D"n">fscanf</span><span class=3D"p">(</span><span class=3D"n">file</s=
pan><span class=3D"p">,</span> <span class=3D"s">"dev=3D"</span> <span clas=
s=3D"n">DEV_F</span> <span class=3D"s">", ino=3D"</span> <span class=3D"n">=
INODE_F</span> <span class=3D"s">", mode=3D%o, uid=3D%d, gid=3D%d, rdev=3D"=
</span> <span class=3D"n">DEV_F</span> <span class=3D"s">" </span><span cla=
ss=3D"se">\n</span><span class=3D"s">"</span><span class=3D"p">,</span> <sp=
an class=3D"o">&</span><span class=3D"n">override</span><span class=3D"=
p">.</span><span class=3D"n">dev</span><span class=3D"p">,</span> <span cla=
ss=3D"o">&</span><span class=3D"n">override</span><span class=3D"p">.</=
span><span class=3D"n">inode</span><span class=3D"p">,</span>
</div><div id=3D"l68" class=3D"code_block"> <span class=3D"o">&a=
mp;</span><span class=3D"n">override</span><span class=3D"p">.</span><span =
class=3D"n">mode</span><span class=3D"p">,</span> <span class=3D"o">&</=
span><span class=3D"n">override</span><span class=3D"p">.</span><span class=
=3D"n">uid</span><span class=3D"p">,</span> <span class=3D"o">&</span><=
span class=3D"n">override</span><span class=3D"p">.</span><span class=3D"n"=
>gid</span><span class=3D"p">,</span> <span class=3D"o">&</span><span c=
lass=3D"n">override</span><span class=3D"p">.</span><span class=3D"n">dev_i=
d</span> <span class=3D"p">))</span><span class=3D"o">=3D=3D</span><span cl=
ass=3D"mi">6</span> <span class=3D"p">)</span>
</div></pre><br>It seems C++ has no reasonable alternatives.<br><br>I sugge=
st the following three functions should be added to the standard library:<b=
r><br><pre><div id=3D"l8" class=3D"code_block"><span class=3D"n">std</span>=
<span class=3D"o">::</span><span class=3D"n">istream</span> <span class=3D"=
o">&</span><span class=3D"n">operator</span><span class=3D"o">>><=
/span><span class=3D"p">(</span> <span class=3D"n">std</span><span class=3D=
"o">::</span><span class=3D"n">istream</span> <span class=3D"o">&</span=
><span class=3D"n">stream</span><span class=3D"p">,</span> <span class=3D"k=
">const</span> <span class=3D"kt">char</span> <span class=3D"o">&</span=
><span class=3D"n">chr</span> <span class=3D"p">);</span>
</div><div id=3D"l9" class=3D"code_block"><span class=3D"n">std</span><span=
class=3D"o">::</span><span class=3D"n">istream</span> <span class=3D"o">&a=
mp;</span><span class=3D"n">operator</span><span class=3D"o">>></span=
><span class=3D"p">(</span> <span class=3D"n">std</span><span class=3D"o">:=
:</span><span class=3D"n">istream</span> <span class=3D"o">&</span><spa=
n class=3D"n">stream</span><span class=3D"p">,</span> <span class=3D"k">con=
st</span> <span class=3D"kt">char</span> <span class=3D"o">*</span><span cl=
ass=3D"n">string</span> <span class=3D"p">);</span>
</div><div id=3D"l10" class=3D"code_block"><span class=3D"n">std</span><spa=
n class=3D"o">::</span><span class=3D"n">istream</span> <span class=3D"o">&=
amp;</span><span class=3D"n">operator</span><span class=3D"o">>></spa=
n><span class=3D"p">(</span> <span class=3D"n">std</span><span class=3D"o">=
::</span><span class=3D"n">istream</span> <span class=3D"o">&</span><sp=
an class=3D"n">stream</span><span class=3D"p">,</span> <span class=3D"k">co=
nst</span> <span class=3D"n">std</span><span class=3D"o">::</span><span cla=
ss=3D"n">string</span> <span class=3D"o">&</span><span class=3D"n">stri=
ng</span> <span class=3D"p">);</span>
</div><div id=3D"l11" class=3D"code_block">
</div></pre>Each one will consume the relevant characters from the input st=
ream, setting fail (or throwing, if so configured) in case the characters d=
on't match. If the stream is set to ignore white spaces, the last two overl=
oads should also ignore white spaces in their input.<br><br>This makes simp=
le parsing sane again on C++[2].<br><br>Feedback welcome,<br>Shachar<br><br=
>1 - http://sourceforge.net/p/fakerootng/source/ci/0.18/tree/file_lie.cpp#l=
67<br>2 - http://sourceforge.net/p/fakerootng/source/ci/multithreaded_debug=
ger/tree/file_lie.cpp#l162<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1986_12188671.1399227283355--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Sun, 4 May 2014 12:48:54 -0700
Raw View
--047d7b3a925008ae3504f8984e69
Content-Type: text/plain; charset=UTF-8
On Sun, May 4, 2014 at 11:14 AM, <shachar@lingnu.com> wrote:
> std::istream is supposed to replace C's scanf. Unfortunately, it lacks
> power in two respects, making it much much much less useful.
>
> The first respect, and one not addressed with this idea, is that scanf
> returns the number of arguments successfully parsed. istream only has a
> boolean meaning whether ALL arguments were successfully parsed or not.
> Frankly, for my particular use cases, this is less of an issue.
>
> The second respect is that scanf allows specifying characters to appear
> verbatim in the input sequence, to be consumed by scanf. Please consider my
> open source program, fakeroot-ng. It stores a state file that has the
> following syntax:
> dev=fe07,ino=6074857,mode=100644,uid=0,gid=1000,rdev=0
>
> Reading it in is done with the following line[1]:
>
> while( (params=fscanf(file, "dev=" DEV_F ", ino=" INODE_F ", mode=%o, uid=%d, gid=%d, rdev=" DEV_F " \n", &override.dev, &override.inode,
> &override.mode, &override.uid, &override.gid, &override.dev_id ))==6 )
>
>
> It seems C++ has no reasonable alternatives.
>
> I suggest the following three functions should be added to the standard
> library:
>
> std::istream &operator>>( std::istream &stream, const char &chr );
> std::istream &operator>>( std::istream &stream, const char *string );
> std::istream &operator>>( std::istream &stream, const std::string &string );
>
> Each one will consume the relevant characters from the input stream,
> setting fail (or throwing, if so configured) in case the characters don't
> match. If the stream is set to ignore white spaces, the last two overloads
> should also ignore white spaces in their input.
>
> This makes simple parsing sane again on C++[2].
>
> Feedback welcome,
>
This makes the overload set for operator>> rather scary.
void f() {
const char expected1[] = "dev=" DEV_F;
char expected2[] = "ino=" INODE_F;
std::cin >> expected1; // read, check, and discard characters
std::cin >> expected2; // read characters *into* expected2.
}
Perhaps some kind of wrapper would help?
struct expected { expected(const char *); const char *text; };
std::istream &operator>>(std::istream &stream, expected);
// ...
std::cin >> expected(expected1) >> expected(expected2);
Shachar
>
> 1 -
> http://sourceforge.net/p/fakerootng/source/ci/0.18/tree/file_lie.cpp#l67
> 2 -
> http://sourceforge.net/p/fakerootng/source/ci/multithreaded_debugger/tree/file_lie.cpp#l162
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b3a925008ae3504f8984e69
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, May 4, 2014 at 11:14 AM, <span dir=3D"ltr"><<a href=3D"mailto:shach=
ar@lingnu.com" target=3D"_blank">shachar@lingnu.com</a>></span> wrote:<b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">std::istream is supposed to replace C's scanf. Unfortu=
nately, it lacks power in two respects, making it much much much less usefu=
l.<br><br>The first respect, and one not addressed with this idea, is that =
scanf returns the number of arguments successfully parsed. istream only has=
a boolean meaning whether ALL arguments were successfully parsed or not. F=
rankly, for my particular use cases, this is less of an issue.<br>
<br>The second respect is that scanf allows specifying characters to appear=
verbatim in the input sequence, to be consumed by scanf. Please consider m=
y open source program, fakeroot-ng. It stores a state file that has the fol=
lowing syntax:<br>
dev=3Dfe07,ino=3D6074857,mode=3D100644,uid=3D0,gid=3D1000,rdev=3D0<br><br>R=
eading it in is done with the following line[1]:<br><pre><div style=3D"back=
ground-color:rgb(255,255,153)"> <span>while</span><span>(</span> <span>(=
</span><span>params</span><span>=3D</span><span>fscanf</span><span>(</span>=
<span>file</span><span>,</span> <span>"dev=3D"</span> <span>DEV_F=
</span> <span>", ino=3D"</span> <span>INODE_F</span> <span>"=
, mode=3D%o, uid=3D%d, gid=3D%d, rdev=3D"</span> <span>DEV_F</span> <s=
pan>" </span><span>\n</span><span>"</span><span>,</span> <span>&a=
mp;</span><span>override</span><span>.</span><span>dev</span><span>,</span>=
<span>&</span><span>override</span><span>.</span><span>inode</span><sp=
an>,</span>
</div><div> <span>&</span><span>override</span><span>.</span=
><span>mode</span><span>,</span> <span>&</span><span>override</span><sp=
an>.</span><span>uid</span><span>,</span> <span>&</span><span>override<=
/span><span>.</span><span>gid</span><span>,</span> <span>&</span><span>=
override</span><span>.</span><span>dev_id</span> <span>))</span><span>=3D=
=3D</span><span>6</span> <span>)</span>
</div></pre><br>It seems C++ has no reasonable alternatives.<br><br>I sugge=
st the following three functions should be added to the standard library:<b=
r><br><pre><div><span>std</span><span>::</span><span>istream</span> <span>&=
amp;</span><span>operator</span><span>>></span><span>(</span> <span>s=
td</span><span>::</span><span>istream</span> <span>&</span><span>stream=
</span><span>,</span> <span>const</span> <span>char</span> <span>&</spa=
n><span>chr</span> <span>);</span>
</div><div><span>std</span><span>::</span><span>istream</span> <span>&<=
/span><span>operator</span><span>>></span><span>(</span> <span>std</s=
pan><span>::</span><span>istream</span> <span>&</span><span>stream</spa=
n><span>,</span> <span>const</span> <span>char</span> <span>*</span><span>s=
tring</span> <span>);</span>
</div><div><span>std</span><span>::</span><span>istream</span> <span>&<=
/span><span>operator</span><span>>></span><span>(</span> <span>std</s=
pan><span>::</span><span>istream</span> <span>&</span><span>stream</spa=
n><span>,</span> <span>const</span> <span>std</span><span>::</span><span>st=
ring</span> <span>&</span><span>string</span> <span>);</span>
</div><div>
</div></pre>Each one will consume the relevant characters from the input st=
ream, setting fail (or throwing, if so configured) in case the characters d=
on't match. If the stream is set to ignore white spaces, the last two o=
verloads should also ignore white spaces in their input.<br>
<br>This makes simple parsing sane again on C++[2].<br><br>Feedback welcome=
,<br></div></blockquote><div><br></div><div>This makes the overload set for=
operator>> rather scary.</div><div><br></div><div>void f() {</div>
<div>=C2=A0 const char expected1[] =3D "dev=3D" DEV_F;</div><div>=
=C2=A0 char expected2[] =3D "ino=3D" INODE_F;</div><div>=C2=A0 st=
d::cin >> expected1; // read, check, and discard characters</div><div=
>=C2=A0 std::cin >> expected2; // read characters *into* expected2.</=
div>
<div>}</div><div><br></div><div>Perhaps some kind of wrapper would help?</d=
iv><div><br></div><div>struct expected { expected(const char *); const char=
*text; };</div><div>std::istream &operator>>(std::istream &s=
tream, expected);</div>
<div>// ...</div><div>std::cin >> expected(expected1) >> expect=
ed(expected2);</div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr">
Shachar<br><br>1 - <a href=3D"http://sourceforge.net/p/fakerootng/source/ci=
/0.18/tree/file_lie.cpp#l67" target=3D"_blank">http://sourceforge.net/p/fak=
erootng/source/ci/0.18/tree/file_lie.cpp#l67</a><br>2 - <a href=3D"http://s=
ourceforge.net/p/fakerootng/source/ci/multithreaded_debugger/tree/file_lie.=
cpp#l162" target=3D"_blank">http://sourceforge.net/p/fakerootng/source/ci/m=
ultithreaded_debugger/tree/file_lie.cpp#l162</a><span class=3D"HOEnZb"><fon=
t color=3D"#888888"><br>
</font></span></div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b3a925008ae3504f8984e69--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sun, 4 May 2014 22:23:37 +0200
Raw View
How about a new member template function `scan` in std::istream:
struct std::istream
{
template <typename... Args>
void scan(const char* format, Args&&... args) { ...}
}
Usage:
std::istream& file = ...;
file.scan("dev=%1, ino=%2, mode=%3, uid=%4, giud=%5, rdev=%6\n",
override.dev, override.inode,
override.mode, override.uid, override.gid, override.dev_id);
On Sun, May 4, 2014 at 9:48 PM, Richard Smith <richard@metafoo.co.uk> wrote:
> On Sun, May 4, 2014 at 11:14 AM, <shachar@lingnu.com> wrote:
>>
>> std::istream is supposed to replace C's scanf. Unfortunately, it lacks
>> power in two respects, making it much much much less useful.
>>
>> The first respect, and one not addressed with this idea, is that scanf
>> returns the number of arguments successfully parsed. istream only has a
>> boolean meaning whether ALL arguments were successfully parsed or not.
>> Frankly, for my particular use cases, this is less of an issue.
>>
>> The second respect is that scanf allows specifying characters to appear
>> verbatim in the input sequence, to be consumed by scanf. Please consider my
>> open source program, fakeroot-ng. It stores a state file that has the
>> following syntax:
>> dev=fe07,ino=6074857,mode=100644,uid=0,gid=1000,rdev=0
>>
>> Reading it in is done with the following line[1]:
>>
>> while( (params=fscanf(file, "dev=" DEV_F ", ino=" INODE_F ", mode=%o,
>> uid=%d, gid=%d, rdev=" DEV_F " \n", &override.dev, &override.inode,
>> &override.mode, &override.uid, &override.gid, &override.dev_id
>> ))==6 )
>>
>>
>> It seems C++ has no reasonable alternatives.
>>
>> I suggest the following three functions should be added to the standard
>> library:
>>
>> std::istream &operator>>( std::istream &stream, const char &chr );
>> std::istream &operator>>( std::istream &stream, const char *string );
>> std::istream &operator>>( std::istream &stream, const std::string &string
>> );
>>
>> Each one will consume the relevant characters from the input stream,
>> setting fail (or throwing, if so configured) in case the characters don't
>> match. If the stream is set to ignore white spaces, the last two overloads
>> should also ignore white spaces in their input.
>>
>> This makes simple parsing sane again on C++[2].
>>
>> Feedback welcome,
>
>
> This makes the overload set for operator>> rather scary.
>
> void f() {
> const char expected1[] = "dev=" DEV_F;
> char expected2[] = "ino=" INODE_F;
> std::cin >> expected1; // read, check, and discard characters
> std::cin >> expected2; // read characters *into* expected2.
> }
>
> Perhaps some kind of wrapper would help?
>
> struct expected { expected(const char *); const char *text; };
> std::istream &operator>>(std::istream &stream, expected);
> // ...
> std::cin >> expected(expected1) >> expected(expected2);
>
>> Shachar
>>
>> 1 -
>> http://sourceforge.net/p/fakerootng/source/ci/0.18/tree/file_lie.cpp#l67
>> 2 -
>> http://sourceforge.net/p/fakerootng/source/ci/multithreaded_debugger/tree/file_lie.cpp#l162
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Shachar Shemesh <shachar@lingnu.com>
Date: Sun, 04 May 2014 23:29:36 +0300
Raw View
This is a multi-part message in MIME format.
--------------030505070801070409030902
Content-Type: text/plain; charset=UTF-8
On 04/05/14 23:23, Andrew Tomazos wrote:
> How about a new member template function `scan` in std::istream:
>
> struct std::istream
> {
> template <typename... Args>
> void scan(const char* format, Args&&... args) { ...}
Why would you need the format? Also, what happens if the format and the
arguments don't match?
You can just do one argument after the other, but then you go back to
Richard's original objection.
Personally, I think this objection is not a big problem. If the
situation was reversed, where we were adding an overload that changed a
variable where previously it was const, I'd be more concerned. This way,
the likely scenario is that the stream will get a fail due to input
mismatching, and no corruption takes place. Hardly a doomsday scenario.
Shachar
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--------------030505070801070409030902
Content-Type: text/html; charset=UTF-8
<html style="direction: ltr;">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<style type="text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt; } </style>
</head>
<body style="direction: ltr;"
bidimailui-detected-decoding-type="UTF-8" bgcolor="#FFFFFF"
text="#000000">
<div class="moz-cite-prefix">On 04/05/14 23:23, Andrew Tomazos
wrote:<br>
</div>
<blockquote
cite="mid:CAB+4KHJPXma+LMqnrfrirf93HObavjnxU5bOaqseE27v+YOFNw@mail.gmail.com"
type="cite">
<pre wrap="">How about a new member template function `scan` in std::istream:
struct std::istream
{
template <typename... Args>
void scan(const char* format, Args&&... args) { ...}</pre>
</blockquote>
Why would you need the format? Also, what happens if the format and
the arguments don't match?<br>
<br>
You can just do one argument after the other, but then you go back
to Richard's original objection.<br>
<br>
Personally, I think this objection is not a big problem. If the
situation was reversed, where we were adding an overload that
changed a variable where previously it was const, I'd be more
concerned. This way, the likely scenario is that the stream will get
a fail due to input mismatching, and no corruption takes place.
Hardly a doomsday scenario.<br>
<br>
Shachar<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--------------030505070801070409030902--
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Sun, 4 May 2014 22:41:07 +0200
Raw View
On Sun, May 4, 2014 at 10:29 PM, Shachar Shemesh <shachar@lingnu.com> wrote:
> On 04/05/14 23:23, Andrew Tomazos wrote:
>
> How about a new member template function `scan` in std::istream:
>
> struct std::istream
> {
> template <typename... Args>
> void scan(const char* format, Args&&... args) { ...}
>
> Why would you need the format? Also, what happens if the format and the
> arguments don't match?
What do you mean "don't match"? The arguments are denoted
positionaly in the format string. The types are deduced by the
varadic template and then the correct operator>> overload is called
for each parameter. Normal text in the format is "expected" out like
you want. Error handling hasn't been considered - either a return
value or a thrown exception on error.
I just think that:
file.scan("dev=%1, ino=%2, mode=%3, uid=%4, giud=%5, rdev=%6\n",
override.dev, override.inode, override.mode,
override.uid, override.gid, override.dev_id);
looks a hell of a lot better than:
file >> expected("dev =") >> override.dev >> expected(", ino =")
>> override.inode >> expected(", mode="), >> override.mode >>
expected(", uid=") >> expected(", giud=") >> override.gid >>
expected("rdev =") >> override.dev_id >> expected("\n");
but maybe it's just me. :)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Dietmar Kuhl <dietmar.kuehl@me.com>
Date: Sun, 04 May 2014 22:41:49 +0200
Raw View
--Boundary_(ID_wxSrT7QdBgnwd17i/GRuUA)
Content-type: text/plain; charset=ISO-8859-1
Content-transfer-encoding: quoted-printable
On 4 May 2014, at 21:48, Richard Smith <richard@metafoo.co.uk> wrote:
>=20
> On Sun, May 4, 2014 at 11:14 AM, <shachar@lingnu.com> wrote:
> std::istream is supposed to replace C's scanf. Unfortunately, it lacks po=
wer in two respects, making it much much much less useful.
>=20
> The first respect, and one not addressed with this idea, is that scanf re=
turns the number of arguments successfully parsed. istream only has a boole=
an meaning whether ALL arguments were successfully parsed or not. Frankly, =
for my particular use cases, this is less of an issue.
>=20
> The second respect is that scanf allows specifying characters to appear v=
erbatim in the input sequence, to be consumed by scanf. Please consider my =
open source program, fakeroot-ng. It stores a state file that has the follo=
wing syntax:
> dev=3Dfe07,ino=3D6074857,mode=3D100644,uid=3D0,gid=3D1000,rdev=3D0
>=20
> Reading it in is done with the following line[1]:
> while( (params=3Dfscanf(file, "dev=3D" DEV_F ", ino=3D" INODE_F ", mo=
de=3D%o, uid=3D%d, gid=3D%d, rdev=3D" DEV_F " \n", &override.dev, &override=
..inode,
> &override.mode, &override.uid, &override.gid, &override.dev_i=
d ))=3D=3D6 )
>=20
> It seems C++ has no reasonable alternatives.
>=20
> I suggest the following three functions should be added to the standard l=
ibrary:
>=20
> std::istream &operator>>( std::istream &stream, const char &chr );
> std::istream &operator>>( std::istream &stream, const char *string );
> std::istream &operator>>( std::istream &stream, const std::string &string=
);
>=20
> Each one will consume the relevant characters from the input stream, sett=
ing fail (or throwing, if so configured) in case the characters don't match=
.. If the stream is set to ignore white spaces, the last two overloads shoul=
d also ignore white spaces in their input.
>=20
> This makes simple parsing sane again on C++[2].
>=20
> Feedback welcome,
>=20
> This makes the overload set for operator>> rather scary.
>=20
> void f() {
> const char expected1[] =3D "dev=3D" DEV_F;
> char expected2[] =3D "ino=3D" INODE_F;
> std::cin >> expected1; // read, check, and discard characters
> std::cin >> expected2; // read characters *into* expected2.
> }
>=20
> Perhaps some kind of wrapper would help?
>=20
> struct expected { expected(const char *); const char *text; };
> std::istream &operator>>(std::istream &stream, expected);
> // ...
> std::cin >> expected(expected1) >> expected(expected2);
I definitely agree with Richard: the distinction between const and non-cons=
t types is far too subtle to use it as a distinction on whether data should=
be skipped or read. I had implemented that at some point as an extension a=
nd found that it picks up unexpected overloads quite frequently. More impor=
tantly, introducing these overloads may break existing code, e.g., because =
no more conversions could be viable creating an ambiguity for currently una=
mbiguous code.
Using a suitable class like expected mentioned above make the distinction b=
latantly obvious and I'm using types like the one proposed by Richard (alth=
ough I'm normally calling it "expect"). To make the use of a suitable class=
a bit easier, the corresponding objects can be created easily using suitab=
le user defined literals:
std::cin >> foo >> "=3D"exp >> bar;
While I think the addition of corresponding classes and literals may be rea=
sonable I don't think using overloads to distinguish between reading and sk=
ipping based on constness is reasonable.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Boundary_(ID_wxSrT7QdBgnwd17i/GRuUA)
Content-type: text/html; charset=ISO-8859-1
Content-transfer-encoding: quoted-printable
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dus-ascii"><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dus-ascii"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode=
: space; -webkit-line-break: after-white-space;">On 4 May 2014, at 21:48, R=
ichard Smith <<a href=3D"mailto:richard@metafoo.co.uk">richard@metafoo.c=
o.uk</a>> wrote:<br><div><blockquote type=3D"cite"><br class=3D"Apple-in=
terchange-newline"><div><div dir=3D"ltr"><div class=3D"gmail_extra"><div cl=
ass=3D"gmail_quote">On Sun, May 4, 2014 at 11:14 AM, <span dir=3D"ltr"><=
;<a href=3D"mailto:shachar@lingnu.com" target=3D"_blank">shachar@lingnu.com=
</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 20=
4, 204); border-left-style: solid; padding-left: 1ex; position: static; z-i=
ndex: auto;">
<div dir=3D"ltr">std::istream is supposed to replace C's scanf. Unfortunate=
ly, it lacks power in two respects, making it much much much less useful.<b=
r><br>The first respect, and one not addressed with this idea, is that scan=
f returns the number of arguments successfully parsed. istream only has a b=
oolean meaning whether ALL arguments were successfully parsed or not. Frank=
ly, for my particular use cases, this is less of an issue.<br>
<br>The second respect is that scanf allows specifying characters to appear=
verbatim in the input sequence, to be consumed by scanf. Please consider m=
y open source program, fakeroot-ng. It stores a state file that has the fol=
lowing syntax:<br>
dev=3Dfe07,ino=3D6074857,mode=3D100644,uid=3D0,gid=3D1000,rdev=3D0<br><br>R=
eading it in is done with the following line[1]:<br><pre><div style=3D"back=
ground-color:rgb(255,255,153)"> <span>while</span><span>(</span> <span>(=
</span><span>params</span><span>=3D</span><span>fscanf</span><span>(</span>=
<span>file</span><span>,</span> <span>"dev=3D"</span> <span>DEV_F</span> <s=
pan>", ino=3D"</span> <span>INODE_F</span> <span>", mode=3D%o, uid=3D%d, gi=
d=3D%d, rdev=3D"</span> <span>DEV_F</span> <span>" </span><span>\n</span><s=
pan>"</span><span>,</span> <span>&</span><span>override</span><span>.</=
span><span>dev</span><span>,</span> <span>&</span><span>override</span>=
<span>.</span><span>inode</span><span>,</span>
</div><div> <span>&</span><span>override</span><span>.</span=
><span>mode</span><span>,</span> <span>&</span><span>override</span><sp=
an>.</span><span>uid</span><span>,</span> <span>&</span><span>override<=
/span><span>.</span><span>gid</span><span>,</span> <span>&</span><span>=
override</span><span>.</span><span>dev_id</span> <span>))</span><span>=3D=
=3D</span><span>6</span> <span>)</span>
</div></pre><br>It seems C++ has no reasonable alternatives.<br><br>I sugge=
st the following three functions should be added to the standard library:<b=
r><br><pre><div><span>std</span><span>::</span><span>istream</span> <span>&=
amp;</span><span>operator</span><span>>></span><span>(</span> <span>s=
td</span><span>::</span><span>istream</span> <span>&</span><span>stream=
</span><span>,</span> <span>const</span> <span>char</span> <span>&</spa=
n><span>chr</span> <span>);</span>
</div><div><span>std</span><span>::</span><span>istream</span> <span>&<=
/span><span>operator</span><span>>></span><span>(</span> <span>std</s=
pan><span>::</span><span>istream</span> <span>&</span><span>stream</spa=
n><span>,</span> <span>const</span> <span>char</span> <span>*</span><span>s=
tring</span> <span>);</span>
</div><div><span>std</span><span>::</span><span>istream</span> <span>&<=
/span><span>operator</span><span>>></span><span>(</span> <span>std</s=
pan><span>::</span><span>istream</span> <span>&</span><span>stream</spa=
n><span>,</span> <span>const</span> <span>std</span><span>::</span><span>st=
ring</span> <span>&</span><span>string</span> <span>);</span>
</div><div>
</div></pre>Each one will consume the relevant characters from the input st=
ream, setting fail (or throwing, if so configured) in case the characters d=
on't match. If the stream is set to ignore white spaces, the last two overl=
oads should also ignore white spaces in their input.<br>
<br>This makes simple parsing sane again on C++[2].<br><br>Feedback welcome=
,<br></div></blockquote><div><br></div><div>This makes the overload set for=
operator>> rather scary.</div><div><br></div><div>void f() {</div>
<div> const char expected1[] =3D "dev=3D" DEV_F;</div><div> cha=
r expected2[] =3D "ino=3D" INODE_F;</div><div> std::cin >> expe=
cted1; // read, check, and discard characters</div><div> std::cin >=
;> expected2; // read characters *into* expected2.</div>
<div>}</div><div><br></div><div>Perhaps some kind of wrapper would help?</d=
iv><div><br></div><div>struct expected { expected(const char *); const char=
*text; };</div><div>std::istream &operator>>(std::istream &s=
tream, expected);</div>
<div>// ...</div><div>std::cin >> expected(expected1) >> expect=
ed(expected2);</div></div></div></div></div></blockquote></div><br><div>I d=
efinitely agree with Richard: the distinction between const and non-const t=
ypes is far too subtle to use it as a distinction on whether data should be=
skipped or read. I had implemented that at some point as an extension and =
found that it picks up unexpected overloads quite frequently. More importan=
tly, introducing these overloads may break existing code, e.g., because no =
more conversions could be viable creating an ambiguity for currently unambi=
guous code.</div><div><br></div><div>Using a suitable class like expected m=
entioned above make the distinction blatantly obvious and I'm using types l=
ike the one proposed by Richard (although I'm normally calling it "expect")=
.. To make the use of a suitable class a bit easier, the corresponding objec=
ts can be created easily using suitable user defined literals:</div><div><b=
r></div><div> std::cin >> foo >> "=3D"exp >>=
bar;</div><div><br></div><div>While I think the addition of corresponding =
classes and literals may be reasonable I don't think using overloads to dis=
tinguish between reading and skipping based on constness is reasonable.</di=
v></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Boundary_(ID_wxSrT7QdBgnwd17i/GRuUA)--
.
Author: Shachar Shemesh <shachar@lingnu.com>
Date: Mon, 05 May 2014 07:49:07 +0300
Raw View
This is a multi-part message in MIME format.
--------------080206050509070700050105
Content-Type: text/plain; charset=UTF-8
On 04/05/14 23:41, Dietmar Kuhl wrote:
>
> I definitely agree with Richard: the distinction between const and
> non-const types is far too subtle to use it as a distinction on
> whether data should be skipped or read. I had implemented that at some
> point as an extension and found that it picks up unexpected overloads
> quite frequently.
Can you, please, give an example of such a thing. This goes counter to
my intuition of the language. The thing I liked most about this proposal
is that it narrowly picked cases that would simply not compile before,
without overstepping any existing code. I would love to see an example
for where this is not the case.
> More importantly, introducing these overloads may break existing code,
> e.g., because no more conversions could be viable creating an
> ambiguity for currently unambiguous code.
Again, examples would be welcome. I don't see it.
Shachar
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--------------080206050509070700050105
Content-Type: text/html; charset=UTF-8
<html style="direction: ltr;">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<style type="text/css">body p { margin-bottom: 0.2cm; margin-top: 0pt; } </style>
</head>
<body style="direction: ltr;"
bidimailui-detected-decoding-type="UTF-8" bgcolor="#FFFFFF"
text="#000000">
<div class="moz-cite-prefix">On 04/05/14 23:41, Dietmar Kuhl wrote:<br>
</div>
<blockquote cite="mid:D241994E-0D25-4AA1-9E44-311E0CEFBB8A@me.com"
type="cite">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<br>
<div>I definitely agree with Richard: the distinction between
const and non-const types is far too subtle to use it as a
distinction on whether data should be skipped or read. I had
implemented that at some point as an extension and found that it
picks up unexpected overloads quite frequently.</div>
</blockquote>
Can you, please, give an example of such a thing. This goes counter
to my intuition of the language. The thing I liked most about this
proposal is that it narrowly picked cases that would simply not
compile before, without overstepping any existing code. I would love
to see an example for where this is not the case.<br>
<blockquote cite="mid:D241994E-0D25-4AA1-9E44-311E0CEFBB8A@me.com"
type="cite">
<div> More importantly, introducing these overloads may break
existing code, e.g., because no more conversions could be viable
creating an ambiguity for currently unambiguous code.</div>
</blockquote>
Again, examples would be welcome. I don't see it.<br>
<br>
Shachar<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--------------080206050509070700050105--
.