Newbie questions (conditional operator, cin >> n...)

A

Army1987

I am a newbie to C++ (altough I already know some C). I've tried to
implement the TPK algorithm.

#include <iostream>
#include <ostream>
#include <cmath>

const int size = 11;
const double max = 400.0;
double f(const double& t);

int main(void)
{
double array[size];
for (int i = 0; i < size; ++i)
std::cin >> array;
for (int i = size - 1; i >= 0; --i) {
double y = f(array);
// std::cout << i + 1 << '\t' << (y > max ? "TOO LARGE" : y )
// << std::endl;
// doesn't compile, because "TOO LARGE" and y are different types.
// Do I really have to use an if statement whose branches are
// almost identical? Is there a better way?
std::cout << i + 1 << '\t';
if (y > max)
std::cout << "TOO LARGE" << std::endl;
else
std::cout << y << std::endl;
}
return 0;
}

double f(const double& t)
{
return std::sqrt(std::fabs(t)) + 5.0 * t * t * t;
}

If something which can't be interpreted as a double is input,
std::cin >> array leaves array uninitialized, and doesn't
discard garbage. How can I check if it succeeds? Since the cascading style can be used, I guess std::cin >> array evalues
to std::cin itself, so I guess using it in the controlling
expression of an if statement doesn't help. I could initialize all
the elements of the array to some strange value (eg. HUGE_VAL) and
check if it was unchanged, but is there a more elegant way?

Also, is there a good free online C++ tutorial, especially one
which points out differences with C? I've tried
http://www.icce.rug.nl/documents/cplusplus/ but it seems to be very
outdated (e.g. it claims there is no long double type in C, which
has had it since C89).
 
V

Victor Bazarov

Army1987 said:
I am a newbie to C++ (altough I already know some C). I've tried to
implement the TPK algorithm.

#include <iostream>
#include <ostream>
#include <cmath>

const int size = 11;
const double max = 400.0;
double f(const double& t);

int main(void)
{
double array[size];
for (int i = 0; i < size; ++i)
std::cin >> array;
for (int i = size - 1; i >= 0; --i) {
double y = f(array);
// std::cout << i + 1 << '\t' << (y > max ? "TOO LARGE" : y )
// << std::endl;
// doesn't compile, because "TOO LARGE" and y are different types.


It's not that they have different types, it's that they can't be
converted to the same type.
// Do I really have to use an if statement whose branches are
// almost identical? Is there a better way?

Almost identical? You mean a double is almost identical to a string
literal? REALLY?

Yes, an 'if' would be a solution. You could also try converting both
parts of ?: to the same type, like 'std::string', see 'lexical_cast'
from Boost.
std::cout << i + 1 << '\t';
if (y > max)
std::cout << "TOO LARGE" << std::endl;
else
std::cout << y << std::endl;
}
return 0;
}

double f(const double& t)
{
return std::sqrt(std::fabs(t)) + 5.0 * t * t * t;
}

If something which can't be interpreted as a double is input,
std::cin >> array leaves array uninitialized, and doesn't
discard garbage.


Meaning the next attempt to read array will fail as well...
How can I check if it succeeds?

if (cin.fail()) // last operation ended in 'failbit' set.

What does your favourite C++ book say?
Since the cascading
style can be used,

"Cascading style"? I guess I'm getting it confused with HTML or smth.
I guess std::cin >> array evalues to std::cin
itself, so I guess using it in the controlling expression of an if
statement doesn't help.


Doesn't? Have you tried?
I could initialize all
the elements of the array to some strange value (eg. HUGE_VAL) and
check if it was unchanged, but is there a more elegant way?

Yes, check the state of 'cin'. And read about streams a bit more.
Also, is there a good free online C++ tutorial, especially one
which points out differences with C?

I think that "good" and "free" in the same expression make an oxymoron.
I've tried
http://www.icce.rug.nl/documents/cplusplus/ but it seems to be very
outdated (e.g. it claims there is no long double type in C, which
has had it since C89).

