Connecting Tech Pros Worldwide Forums | Help | Site Map

C++ istringstream problem

James Aguilar
Guest
 
Posts: n/a
#1: Jul 23 '05
Hello all,

I am trying to use an istringstream to do some input off of cin by lines.
The following snippet does not work:

char buf[90];
cin.getline(buf, 90);

istringstream line1(string(buf));

cin.getline(buf, 90);
istringstream line2(string(buf));

ChainOfExpressions line1chn;
ChainOfExpressions line2chn;

line1 >> line1chn;
line2 >> line2chn;

I have defined an extraction operator on istream and ChainOfExpressions.
Here is the prototype:

istream &operator >>(istream &strm, ChainOfExpressions &chain);

I get this error when I try to compile:

errantphysicist.cpp:310: error: no match for 'operator>>' in 'line1 >>
line1chn'
errantphysicist.cpp:159: error: candidates are: std::istream&
operator>>(std::istream&, Expression&)
errantphysicist.cpp:269: error: std::istream&
operator>>(std::istream&, ChainOfExpressions&)

I think the problem is that istringstream is not being converted to istream.
However, I thought that istringstream was a child of istream. What is my
problem here?

- JFA1



Victor Bazarov
Guest
 
Posts: n/a
#2: Jul 23 '05

re: C++ istringstream problem


James Aguilar wrote:[color=blue]
> I am trying to use an istringstream to do some input off of cin by lines.
> The following snippet does not work:
>
> char buf[90];
> cin.getline(buf, 90);
>
> istringstream line1(string(buf));
>
> cin.getline(buf, 90);
> istringstream line2(string(buf));
>
> ChainOfExpressions line1chn;
> ChainOfExpressions line2chn;
>
> line1 >> line1chn;
> line2 >> line2chn;
>
> I have defined an extraction operator on istream and ChainOfExpressions.
> Here is the prototype:
>
> istream &operator >>(istream &strm, ChainOfExpressions &chain);
>
> I get this error when I try to compile:
>
> errantphysicist.cpp:310: error: no match for 'operator>>' in 'line1 >>
> line1chn'
> errantphysicist.cpp:159: error: candidates are: std::istream&
> operator>>(std::istream&, Expression&)
> errantphysicist.cpp:269: error: std::istream&
> operator>>(std::istream&, ChainOfExpressions&)
>
> I think the problem is that istringstream is not being converted to istream.
> However, I thought that istringstream was a child of istream. What is my
> problem here?[/color]

I think FAQ 5.8 should be of some help.

V
James Aguilar
Guest
 
Posts: n/a
#3: Jul 23 '05

re: C++ istringstream problem



"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:jeXCd.34569$NC6.33349@newsread1.mlpsca01.us.t o.verio.net...[color=blue]
>
> I think FAQ 5.8 should be of some help.[/color]

OK then. Naturally, it is not compilable because of the error I mentioned
before, but this is what I have:

** CODE BEGINS **

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>

using namespace std;

string &stringToSpaces(string &toSpaces);
string intToString(int from);

class AddingException {};

class Expression
{
public:
Expression();
Expression(int coeff, int xDegree, int yDegree);
Expression(const Expression &other);

Expression operator *(const Expression &other) const;
void operator +=(const Expression &other);

bool sameDegrees(const Expression &other) const;

string topLine() const;
string bottomLine() const;

bool operator <(const Expression &other) const;

friend istream &operator >>(istream &strm, Expression &expr);
private:
int m_coeff, m_xDegree, m_yDegree;
};

Expression::Expression()
: m_coeff(0), m_xDegree(0), m_yDegree(0)
{}

Expression::Expression(int coeff, int xDegree, int yDegree)
: m_coeff(coeff), m_xDegree(xDegree), m_yDegree(yDegree)
{}

Expression::Expression(const Expression &other)
: m_coeff(other.m_coeff), m_xDegree(other.m_xDegree),
m_yDegree(other.m_yDegree)
{}

Expression Expression::operator *(const Expression &other) const
{
return Expression(m_coeff * other.m_coeff,
m_xDegree * other.m_xDegree,
m_yDegree * other.m_yDegree);
}

void Expression::operator +=(const Expression &other)
{
if (sameDegrees(other))
m_coeff += other.m_coeff;
else
throw AddingException();
}

