Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

C++ Programming Help

Options
  • 12-03-2004 9:25am
    #1
    Registered Users Posts: 1,226 ✭✭✭


    We have recently been given an assignment in college.
    Its a C++ programing excercise. Programming is a small
    part of the course and we did it before christmas and I'm
    having trouble remembering everything. I have most of
    it done, I just need help tidying it up, the question is below
    and my answer is under that. If anyone can help I'd really
    appreciate it!


    Question
    Write a class called Team that holds information about
    one team in a football league. The class should have three
    private fields to hold the number of wins, the number of losses,
    and the number of draws that the team have achieved. It should
    have a private field to hold the name of the team as a text string
    of up to 20 characters. It should have one constructor that takes
    the name of the team and initialisess the number of wins, losses
    and draws to zero. It should have three public methods called
    addWin() , addLoss() and addDraw() that take no
    arguments and increment the wins, losses, and draws fields respectively.
    It should have a method called getPoints() thattakes no arguments
    and returns the number of league points for the team. Points should
    be calculated as 3 for each win, 1 for each draw, and zero for each
    loss. The class should have a method called getName() that
    returns the name of the team.


    My Answer

    #include <stdio.h>

    class Team {

    private:

    char name[21];
    int win;
    int loss;
    int draw;

    public:


    Team() {
    strcpy(name,"Team Name" );
    win = 0
    loss = 0
    draw = 0

    }


    void addwin() {
    win ++;
    }


    void addLoss(){
    loss ++;
    }

    void addDraw(){
    draw ++;
    }



    /*Is the points calculation bit here right?? I think thats the main problem with it*/

    int getPoints(){
    return(points);
    }

    if (win >0) {
    points =points*3
    }

    if (draw >0) {
    points = points*1
    }
    }

    Char getName() {
    return (name);
    }