Hmm

V
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

I am a newbie to C++ (altough I already know some C). I've tried to
implement the TPK algorithm.

#include <iostream>
#include <ostream>
#include <cmath>

const int size = 11;
const double max = 400.0;
double f(const double& t);

int main(void)
{
double array[size];
for (int i = 0; i < size; ++i)
std::cin >> array;
for (int i = size - 1; i >= 0; --i) {
double y = f(array);
// std::cout << i + 1 << '\t' << (y > max ? "TOO LARGE" : y )
// << std::endl;
// doesn't compile, because "TOO LARGE" and y are different types.
// Do I really have to use an if statement whose branches are
// almost identical? Is there a better way?


Not really, since they have different type. And what's so bad about an
if-statement, it'll make the code easier to read.
std::cout << i + 1 << '\t';
if (y > max)
std::cout << "TOO LARGE" << std::endl;
else
std::cout << y << std::endl;
}
return 0;
}

double f(const double& t)
{
return std::sqrt(std::fabs(t)) + 5.0 * t * t * t;
}

If something which can't be interpreted as a double is input,
std::cin >> array leaves array uninitialized, and doesn't
discard garbage. How can I check if it succeeds? Since the cascading style can be used, I guess std::cin >> array evalues
to std::cin itself, so I guess using it in the controlling
expression of an if statement doesn't help. I could initialize all
the elements of the array to some strange value (eg. HUGE_VAL) and
check if it was unchanged, but is there a more elegant way?


The FAQ might help you:
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3
Also, is there a good free online C++ tutorial, especially one
which points out differences with C? I've tried
http://www.icce.rug.nl/documents/cplusplus/ but it seems to be very
outdated (e.g. it claims there is no long double type in C, which
has had it since C89).

Don't know how much about the differences between C and C++ there is in
them but Thinking in C++ by Bruce Eckel can be downloaded for free:
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html
 
A

Army1987

Victor Bazarov said:
Army1987 said:
I am a newbie to C++ (altough I already know some C). I've tried to
implement the TPK algorithm.

#include <iostream>
#include <ostream>
#include <cmath>

const int size = 11;
const double max = 400.0;
double f(const double& t);

int main(void)
{
double array[size];
for (int i = 0; i < size; ++i)
std::cin >> array;
for (int i = size - 1; i >= 0; --i) {
double y = f(array);
// std::cout << i + 1 << '\t' << (y > max ? "TOO LARGE" : y )
// << std::endl;
// doesn't compile, because "TOO LARGE" and y are different types.


It's not that they have different types, it's that they can't be
converted to the same type.
// Do I really have to use an if statement whose branches are
// almost identical? Is there a better way?

Almost identical? You mean a double is almost identical to a string
literal? REALLY?

Yes, an 'if' would be a solution. You could also try converting both
parts of ?: to the same type, like 'std::string', see 'lexical_cast'
from Boost.


Ehm... Then I'll simplily use an if. By "better" I actually meant
"simpler".
std::cout << i + 1 << '\t';
if (y > max)
std::cout << "TOO LARGE" << std::endl;
else
std::cout << y << std::endl;
}
return 0;
}

double f(const double& t)
{
return std::sqrt(std::fabs(t)) + 5.0 * t * t * t;
}

If something which can't be interpreted as a double is input,
std::cin >> array leaves array uninitialized, and doesn't
discard garbage.


Meaning the next attempt to read array will fail as well...


That's what I meant by "doesn't discard garbage".
How can I do that other than by
std::cerr << "Please insert a number: " << std:flush;
char ch;
do {
std::cin >> ch;
if (cin.fail()) {
std::cerr << "Error\n";
return EXIT_FAILURE; // supposing <cstdlib> is included
}
} while (ch != '\n');
?
if (cin.fail()) // last operation ended in 'failbit' set.

