By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,484 Members | 1,568 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,484 IT Pros & Developers. It's quick & easy.

stream input

P: n/a
Hi folks,
I am well aware of the superiority of using streams and operators << / >>
instead of the old-style printf and scanf. However, there is only one
obstacle that prevents me from switching to the better form.
scanf has the following really convenient syntax:

fscanf(pFile, "prfl num: %d\n", &nPrflNum);
The convenient part about it is that it's almost an exact copy of the
fprintf operation that created the input. In particular it allows to skip
over a particular text by just writing what it is.

It seems to be very difficult to replace this with a convenient input stream
version, such as:
input>>"prfl num: ">>nPrflNum;

This code turns out to be illegal, because the input stream class doesn't
know how to input constant strings. The workaround I know for this is quite
cumbersome, involving reading characters one by one, and verifying if they
fit the pattern "prfl num: ", or ignoring everything until a numeric
character is found in the stream.

Is there a more straightforward / painless way to do what I want?

Cheers,
Aleks D.

Jul 22 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a

"Aleks Dubinskiy" <ad@imm.dtu.dk> wrote in message
news:cg**********@news.net.uni-c.dk...
Hi folks,
I am well aware of the superiority of using streams and operators << / >>
instead of the old-style printf and scanf. However, there is only one
obstacle that prevents me from switching to the better form.
scanf has the following really convenient syntax:

fscanf(pFile, "prfl num: %d\n", &nPrflNum);
The convenient part about it is that it's almost an exact copy of the
fprintf operation that created the input. In particular it allows to skip
over a particular text by just writing what it is.

It seems to be very difficult to replace this with a convenient input stream version, such as:
input>>"prfl num: ">>nPrflNum;

This code turns out to be illegal, because the input stream class doesn't
know how to input constant strings. The workaround I know for this is quite cumbersome, involving reading characters one by one, and verifying if they
fit the pattern "prfl num: ", or ignoring everything until a numeric
character is found in the stream.

Is there a more straightforward / painless way to do what I want?

Cheers,
Aleks D.
std::ifstream input;
std::string s;
int num(0);
/* etc */
std::getline(input, s);
if(s == "prfl num: ")
input >> num;

-Mike

Jul 22 '05 #2

P: n/a
Aleks Dubinskiy wrote:
Hi folks,
I am well aware of the superiority of using streams and operators << / >>
instead of the old-style printf and scanf. However, there is only one
obstacle that prevents me from switching to the better form.
scanf has the following really convenient syntax:

fscanf(pFile, "prfl num: %d\n", &nPrflNum);
The convenient part about it is that it's almost an exact copy of the
fprintf operation that created the input. In particular it allows to skip
over a particular text by just writing what it is.

It seems to be very difficult to replace this with a convenient input stream
version, such as:
input>>"prfl num: ">>nPrflNum;

This code turns out to be illegal, because the input stream class doesn't
know how to input constant strings. The workaround I know for this is quite
cumbersome, involving reading characters one by one, and verifying if they
fit the pattern "prfl num: ", or ignoring everything until a numeric
character is found in the stream.

Is there a more straightforward / painless way to do what I want?

Probably something in line with