Comments

  • Closed Accounts Posts: 437 ✭✭casper-


    Since they just want you to keep track of win/lost/draw you can calculate points in the same method where you return it
    int getPoints()
    { 
    return(win * 3 + draw);
    }
    

    Also i'm not sure what you have 'Char' defined to, but I would write getName as:
    const char * getName()
    {
    return &name;
    }
    

    You might need to cast the return value ..


  • Registered Users Posts: 491 ✭✭Silent Bob


    Originally posted by casper-
    Also i'm not sure what you have 'Char' defined to, but I would write getName as:

    const char * getName()
    {
    return &name;
    }
    

    You might need to cast the return value ..
    Given that you are using C++ you are better off using strings than char* for passing around strings.
    #include <string>
    using std::string;
    

    And then you can use string objects instead of character pointers.

    Examples (taken from SGIs STL reference)
    int main() { 
      string s(10u, ' ');           // Create a string of ten blanks.
    
      const char* A = "this is a test";
      s += A;
      cout << "s = " << (s + '\n');
      cout << "As a null-terminated sequence: " << s.c_str() << endl;
      cout << "The sixteenth character is " << s[15] << endl;
      
      reverse(s.begin(), s.end());
      s.push_back('\n');
      cout << s;
    }
    


  • Registered Users Posts: 1,226 ✭✭✭stereo_steve


    Thanks for all the help guys. I happy with the points adding bit. What you guys said make sense. I'll still confused about the team name though. Now that I'm using the string. Also whats casting? thanks alot.




    #include <string>

    class Team {

    private:

    char name[21];
    int win;
    int loss;
    int draw;

    public:


    Team() {
    strcpy(name,"Team Name" );
    win = 0
    loss = 0
    draw = 0

    }


    void addwin() {
    win ++;
    }


    void addLoss(){
    loss ++;
    }

    void addDraw(){
    draw ++;
    }


    int getPoints() {
    return(win * 3 + draw);
    }


    Char getName() {
    return (name);
    }


  • Registered Users Posts: 1,372 ✭✭✭silverside


    I would second the suggestion of using the string class.

    remove all mention of char and char* from your class.
    Set up a member variable of type string

    string name;

    in your constructor initialize it

    name="The bluejays";

    and return it in the getname
    string getName( return name;};

    OR

    if you want to stick with char* (the C-style way)

    define your getname function something like

    void getName(char* whereToPutName)
    {
    strcpy(whereToPutName, name);
    }

    Don't return pointers to member variables. If your object dies then people are left with a dangling pointer which can cause crashes.

    Borrow a C++ book that covers strings (and char* pointers if you want to understand that as well).

    You should not need to cast as it is generally a bad thing unless you know exactly what you are doing.


  • Closed Accounts Posts: 1,502 ✭✭✭MrPinK


    Originally posted by stereo_steve
    Also whats casting?
    Changing a variable from one type to another. C++ has a few different casts, but the most common is the static_cast. The syntax is: static_cast<newType>(variableName)

    e.g
    double d = 3.52;
    int x = static_cast<int>(d);
    


  • Advertisement
  • Registered Users Posts: 1,226 ✭✭✭stereo_steve


    Guys, you've all been great! I've always used the "char" The whole 2 months I did it!
    The only thing is, in the question it says i should allow 20 characters for the name, does this meanI would have to type char[21] . How could that be done with just name =????

    so You all thing I should get rid f the blue text and put in the red?After this I'll leave you all alone!

    #include <string>

    class Team {

    private:


    char name[21];
    int win;
    int loss;
    int draw;

    public:

    name=input_name
    Team() {
    strcpy(name,"Team Name" );
    win = 0
    loss = 0
    draw = 0

    }


    void addwin() {
    win ++;
    }


    void addLoss(){
    loss ++;
    }

    void addDraw(){
    draw ++;
    }


    int getPoints() {
    return(win * 3 + draw);
    }


    Char getName() {
    return (name);
    }


  • Registered Users Posts: 491 ✭✭Silent Bob


    #include <string>
    [b]using std::string;[/b]
    
    class Team {
    
    private:
        [b]string[/b] name;
        int win;
        int loss;
        int draw;
    
    public:
        Team() {
            [b]name = "Team Name"[/b];
            win = 0
            loss = 0
            draw = 0
        }
    
    
    void addwin() {
    win ++;
    }
    
    
    void addLoss(){
    loss ++;
    }
    
    void addDraw(){
    draw ++;
    }
    
    
    int getPoints() {
    return(win * 3 + draw);
    }
    
    
    [b]string[/b] getName() {
    return name;
    }
    

    The bold stuff is what it should be (I say this with a slight bit of caution, I've been coding almost 10 hours today)


  • Closed Accounts Posts: 437 ✭✭casper-


    Yes.. std::string is a good idea ... I just assumed that since it was for school you had limited choices and hence the char[].. I remember back in first year when they were going through different sets of loops in Pascal, and you _had_ to use 'while' for a project and not 'for'. Heh :)


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    I agree that std::string is superior to char* or char[], but the question specifies a string length, so I would go with the original char[], but note the advantages of std::string in comments and/or the write-up.


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    Dealing with the constructor:
    Depending on whether you use char* or std::string go with either:
    class Team {
    	char name[21];
    	int win;
    	int loss;
    	int draw;
    public:
    	Team(const char* teamName)
    	:win(0), loss(0), draw(0)
    	{
    		if (!teamName)
    			throw std::invalid_argument("Null pointer for team name.");
    
    		size_t len = strlen(teamName);
    		if (len > 20)
    			len = 20;
    		strncpy(name, teamName, len)
    		strncpy[len] = 0;
    	}
    	/* Other stuff elided */
    };
    
    strcpy could overflow the buffer, so we use strncpy to ensure this doesn't happen.

    Or with std::string you could use:
    class Team {
    	std::string name[21];
    	int win;
    	int loss;
    	int draw;
    public:
    	Team(const std::string& teamName)
    	:name(teamName), win(0), loss(0), draw(0)
    	{
    	}
    	/* Other stuff elided */
    };
    

    In both cases it's not strictly necessary to initialise win, loss and draw since the default behaviour would be to initialise them to 0 anyway, but it's good to be explicit.

    Another thing, can the name change once the class has been created? If not you could use a const std::string. However using an const char[] would be tricky since you would have to initialise it in the initialiser list, which is awkard with arrays to say the least.


  • Advertisement
  • Closed Accounts Posts: 437 ✭✭casper-


    This is getting slightly off-topic, but :
    
    Team::Team(...) 
    
    .
    .
    .
    
    if (!teamName)
    			throw std::invalid_argument("Null pointer for team name.");
    

    seems like overkill ;) And I'll refrain from getting into an argument over using exceptions in c++ *ahem* =)


    Oh wait...you're the mod for this board. (frantically starts entering ^H)


  • Registered Users Posts: 1,226 ✭✭✭stereo_steve


    Thanks for all the help guys. I'm handing it in later today. We were never tought about using string and I can see the benefit, preventing buffer overflows but I think he'll expect us to use char .

    With all the help here in the forum, I'm start teaching myself C++ after my exams finish. Thanks


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    Originally posted by casper-
    This is getting slightly off-topic, but :

    
    Team::Team(...) 
    
    .
    .
    .
    
    if (!teamName)
    			throw std::invalid_argument("Null pointer for team name.");
    

    seems like overkill ;)

    If the class is used in a few limited places and it's easy to ensure that there will never be a null pointer passed then it is overkill. If the class is used in a lot of places then it's good practice. If the class is part of the interface to a library that will be used in a variety of different applications then it's essential (indeed in such a case I might even go further and throw a class derived from std::invalid_argument.

    And I'll refrain from getting into an argument over using exceptions in c++ *ahem* =)
    Is it the increased reliability, readability or efficiency (efficiency over an equally robust implementation, not over something that can break easily) that you dislike :)

    For another thread however.


Advertisement