bool Expression::operator <(const Expression &other) const
{
if (m_xDegree == other.m_xDegree)
return (m_yDegree < other.m_yDegree);
else return (m_xDegree > other.m_xDegree);
}

bool Expression::sameDegrees(const Expression &other) const
{
return (m_xDegree == other.m_xDegree) && (m_yDegree == other.m_yDegree);
}

string Expression::topLine() const
{
//0: Don't print anything if multiplied by zero
if (m_coeff == 0)
return "";

string retVal;

//1: Make a string out of the coefficient
if (m_coeff > 1 || m_coeff < -1 || (m_xDegree == 0 && m_yDegree == 0))
retVal += intToString((int) abs(m_coeff));

//2: Prepare the coefficient section
//2.1: Change all of those elements into spaces
stringToSpaces(retVal);
//2.2: Add two spaces that correspond to the operator and the space after
it
retVal += " ";

//3: Display the xDegree
//3.1: If the xDegree is greater than zero, add a space for the x
if (m_xDegree > 0)
retVal += ' ';
//3.2: If the xDegree is greater than 1, print it out
if (m_xDegree > 1)
retVal += intToString(m_xDegree);

//4: Display the yDegree
//4.1: If the yDegree is greater than zero, add a space for the y
if (m_yDegree > 0)
retVal += ' ';
//4.2: if the yDegree is greater than 1, print it out
if (m_yDegree > 1)
retVal += intToString(m_yDegree);

//5: Add the trailing space
retVal += ' ';

return retVal;
}

string Expression::bottomLine() const
{
if (m_coeff == 0)
return "";

string retVal;

//1: add the addition or subtraction sign
retVal += (m_coeff < 0) ? "- " : "+ ";

//2: Prepare the coefficient section
if (m_coeff > 1 || m_coeff < -1 || (m_xDegree == 0 && m_yDegree == 0))
retVal += intToString((int) abs(m_coeff));

//3: Display the xDegree
//3.1: If the xDegree is greater than zero, add the x
if (m_xDegree > 0)
retVal += 'x';
//3.2: If the xDegree is greater than 1, print out spaces for it
if (m_xDegree > 1) {
string rep(intToString(m_xDegree));
retVal += stringToSpaces(rep);
}

//4: Display the yDegree
//4.1: If the yDegree is greater than zero, add the y
if (m_yDegree > 0)
retVal += 'y';
//4.2: if the yDegree is greater than 1, print out spaces for it
if (m_yDegree > 1) {
string rep(intToString(m_yDegree));
retVal += stringToSpaces(rep);
}

//5: Add the trailing space
retVal += ' ';

return retVal;

}

istream &operator >>(istream &strm, Expression &expr)
{

expr.m_coeff = 1;
if (strm.peek() == '-') {
expr.m_coeff = -1;
strm.get();
} else if (strm.peek() == '+') {
strm.get();
}

if (strm.peek() != 'x' && strm.peek() != 'y') {
int coeff;
strm >> coeff;
expr.m_coeff *= coeff;
}

for (int i = 0; i < 2; ++i) {
if (strm.peek() == 'x') {
strm.get();
if (strm.peek() >= '0' && strm.peek() <= '9')
strm >> expr.m_xDegree;
else expr.m_xDegree = 1;
} else if (strm.peek() == 'y') {
strm.get();
if (strm.peek() >= '0' && strm.peek() <= '9')
strm >> expr.m_yDegree;
else expr.m_yDegree = 1;
}
}
}

class ChainOfExpressions
{
ChainOfExpressions operator *(const ChainOfExpressions &other) const;

void insert(const Expression &expr);

friend istream &operator >>(istream &strm, ChainOfExpressions &expr);
friend ostream &operator <<(ostream &strm, const ChainOfExpressions
&expr);
private:
vector< Expression > expressions;
};

ChainOfExpressions
ChainOfExpressions::operator *(const ChainOfExpressions &other) const
{
vector< Expression >::const_iterator thisIt(expressions.begin());
ChainOfExpressions retChain;

while (thisIt != expressions.end()) {
vector< Expression >::const_iterator otherIt(other.expressions.begin());
while (otherIt != other.expressions.end()) {
Expression newExpr((*thisIt) * (*otherIt));

bool same = false;
vector< Expression >::iterator it(retChain.expressions.begin());
while (it != retChain.expressions.end()) {
if (it->sameDegrees(newExpr)) {
(*it) += newExpr;
same = true;
}
}
if (!same)
retChain.expressions.push_back(newExpr);

++otherIt;
}
++thisIt;
}

sort(retChain.expressions.begin(), retChain.expressions.end());
}