template<class S> S& skipover(S& s, const char* str) {
return s.seekg(fpos(strlen(str), S::cur);
}
...
skipover(input, "prfl num: ") >> nPrflNum;

I am sure folks will correct me where I erred.

V
Jul 22 '05 #3

P: n/a
Mike Wahler wrote:
"Aleks Dubinskiy" <ad@imm.dtu.dk> wrote in message
news:cg**********@news.net.uni-c.dk...
Hi folks,
I am well aware of the superiority of using streams and operators << / >>
instead of the old-style printf and scanf. However, there is only one
obstacle that prevents me from switching to the better form.
scanf has the following really convenient syntax:

fscanf(pFile, "prfl num: %d\n", &nPrflNum);
The convenient part about it is that it's almost an exact copy of the
fprintf operation that created the input. In particular it allows to skip
over a particular text by just writing what it is.

It seems to be very difficult to replace this with a convenient input


stream
version, such as:
input>>"prfl num: ">>nPrflNum;

This code turns out to be illegal, because the input stream class doesn't
know how to input constant strings. The workaround I know for this is


quite
cumbersome, involving reading characters one by one, and verifying if they
fit the pattern "prfl num: ", or ignoring everything until a numeric
character is found in the stream.

Is there a more straightforward / painless way to do what I want?

Cheers,
Aleks D.

std::ifstream input;
std::string s;
int num(0);
/* etc */
std::getline(input, s);
if(s == "prfl num: ")
input >> num;


I am not sure how it would help to read the integer in a line like

prfl num: 42

(which was printed by the symmetrical statement

of << "prfl num: " << some_int_with_value_42 << std::endl;
}

Wouldn't 'getline' skip over the number and read until the end of line
thus losing the "42"?

Victor
Jul 22 '05 #4

P: n/a
Aleks Dubinskiy wrote in news:cg**********@news.net.uni-c.dk in
comp.lang.c++:
Hi folks,
I am well aware of the superiority of using streams and operators << /
instead of the old-style printf and scanf. However, there is only

one obstacle that prevents me from switching to the better form.
scanf has the following really convenient syntax:

fscanf(pFile, "prfl num: %d\n", &nPrflNum);
The convenient part about it is that it's almost an exact copy of the
fprintf operation that created the input. In particular it allows to
skip over a particular text by just writing what it is.

It seems to be very difficult to replace this with a convenient input
stream version, such as:
input>>"prfl num: ">>nPrflNum;

This code turns out to be illegal, because the input stream class
doesn't know how to input constant strings. The workaround I know for
this is quite cumbersome, involving reading characters one by one, and
verifying if they fit the pattern "prfl num: ", or ignoring everything
until a numeric character is found in the stream.

Is there a more straightforward / painless way to do what I want?


I'm sure there are problems with it, but hopefully it will
get you started:

#include <iostream>
#include <ostream>
#include <istream>
#include <sstream>
#include <string>

template < typename Ch >
struct matcher
{
Ch const *m_to;
matcher( Ch const *s ) : m_to( s ) {}
};

template < typename Ch, typename Tr >
std::basic_istream< Ch, Tr > &operator >> (
std::basic_istream< Ch, Tr > &is, matcher< Ch > const &m
)
{
std::istringstream iss( m.m_to );

std::string get, got;

while (iss >> get)
{
if ( !(is >> got) ) return is;
if ( get != got )
{
is.setstate( std::ios::failbit );
return is;
}
}

return is;
}

template < typename Ch >
inline matcher< Ch > match( Ch const *s )
{
return matcher< Ch >( s );
}
int main()
{
std::stringstream ss;
int i = 10, j = -1;

ss << "i: " << i << '\n';

ss >> match( "i: " ) >> j;

std::cout << j << '\n';

ss.clear();

ss.str( "i : 2" );

if ( ss >> match( "i: " ) )
{
ss >> j;
}
else
{
std::cout << "input didn't match\n";
}
}
Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #5

P: n/a
Aleks Dubinskiy wrote:
fscanf(pFile, "prfl num: %d\n", &nPrflNum);
The convenient part about it is that it's almost an exact copy of the
fprintf operation that created the input. In particular it allows to skip
over a particular text by just writing what it is.

It seems to be very difficult to replace this with a convenient input
stream version, such as:
input>>"prfl num: ">>nPrflNum;


Something like that can do the work:

#include <istream>
#include <string>

class Literal {
public:
Literal (const std::string & nstr) :
str (nstr)
{ }
friend std::istream & operator >>
(std::istream & is, const Literal & lit);
private:
std::string str;
};

std::istream & operator >> (std::istream & is, const Literal & lit)
{
for (std::string::size_type i= 0; i < lit.str.size (); ++i)
{
char c= is.get ();
if (! is)
break;
if (c != lit.str [i] )
{
is.unget ();
is.clear (std::ios::badbit);
break;
}
}
return is;
}

Little test:

#include <iostream>
#include "literal.h"

int main ()
{
int i;
std::cin >> Literal ("Hello ") >> i;
std::cout << i << std::endl;
}

--
Salu2
Jul 22 '05 #6

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:DI**************@newsread1.dllstx09.us.to.ver io.net...
Mike Wahler wrote:
"Aleks Dubinskiy" <ad@imm.dtu.dk> wrote in message
news:cg**********@news.net.uni-c.dk...
Hi folks,
I am well aware of the superiority of using streams and operators << /

instead of the old-style printf and scanf. However, there is only one
obstacle that prevents me from switching to the better form.
scanf has the following really convenient syntax:

fscanf(pFile, "prfl num: %d\n", &nPrflNum);
The convenient part about it is that it's almost an exact copy of the
fprintf operation that created the input. In particular it allows to skipover a particular text by just writing what it is.

It seems to be very difficult to replace this with a convenient input


stream
version, such as:
input>>"prfl num: ">>nPrflNum;

This code turns out to be illegal, because the input stream class doesn'tknow how to input constant strings. The workaround I know for this is


quite
cumbersome, involving reading characters one by one, and verifying if theyfit the pattern "prfl num: ", or ignoring everything until a numeric
character is found in the stream.

Is there a more straightforward / painless way to do what I want?

Cheers,
Aleks D.

std::ifstream input;
std::string s;
int num(0);
/* etc */
std::getline(input, s);
if(s == "prfl num: ")
input >> num;


I am not sure how it would help to read the integer in a line like

prfl num: 42

(which was printed by the symmetrical statement

of << "prfl num: " << some_int_with_value_42 << std::endl;
}

Wouldn't 'getline' skip over the number and read until the end of line
thus losing the "42"?


Yes, I totally fouled that one up. Thanks for noticing. :-)

