Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Newbie questions (conditional operator, cin >> n...)

Reply
Thread Tools

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

 
 
Army1987
Guest
Posts: n/a
 
      06-28-2007
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[i];
for (int i = size - 1; i >= 0; --i) {
double y = f(array[i]);
// 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[i] leaves array[i] 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[i] 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).


 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      06-28-2007
Army1987 wrote:
> 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[i];
> for (int i = size - 1; i >= 0; --i) {
> double y = f(array[i]);
> // 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[i] leaves array[i] uninitialized, and doesn't
> discard garbage.


Meaning the next attempt to read array[i] 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[i] 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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
=?ISO-8859-1?Q?Erik_Wikstr=F6m?=
Guest
Posts: n/a
 
      06-28-2007
On 2007-06-28 16:29, Army1987 wrote:
> 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[i];
> for (int i = size - 1; i >= 0; --i) {
> double y = f(array[i]);
> // 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[i] leaves array[i] 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[i] 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-lit....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/...ngInCPP2e.html


--
Erik Wikström
 
Reply With Quote
 
Army1987
Guest
Posts: n/a
 
      06-28-2007

"Victor Bazarov" <(E-Mail Removed)> ha scritto nel messaggio news:f60i3g$qqj$(E-Mail Removed)...
> Army1987 wrote:
>> 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[i];
>> for (int i = size - 1; i >= 0; --i) {
>> double y = f(array[i]);
>> // 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[i] leaves array[i] uninitialized, and doesn't
>> discard garbage.

>
> Meaning the next attempt to read array[i] 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');
?

>> 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 meant the style
cin >> a >> b >> c;
as opposed to cin >> a; cin >> b; cin >> c;

>
>> I guess std::cin >> array[i] 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?

>> 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'll rephrase it into "Which is one of the least bad free online
C++ tutorial?"


>> 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



 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      06-28-2007
Army1987 wrote:

>
> "Victor Bazarov" <(E-Mail Removed)> ha scritto nel messaggio
> news:f60i3g$qqj$(E-Mail Removed)...
>> Army1987 wrote:

[snip]
>>> I guess std::cin >> array[i] 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
 
Reply With Quote
 
Marcus Kwok
Guest
Posts: n/a
 
      06-28-2007
Kai-Uwe Bux <(E-Mail Removed)> wrote:
> 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/?m...html#basic_ios

http://www.dinkumware.com/manuals/?m...tor%20void%20*

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      06-28-2007
Marcus Kwok wrote:

> Kai-Uwe Bux <(E-Mail Removed)> wrote:
>> 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/?m...html#basic_ios
>
>

http://www.dinkumware.com/manuals/?m...tor%20void%20*
>


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
 
Reply With Quote
 
Marcus Kwok
Guest
Posts: n/a
 
      06-28-2007
Kai-Uwe Bux <(E-Mail Removed)> wrote:
> Marcus Kwok wrote:
>> Kai-Uwe Bux <(E-Mail Removed)> wrote:
>>> Streams define a conversion operator to bool.

>>
>> Actually, they have a conversion to void*, which is then converted to
>> bool;

>
> 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:perator void* returns a null pointer only if fail()
basic_ios:perator! returns fail()

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

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
Army1987
Guest
Posts: n/a
 
      06-29-2007

"Erik Wikström" <(E-Mail Removed)> ha scritto nel messaggio news:VjQgi.3079$(E-Mail Removed)...
> On 2007-06-28 16:29, Army1987 wrote:
>> 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[i];
>> for (int i = size - 1; i >= 0; --i) {
>> double y = f(array[i]);
>> // 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[i] leaves array[i] 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[i] 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-lit....html#faq-15.3


Is there any mirror? At the moment I can't open it. (I'll retry
later on...)

>> 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/...ngInCPP2e.html


Thanks.


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      06-29-2007
On Jun 28, 4:54 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
> Army1987 wrote:
> > 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[i];
> > for (int i = size - 1; i >= 0; --i) {
> > double y = f(array[i]);
> > // 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.)

[...]
> > How can I check if it succeeds?


> 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?


> > Since the cascading
> > style can be used,


> "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).

[...]
> > 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.


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.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Using cin.get() and cin.eof() ends up in an endless loop Fernando C++ 4 11-16-2011 07:19 PM
cin and cin.getline() Aleander C++ 5 03-06-2005 03:57 PM
std::cin.ignore() and std::cin.clear() Chris Mantoulidis C++ 5 01-06-2004 11:08 PM
cin and cin.clear() problem TaiwanNoWhere C++ 8 10-17-2003 05:53 PM
Newbie: what is cin.get() Zalek Bloom C++ 19 09-20-2003 05:16 PM



Advertisments