0

I'm am a beginner in C++. I'm using Xcode to compile my code. Right now I am going over variables and doing a brief exercise on the subject. The exercise asks that I ask for the user to input their first and last name as well their age. As a additional requirement I need to use a double floating point for age so I can multiply the age into months. Below is my code:

#include <iostream>
#include <math.h>

int main()
{
    std::cout << "Please enter your first name, second name, and age (then press enter).\n";
    std::string first;
    std::string last;
    std::double age;
    std::cin >> first >> last >> age;
    std::cout << "Hello, " << first << " " << last << ". Your age is " << age << " and you are " << (age * 12) << " months old.";
    return 0;
}

I get an error that says that the double is an expected unqualified-id. Can someone point out what I'm doing wrong and the correct way to do this?

Jarod42
  • 203,559
  • 14
  • 181
  • 302

4 Answers4

4

double does not live in the std namespace. You need

double age;

You also need to include the string header for std::string. You may get it indirectly from iostream on some implementations, but you cannot rely on that: it is a fluke.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 1
    Obviously this answer is so wrong and controversial as to merit a down-vote. I may remove it, once I discover what is wrong with it. That might take a while. – juanchopanza Jan 01 '14 at 21:33
  • @juanchopanze: at a guess, the downvote is childish revenge voting (it's usually that way for me). anyway re your comment on a now deleted answer to this question, "there is a reason C++ has namespaces", and yes, that reason has mainly to do with the possibility of `using`. Otherwise ordinary C style prefixes and suffixes would be quite enough. – Cheers and hth. - Alf Jan 01 '14 at 21:41
  • @Cheersandhth.-Alf I suspect the same. Concerning `using`, if they had recommended something like `using std::string;` it would have been fine with me. As I said, I spent too much time fixing problems caused by careless `using namespace std;`, so my tolerance to it is pretty low. – juanchopanza Jan 01 '14 at 21:45
  • @juanchopanza: I noticed a downvote, too. If there is no comment I just assume bad mood or revenge voting. I decided not to care about these as it is futile anyway. – Dietmar Kühl Jan 01 '14 at 22:31
  • Thank you! That worked. I got rid of the std:: and the code compiled without any error. – user3151953 Jan 02 '14 at 01:37
2

double is a built-in type. It doesn't live in any namespace and doesn't need any qualification! Just remove the std:: in front of double:

double age;

Note, you should test whether your input was actually successful:

if (std::cin >> first >> last >> age) {
    // process successful input
}
else {
    std::cout << "ERROR: failed to read expected input\n";
}
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • +1 But I would have recommended a `using` as well. I think Bjarne did that right in his intermediate book. No need to teach novices (the incorrect impression) that C++ is designed for verbosity and unreadability (and for those professionals who have adopted this view as coding guideline, which I know is done at a few Norwegian firms, I think there's no hope!). – Cheers and hth. - Alf Jan 01 '14 at 21:37
  • 1
    @Cheersandhth.-Alf: When you have multiple libraries around knowing where to go looking for documentation of entities is extremely helpful. I learned that when I needed to figure out what a Java program does and I struggled with locating the classes. It may feel unnecessary with `std::` but I like explicit qualifications and I won't recommend to drop them (for longer or nested namespaces I would recommend use of namespace aliases, though). – Dietmar Kühl Jan 01 '14 at 21:46
  • Oh, the days of analyzing code printouts is over. I think with modern IDE there /should/ be no problem of finding what a name refers to. E.g. just hover the mouse cursor over the name. ;-) – Cheers and hth. - Alf Jan 01 '14 at 21:48
  • 1
    @Cheersandhth.-Alf: I have rather recent experience with using IDEs which are keen on helping me but I consider the experience rather annoying as they tend to propose what I don't want to do. Also, they don't like to support vi keybindings. So, for my main work I'll stick with emacs/viper. – Dietmar Kühl Jan 01 '14 at 21:52
  • 1
    Never write code that requires an IDE's magic tricks to understand. – Lightness Races in Orbit Jan 01 '14 at 22:11
  • @LightnessRacesinOrbit: You are conflating the quick scanning of code with understanding the code. IDEs help with the former. Tool support for latter is a much more involved and thorny issue, involving language design (such as Eiffel's "Design by Contract", unfortunately not yet supported by C++), and going all the way back to Donald Knuth's observations about assertions in the first volume of "The Art of Computer Programming", and later his ideas about executable documentation. Anyway, conflated. And misleading. – Cheers and hth. - Alf Jan 01 '14 at 22:19
  • 1
    The upshot anyway is to do what's practical. I give different advice about PC things to my mother (old technophobic lady) than to my sister (middle age technofiliac, if there is such a term). I think absolute rules are very counter-productive for intelligent people in most any endeavour, except possibly some military operations – Cheers and hth. - Alf Jan 01 '14 at 22:23
  • What's practical for you, because _you_'re using some IDE and _you_ can "just hover the mouse cursor over the name", is not practical for someone else who doesn't. That's the point. A decent programmer writes self-explanatory code, not code that you need some software to hold your hand through in order to understand it without bloomin' code analysis. – Lightness Races in Orbit Jan 01 '14 at 22:37
  • @LightnessRacesinOrbit: sorry, again you're conflating things. i'm recommending a `using namespace std;` for the OPs code, and this is also the approach used by Bjarne in his intermedate C++ book. there is no possibility of getting confused about where a name comes from in such code, so your argument simply isn't relevant: it's based on a conflation of issues, misunderstanding what's relevant where. – Cheers and hth. - Alf Jan 01 '14 at 22:51
  • @LightnessRacesinOrbit: sorry, i had to flag your comment. i have NOT done written anything deserving of your description "accuse me of being stupid". that said, i agree that bjarne's use of something doesn't mean that it's necessarily right to do in some other context. – Cheers and hth. - Alf Jan 01 '14 at 22:59
  • Well you keep saying I'm conflating and misunderstanding things. I don't believe that to be the case at all. – Lightness Races in Orbit Jan 01 '14 at 22:59
  • That code you showed is helpful. I'm going to mess around with it in a sec. Thank you! – user3151953 Jan 02 '14 at 01:50
0

First of all it is a good idea to include header <string>

#include <string>

If in C# so-called built-in types in realty are aliases for classes as for example double is an alias for System.Double and you can write

System.Double age;

or

double age;

in C++ these types indeed are built in types and use keywords as doubleto specify a type

double age;

Though i do not understand why age should be double because the number of months in year is an integer value.:)

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 3
    I don't understand the relevance of C#. Can you explain it to me? – Lightness Races in Orbit Jan 01 '14 at 22:06
  • Age is typically given in number of years. The OP is looking to take a number of years, _not_ rounded to the nearest year, so that he can later report it in terms of years and months. – Lightness Races in Orbit Jan 01 '14 at 22:08
  • @LightnessRacesinOrbit: i think the relevance of C# is as an example of a language where what the OP did (OP is a beginner) is supported and makes sense. i.e. it goes to the OP's **conceptual model** of the language, correcting it so as to hopefully help the OP understand things better. in the same way, to someone who does something indicating a confusion of processor registers with adressable memory, one might use the PDP-11 as an example where that made sense (register were mapped to memory), and point out that on processor X this is not supported, that it's not like that on processor X. – Cheers and hth. - Alf Jan 01 '14 at 23:06
0

I believe the code below is about ideal for learning how to do this kind of nearly-first C++ program.

The little technical problem with your code was just that double is keyword, not a name defined by the standard library, and hence, not in namespace std.

In addition I’ve added

  • inclusion of the <string> header, necessary for using std::string in a portable way,

  • a using namespace std; directive, very handy for small exploration programs (but do not place this in the global namespace in a header file!),

  • checking of whether input operations succeed (also output can fail but that’s extremely rare).

The way that I check for input operation failure, using boolean "or" (the || operator), is not yet very much used in C++, but is common in some other languages. Essentially the left hand argument of || is converted to bool, since that’s what || requires. The left hand argument is the expression result of some input operation, which in general is a reference to the cin stream, and a bool value is then produced via a defined conversion that is equivalent to writing !cin.fail() (where ! is the logical "not" operation).

E.g., getline( cin, first ) || fail( ... ) reads very nicely as “getline or else fail”, and in addition to reading nicely it’s also visually distinctive, easy to recognize as a failure check.

#include <iostream>
#include <string>
#include <stdlib.h>             // exit, EXIT_FAILURE
using namespace std;

// Poor man's way to handle failure, but good enough here:
bool fail( string const& message )
{
    cerr << "!" << message << endl;
    exit( EXIT_FAILURE );
}

int main()
{
    cout << "Please enter your first name: ";
    string first;
    getline( cin, first )
        || fail( "Sorry, input of your first name failed." );

    cout << "Please enter your last name: ";
    string last;
    getline( cin, first )
        || fail( "Sorry, input of your last name failed." );

    cout << "Please enter your age in years: ";
    double age;
    cin >> age
        || fail( "Sorry, input of your age failed." );

    cout << "Hello, " << first << " " << last << "." << endl;
    cout
        << "Your age is " << age << " years"
        << " and you are "<< (age*12) << " months old."
        << endl;
}
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • @LightnessRacesinOrbit: re `cstdlib` versus `stdlib.h`, the latter is generally preferable in standard C++. and in my view even for the case of g++ `math.h` (which is a bit non-standard). see http://stackoverflow.com/questions/10625716/in-what-cases-we-need-to-include-cassert/10626042#10626042 for more discussion. – Cheers and hth. - Alf Jan 01 '14 at 23:15
  • Why is the latter preferable? I think we've had this discussion before and you've not convinced me. A link to someplace else where you give the same opinion is not an acceptable citation :P From what I can tell, you take issue with `cstdlib` potentially contaminating the global namespace, and instead recommend `stdlib.h` which is guaranteed to. #confuse – Lightness Races in Orbit Jan 01 '14 at 23:17
  • 1
    @LightnessRacesinOrbit: that answer includes relevant citations from the C++ standard. it would be too much to reproduce in comments here. so. ;-) – Cheers and hth. - Alf Jan 01 '14 at 23:19
  • No, neither of them state that "the latter is generally preferable in standard C++". – Lightness Races in Orbit Jan 01 '14 at 23:23
  • @LightnessRacesinOrbit: the citations are not fallacious authority arguments. they merely prove what the language rules are. from there to suitability is a, well a gap of sorts, that is crossed by applying logic. others have put that logic more eloquently than me. but i don't have the time to do the relevant googling for you. – Cheers and hth. - Alf Jan 01 '14 at 23:26
  • I know exactly what the language rules are. I'm asking you to explain your claim that "`stdlib.h` is generally preferable in standard C++", because I disagree with you. – Lightness Races in Orbit Jan 01 '14 at 23:26
  • @LightnessRacesinOrbit: apparently you have looked at the linked to answer about that, and request that I quote it here. that's absurd. – Cheers and hth. - Alf Jan 01 '14 at 23:28
  • 1
    "others have put that logic more eloquently than me" - that must be the _appeal to an (hopefully?) implied authority_ stylism then – sehe Jan 01 '14 at 23:28
  • 1
    @sehe: i don't see why that "must be an appeal to ... autority". Lighness (a.k.a. this, a.k.a. that) claims to not be convinced by my explanation, or even recognizing it as such. so i'm suggesting he then seeks others' explanations. in other words, i have given up on explaining this to him myself. but others' explanation might offer some hope. – Cheers and hth. - Alf Jan 01 '14 at 23:31
  • @Cheersandhth.-Alf: I read the answer and I already told you it does not answer my question. It was a pretty simple question. I generally find that when I can't explain my own assertions I should then question whether I really believe in them myself. – Lightness Races in Orbit Jan 01 '14 at 23:33
  • And I'm not really sure what you mean by "aka this, aka that". If you're making a reference to my SO name not being my real name, then I suggest you take another look at your own ;) – Lightness Races in Orbit Jan 01 '14 at 23:37
  • @Cheers: It wasn't me, FWIW. – Lightness Races in Orbit Jan 01 '14 at 23:39
  • @Cheersandhth.-Alf: Thank you for showing me that code. I'm going through Bjarne's Programming Principles and Practice. He hasn't shown #include yet but I'll do that from now on. Just a quick question. I'm not familiar with what you mean by inclusion of the header, necessary for using std::string in a portable way. Could you dumb it down for me? :) – user3151953 Jan 02 '14 at 01:47
  • @user3151953: The C++ core language, like the C core language, doesn't have any i/o functionality, string handling, whatever. All that is provided by **libraries**, most notably the C++ **standard library** (which is always available). To use things from a library you typically `#include` the text from a (in practice) file called a **header**, which provides declarations of the functions etc. It may also provide implementations of those functions, or compiled implementations may be linked in. The `` header provides declarations & implementation of the `std::string` type, + more. – Cheers and hth. - Alf Jan 02 '14 at 01:58
  • 1
    @user3151953: In C, if I recall correctly, one is guaranateed that one standard library header does not in turn include another. But in C++ they can. And so by including e.g. ``, with some given C++ implementation it may in turn include ``, so that the `std::string` type is available. But with some other implementation the `` may *not* do that. So for portable code `` should always be explicitly included, `#include`, when the code uses `std::string` (or anything else from that header). – Cheers and hth. - Alf Jan 02 '14 at 02:07