What does your favourite C++ book say?


"Cascading style"? I guess I'm getting it confused with HTML or smth.

I meant the style
cin >> a >> b >> c;
as opposed to cin >> a; cin >> b; cin >> c;
I guess std::cin >> array evalues to std::cin
itself, so I guess using it in the controlling expression of an if statement doesn't help.


Doesn't? Have you tried?

Do you mean that cin can ever compare equal to zero?
Yes, check the state of 'cin'. And read about streams a bit more.


I think that "good" and "free" in the same expression make an oxymoron.

I'll rephrase it into "Which is one of the least bad free online
C++ tutorial?"
 
K

Kai-Uwe Bux

Army1987 said:
Victor Bazarov said:
Army1987 wrote: [snip]
I guess std::cin >> array evalues to std::cin
itself, so I guess using it in the controlling expression of an if
statement doesn't help.


Doesn't? Have you tried?

Do you mean that cin can ever compare equal to zero?


Streams define a conversion operator to bool. Thus, you can do something
like

if ( std::cin >> my_var ) {
// success
} else {
// failure
}

and

while ( std::cin >> my_var ) {
// something
}


Best

Kai-Uwe Bux
 
M

Marcus Kwok

Kai-Uwe Bux said:
Streams define a conversion operator to bool. Thus, you can do something
like

if ( std::cin >> my_var ) {
// success
} else {
// failure
}

and

while ( std::cin >> my_var ) {
// something
}

Actually, they have a conversion to void*, which is then converted to
bool; see FAQ #15.4, plus you can see it in Dinkumware's documentation:

http://www.dinkumware.com/manuals/?manual=compleat&page=ios.html#basic_ios

http://www.dinkumware.com/manuals/?manual=compleat&page=ios.html#basic_ios::operator void *
 
K

Kai-Uwe Bux

Marcus said:
Actually, they have a conversion to void*, which is then converted to
bool; see FAQ #15.4, plus you can see it in Dinkumware's documentation:

http://www.dinkumware.com/manuals/?manual=compleat&page=ios.html#basic_ios

http://www.dinkumware.com/manuals/?manual=compleat&page=ios.html#basic_ios::operator void *

Opps, my bad. Thanks.

I just like to add that the negation operator ! will nonetheless work as
expected since there is bool-valued operator! defined.


Best

Kai-Uwe Bux
 
M

Marcus Kwok

Kai-Uwe Bux said:
Opps, my bad. Thanks.

No problem.
I just like to add that the negation operator ! will nonetheless work as
expected since there is bool-valued operator! defined.

Yes, since from Dinkumware's docs:

basic_ios::eek:perator void* returns a null pointer only if fail()
basic_ios::eek:perator! returns fail()

So basically they're a couple different ways of finding the same info.
 
A

Army1987

Erik Wikström said:
I am a newbie to C++ (altough I already know some C). I've tried to
implement the TPK algorithm.

#include <iostream>
#include <ostream>
#include <cmath>

const int size = 11;
const double max = 400.0;
double f(const double& t);

int main(void)
{
double array[size];
for (int i = 0; i < size; ++i)
std::cin >> array;
for (int i = size - 1; i >= 0; --i) {
double y = f(array);
// std::cout << i + 1 << '\t' << (y > max ? "TOO LARGE" : y )
// << std::endl;
// doesn't compile, because "TOO LARGE" and y are different types.
// Do I really have to use an if statement whose branches are
// almost identical? Is there a better way?


Not really, since they have different type. And what's so bad about an if-statement, it'll make the code easier to read.
std::cout << i + 1 << '\t';
if (y > max)
std::cout << "TOO LARGE" << std::endl;
else
std::cout << y << std::endl;
}
return 0;
}

double f(const double& t)
{
return std::sqrt(std::fabs(t)) + 5.0 * t * t * t;
}