std::getline(input, s, ':');
if(s == "prfl num")
/* etc */

-Mike
Jul 22 '05 #7

P: n/a
On 24 Aug 2004 08:22:48 -0700, "Dietmar Kuehl"
<di***********@yahoo.com> wrote:
std::cin >> expect("expect: ") >> whatever;


Dietmar, any chance of you proposing something like this for
standardization? The lack of ability to match the fscanf feature-set
is definitely an embarrassment of iostreams. And <iomanip> is a bit
bare at the moment...

Tom
Jul 22 '05 #8

P: n/a
tom_usenet wrote:
On 24 Aug 2004 08:22:48 -0700, "Dietmar Kuehl"
<di***********@yahoo.com> wrote:
std::cin >> expect("expect: ") >> whatever;


Dietmar, any chance of you proposing something like this for
standardization?


I hacked this up in less than five minutes and it was only about
the second or third time I ever needed it. Actually, I don't
think I have ever used something like this in any production code.
Thus: is this something really needed?

Personally, I'm not that interested in doing micro-proposals like
this for the IOStreams library: if there is something to propose,
it would be a general overhaul of the IOStreams library. But I don't
even see much point in this: persistance is done through data bases,
user interaction through GUIs, and the remaining debug output (this
is nearly the exclusive use I have myself for IOStreams in production
code) or input from files is already reasonably handled. It would be
much more reasonable to concentrate e.g. on XML support of C++.

However, support for something like the "expect" manipulator mentioned
here my be a reasonable but small contribution to Boost which may
make it into a proposal for extensions to the IOStreams library.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
Jul 22 '05 #9

P: n/a
> I hacked this up in less than five minutes and it was only about
the second or third time I ever needed it. Actually, I don't
think I have ever used something like this in any production code.
Thus: is this something really needed?

Personally, I'm not that interested in doing micro-proposals like
this for the IOStreams library: if there is something to propose,
it would be a general overhaul of the IOStreams library. But I don't
even see much point in this: persistance is done through data bases,
user interaction through GUIs, and the remaining debug output (this
is nearly the exclusive use I have myself for IOStreams in production
code) or input from files is already reasonably handled. It would be
much more reasonable to concentrate e.g. on XML support of C++.

However, support for something like the "expect" manipulator mentioned
here my be a reasonable but small contribution to Boost which may
make it into a proposal for extensions to the IOStreams library.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting


Thanks for the suggestion, Dietmar - this is exactly what i was looking for.
While the code is not incredibly difficult, it is still serious and
unnecessary micro-management.
I think a lot of people would benefit from this feature in C++, especially a
portable one!

Cheers,
Aleks
Jul 22 '05 #10

P: n/a
"Aleks Dubinskiy" <ad@imm.dtu.dk> wrote:
Hi folks,
I am well aware of the superiority of using streams and operators << / >>
instead of the old-style printf and scanf. However, there is only one
obstacle that prevents me from switching to the better form.
scanf has the following really convenient syntax:
fscanf(pFile, "prfl num: %d\n", &nPrflNum);
It seems to be very difficult to replace this with a convenient input stream
version, such as:
input>>"prfl num: ">>nPrflNum;

Is there a more straightforward / painless way to do what I want?


You could use the very flexible Boost Spirit library (www.boost.org)
(warning - late-model compiler required):

#include <iostream>
#include <string>
#include "boost/spirit/core.hpp"

using namespace boost::spirit;

int main()
{
std::string s;
int i;

getline(std::cin, s);

if (parse(s.c_str(), "prfl num:" >> int_p[assign_a(i)], space_p).full)
std::cout << "input was: " << i << "\n";
else
std::cout << "input did not match expected form.\n";

return 0;
}

"int_p" indicates to parse a signed int, "[assign_a(i)]" means to
assign the result of parsing to the variable "i", "space_p"
indicates that whitespace is used to separate tokens in the input,
"full" means that the entire input was parsed correctly.
Jul 22 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.