void ChainOfExpressions::insert(const Expression &expr)
{
vector<Expression>::iterator it(expressions.begin());
bool same = false;

while (it != expressions.end())
if (it->sameDegrees(expr)) {
(*it) += expr;
same = true;
}

if (!same)
expressions.push_back(expr);
}

ostream &operator <<(ostream &strm, const ChainOfExpressions &chain)
{
string topLine;
string bottomLine;
vector<Expression>::const_iterator it(chain.expressions.begin());

while (it != chain.expressions.end()) {
topLine += it->topLine();
bottomLine += it->bottomLine();
}

if (*(bottomLine.begin()) == '+') {
topLine = topLine.substr(2, 2000);
bottomLine = bottomLine.substr(2, 2000);
} else {
topLine = topLine.substr(1, 2000);
bottomLine = bottomLine.substr(1, 2000);
bottomLine[0] = '-';
}
}

istream &operator >>(istream &strm, ChainOfExpressions &chain)
{
while (strm) {
Expression expr;
strm >> expr;
chain.insert(expr);
}
}

string &stringToSpaces(string &toSpaces)
{
string::iterator it(toSpaces.begin());

while (it != toSpaces.end()) {
*it = ' ';
++it;
}

return toSpaces;
}

string intToString(int from)
{
ostringstream strm;
strm << from << flush;
return string(strm.str());
}

int main()
{
while (cin.peek() != '#') {
char buf[90];
cin.getline(buf, 90);

istringstream line1(string(buf));

cin.getline(buf, 90);
istringstream line2(string(buf));

ChainOfExpressions line1chn;
ChainOfExpressions line2chn;

line1 >> line1chn;
line2 >> line2chn;

ChainOfExpressions product(line1chn * line2chn);

cout << product;
}
}

** CODE ENDS **


Victor Bazarov
Guest
 
Posts: n/a
#4: Jul 23 '05

re: C++ istringstream problem


James Aguilar wrote:[color=blue]
> [...]
> istringstream line1(string(buf));
> istringstream line2(string(buf));
>[/color]

Sorry I didn't catch them at first. These two are function declarations.

V
James Aguilar
Guest
 
Posts: n/a
#5: Jul 23 '05

re: C++ istringstream problem


Oops. Skipped the minimal guideline. Here's a minimal demonstration of the
problem:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

class Test {
friend istream &operator >>(istream &strm, Test &tst);
};

istream &operator >>(istream &strm, Test &tst)
{
return strm;
}

int main()
{
char buf[80];
Test tst;

cin.getline(buf, 80);

istringstream strm(string(buf));

strm >> tst;
}


James Aguilar
Guest
 
Posts: n/a
#6: Jul 23 '05

re: C++ istringstream problem



"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:5FXCd.34574$NC6.29168@newsread1.mlpsca01.us.t o.verio.net...[color=blue]
>
> Sorry I didn't catch them at first. These two are function declarations.[/color]

Changed it, and you're right. Can you help me fix my meta-understanding
now? What can I do (besides pulling out the use of the string constructor
into another statement) to make those not function declarations?

- JFA


Victor Bazarov
Guest
 
Posts: n/a
#7: Jul 23 '05

re: C++ istringstream problem


James Aguilar wrote:[color=blue]
> Oops. Skipped the minimal guideline. Here's a minimal demonstration of the
> problem:
>
> #include <iostream>
> #include <sstream>
> #include <string>
>
> using namespace std;
>
> class Test {
> friend istream &operator >>(istream &strm, Test &tst);
> };
>
> istream &operator >>(istream &strm, Test &tst)
> {
> return strm;
> }
>
> int main()
> {
> char buf[80];
> Test tst;
>
> cin.getline(buf, 80);
>
> istringstream strm(string(buf));[/color]

The simplest way to fix it is to do

istringstream strm((string(buf)));

(extra parentheses surrounding the argument list).
[color=blue]
>
> strm >> tst;
> }
>
>[/color]

Victor
Closed Thread