If something which can't be interpreted as a double is input,
std::cin >> array leaves array uninitialized, and doesn't
discard garbage. How can I check if it succeeds? Since the cascading style can be used, I guess std::cin >> array evalues
to std::cin itself, so I guess using it in the controlling
expression of an if statement doesn't help. I could initialize all
the elements of the array to some strange value (eg. HUGE_VAL) and
check if it was unchanged, but is there a more elegant way?


The FAQ might help you:
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3


Is there any mirror? At the moment I can't open it. (I'll retry
later on...)
Don't know how much about the differences between C and C++ there is in them but Thinking in C++ by Bruce Eckel can be downloaded
for free:
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

Thanks.
 
J

James Kanze

Army1987 said:
I am a newbie to C++ (altough I already know some C). I've tried to
implement the TPK algorithm.
#include <iostream>
#include <ostream>
#include <cmath>
const int size = 11;
const double max = 400.0;
double f(const double& t);
int main(void)
{
double array[size];
for (int i = 0; i < size; ++i)
std::cin >> array;
for (int i = size - 1; i >= 0; --i) {
double y = f(array);
// std::cout << i + 1 << '\t' << (y > max ? "TOO LARGE" : y )
// << std::endl;
// doesn't compile, because "TOO LARGE" and y are different types.

It's not that they have different types, it's that they can't be
converted to the same type.

Just a nit (and irrelevant here), but the requirement for ?: is
(very roughly) that one can be converted to the type of the
other. If both can be converted to some common third type, it's
not enough. (This situation commonly occurs in things like:

Base* pBase = condition ? new Derived1 : new Derived2 ;

Both Derived1* and Derived2* can be converted to Base*, which in
addition is what we want. But the expression as it stands is
illegal.)

[...]
if (cin.fail()) // last operation ended in 'failbit' set.

if ( ! cin )
or
if ( cin )
is more idiomatic. (I'm not particularly fond of the idiom
myself, but it's what one expects to see. And conforming to
reader expectations is a good thing.)
What does your favourite C++ book say?
"Cascading style"? I guess I'm getting it confused with HTML or smth.

I think he means something like "cin >> var1 >> var2", where you
"cascade" several >> in one expression. This works for exactly
the reason you mentionned above: the error is "sticky", and
won't go away until explicitly cleared, and operations invoked
when the stream is in an error state are no-ops. So if you
write something like:

if ( cin >> var1 >> var2 ) {
// All OK, use var1 and var2...
} else {
// Error...
}

You can't tell whether the error occured on var1 or on var2, but
the error never gets lost.

For anything but the most trivial use, it's usual to provide
some means of resynchrnonizing. The simplest is when input is
line oriented; just read line by line using getline, then
process each line using an istringstream. In case of an error
when reading the istringstream, the main source is still in a
non-error state, and synchronized ready to read the next line.
If you're converting directly from the input stream, on the
other hand, you need to 1) clear the error state (istream.clear()),
and 2) move ahead to the next synchronization point (consider
istream::ignore(), but if you need to synchronize on more than a
single character, it will require actively reading the file).

[...]
I think that "good" and "free" in the same expression make an oxymoron.

It depends. G++ is one of the better compilers around, and it
is "free" in most senses of the word. (In the strictest sense,
no software is ever totally free, since it costs time and effort
to install it, learn it, etc., etc. G++ doesn't cost any more
than most commercial offerings in this regard, however, and the
purchase price is considerably lower than most.)
 
A

Army1987

[snip code]
If something which can't be interpreted as a double is input,
std::cin >> array leaves array uninitialized, and doesn't
discard garbage. How can I check if it succeeds? Since the cascading style can be used, I guess std::cin >> array evalues
to std::cin itself, so I guess using it in the controlling
expression of an if statement doesn't help. I could initialize all
the elements of the array to some strange value (eg. HUGE_VAL) and
check if it was unchanged, but is there a more elegant way?


