Hi again!

So, I have an object that gets appended to a linked list now. Now I need to have all of that item's data output in a formatted manner - something similar to this:

CD Artist         CD Title         CD Length         Track Name         Track Length
Arist name here   Title here       hh:mm:ss          Track name here    mm:ss
                                                     Track name here    mm:ss
                                                     Track name here    mm:ss

The problem with this is that the output for this is all in the overloaded << operator for my CD object and I'm having trouble figuring out how to append the track names and track lenghts, which are stored in their own linked lists (as per my assignment instructions), to a string, which I feel should be the best way to do things?

I don't feel like my code is far off, but.. if I was right, I wouldn't need help.

Code that should actually be right:

ostream &operator << (ostream &strm, const CD &obj)
{
    string outCD = "";

    outCD.append("\t");
    outCD.append(obj.artist);
    outCD.append("\t\t");
    outCD.append(obj.title);
    outCD.append("\t\t");
    outCD.append(obj.length);

    for (int it = 0; it <= obj.trackNum; it++)
    {
        if (it == 0)
        {
            outCD.append("\t\t");
            outCD.append(obj.tracks.returnString(it));
            outCD.append("\t\t");
            outCD.append(obj.tracktimes.returnString(it));
        }
        else
        {
            outCD.append("\n\t\t\t\t\t\t\t\t");
            outCD.append(obj.tracks.returnString(it));
            outCD.append("\t\t");
            outCD.append(obj.tracktimes.returnString(it));
        }
    }

    strm << outCD << endl;
    return strm;
}

Code that's giving me trouble:

//Return Single Stored String****************
//*******************************************
template <class T>
string TList<T>::returnString(int thisNode) const
{
    ListNode<T> *nodePtr;

    //Set nodePtr to the first position.
    nodePtr = head;

    //Traverse the list, moving to the nth node, where n is thisNode.
    for (int it = 0; it < thisNode; it++)
    {
        if (nodePtr)
        {
            nodePtr = nodePtr->next;
        }
    }

    //Return the string in the current node.
    if (nodePtr)
        return nodePtr->value;
}

1: I'm going to replace all the tabs with better formatting once I get it working.
2: If I throw some /* */ around my loop, it works fine, and it doesn't seem like anything's wrong with my loop.
3: Only a single string is ever stored in the tracks and tracktimes lists.

"In the function, it may be going through too many times (being a logical error; that'd be the less probable cause). The other scenario is that you may be giving it a wrong number, such as a number that exceeds the list of nodes, like going to a pointer that doesn't point to anything, based on what you think is the error. I'd have to look at all the code."

-- Mike

Yeah, I think it would have been, before I changed it. This is what I had before I went to work:

template <class T>
string TList<T>::returnString(int thisNode) const
{
    ListNode<T> *nodePtr;
    string nodeString = "";

    //Set nodePtr to the first position.
    nodePtr = head;

    //Traverse the list if necessary, finding the right node to add to output.
    if (thisNode > 0)
    {
        for (int it = 1; it < thisNode; it++)
        {
            if (nodePtr->next)
                nodePtr = nodePtr->next;
            else
                cout << "\nNo next node." << endl;
        }
    }

    //Add the string nodePtr points to to the end of the nodeString string.
    if (nodePtr)
        nodeString.append(nodePtr->value);
    return nodeString;
}

So it starts at the head and only runs through the for loop if thisNode is larger than 0, it only tries to append the string if there is a value in the node, and it only goes to the next node if the next node holds a value other than NULL.

I'll paste an image of what I get when I try to run through it, though.
http://i49.tinypic.com/qzqa1w.jpg

From the image you posted, you've got a std::bad_alloc exception being thrown, which can't be a good thing. I'd find out where that's comming from.

One possible source of that exception is that the loop isn't finding the node that you're asking for. If this means that you reach the end of your list and the last node is NULL, then your function won't return anything! The calling function is doing things with the return value (a std::string) so the behaviour is undefined. You need to sort out the TList<T>::returnString function so that all the return-paths return a value. If you have warnings turned on, you should be getting one about this. If not, you should turn on compiler warnings!

There's not really enough information to say exactly what's going wrong, but I'd say put a break point on line 11 of TList<T>::returnString and step through to see what it's doing.

I tried to take care of that with the definition of nodeString at the top of the function, making it an empty string so that it can be returned if there's nothing in the node, but there still always should be something there, with the loops I have - they shouldn't let nodePtr point to an empty node in the first place.

Today's my last day to finish this assignment. :( I don't think it'll be getting done.

Jen tells me I'll be better off posting all of my code. Also, I'm not sure what you mean by putting in a break point. :\

ListTemplate.h
http://pastie.org/private/xnoodksvibbii1rcjila2a
CD_class.h
http://pastie.org/private/qeqxieymivf0dfy2djgaa
DVD_class.h
http://pastie.org/private/8w234z6urlgnkofxziweqa
Media.h
http://pastie.org/private/nngvt2ejlhxanbqbogbfhw
Main.cpp
http://pastie.org/private/l9icooedi19vfg2vhyjaa

Still figuring out how to do other things, too. Working with objects in Linked Lists wasn't covered in the text. I'll work on those in the meantime..

I can't get nodePtr->value to return as a string. That's the problem. I can return a string, but if I try to cout << nodePtr->value; or return nodePtr->value, I get errors.

This is how I store strings in it, so it's only 1 string per node.

    for (int index = 0; index < trackNum; index++)
    {
        if (index == 0)
            cin.get();

        cout << "\n\n";
        cout << "What is the title of track " << (index + 1) << "?" << endl;
        cout << "> ";
        getline(cin, trks);
        tracks.appendNode(trks);

        cout << "\n\n";
        cout << "What is the length of track " << (index + 1) << "? (mm:ss)" << endl;
        cout << "> ";
        getline(cin, tracklens);
        tracktimes.appendNode(tracklens);
    }

Can anyone help me quickly? I have less than an hour.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.