The FAQ might help you:
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3

Now I have this:

#include <iostream>
#include <ostream>
#include <cmath>
#include <limits>

const int size = 11;
const double max = 400.0;
double f(const double& t);

int main(void)
{
double array[size];
for (int i = 0; i < size; ++i)
while (!(std::cin >> array)) {
std::cerr << "Please insert a number: " << std::flush;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
for (int i = size - 1; i >= 0; --i) {
double y = f(array);
std::cout << i + 1 << '\t';
if (y > max)
std::cout << "TOO LARGE\n";
else
std::cout << y << '\n';
}
return 0;
}

double f(const double& t)
{
return std::sqrt(std::fabs(t)) + 5.0 * t * t * t;
}

If I give the eof signal, the error is cleared and the program goes
on. That would cause an endless loop if the input is redirected to
a file. What are the <iostream> C++ equivalents of feof() and
ferror()?
 
B

BobR

Army1987 said:
[snip]

What are the <iostream> C++ equivalents of feof() and
ferror()?

#include <iostream> // #include <ostream>
#include <fstream>

{
// std::fstream Zstat("Zstatus.txt",
// std::ios_base::in | std::ios_base::binary );
// std::eek:fstream Zstat( "Zstatus.txt" );
std::ifstream Zstat( "Zstatus.txt" );
if( not Zstat.is_open() ){ // if( not Zstat ){
std::cout<<" file error="<<Zstat.flags()<<std::endl;
std::cout<<" ios::good="<<Zstat.good()<<std::endl;
std::cout<<" ios::bad="<<Zstat.bad()<<std::endl;
std::cout<<" ios::eof="<<Zstat.eof()<<std::endl;
std::cout<<" ios::fail="<<Zstat.fail()<<std::endl;
} // if(!Zstat)
else{ /* .... */ }
}

Is that what you are looking for?

Note:
std::ifstream Zstat;
if( Zstat ){
// stream could be good with no file opened.
std::cout<<"this will print\n";
}
Zstat >> myvar; // NOW it is in fail state.
 
J

James Kanze

"Erik Wikström" <[email protected]> ha scritto nel messaggionews:[email protected]...
[snip code]
If something which can't be interpreted as a double is
input, std::cin >> array leaves array uninitialized,
and doesn't discard garbage. How can I check if it
succeeds? Since the cascading style can be used, I guess
std::cin >> array evalues to std::cin itself, so I guess
using it in the controlling expression of an if statement
doesn't help. I could initialize all the elements of the
array to some strange value (eg. HUGE_VAL) and check if it
was unchanged, but is there a more elegant way?

The FAQ might help you:
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3

Now I have this:
#include <iostream>
#include <ostream>
#include <cmath>
#include <limits>
const int size = 11;
const double max = 400.0;
double f(const double& t);
int main(void)
{
double array[size];
for (int i = 0; i < size; ++i)
while (!(std::cin >> array)) {
std::cerr << "Please insert a number: " << std::flush;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
for (int i = size - 1; i >= 0; --i) {
double y = f(array);
std::cout << i + 1 << '\t';
if (y > max)
std::cout << "TOO LARGE\n";
else
std::cout << y << '\n';
}
return 0;
}

double f(const double& t)
{
return std::sqrt(std::fabs(t)) + 5.0 * t * t * t;

}
If I give the eof signal, the error is cleared and the program goes
on. That would cause an endless loop if the input is redirected to
a file. What are the <iostream> C++ equivalents of feof() and
ferror()?

There is no real direct equivalent. Basically, once input has
failed, you can more or less test why:

if ( stream.bad() ) {
// Hard error...
} else if ( ! stream.eof() ) {
// Format error...
} else {
// End of file has been seen (but they might
// also be a format error).
}

Note that this checking should only be done once input has
failed, i.e. if stream.fail() is true (or if conversion to void*
yields a null pointer, or if ! returns true).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top