Sign in to follow this  
JimPrice

Streams and overloaded [SOLVED]

Recommended Posts

This is the first time I've tried writing a custom << operator for use with streams, and I can't work out why it's not working. Any advice welcomed.
class Ingredient
{
public:
	Ingredient(std::string name); //obvious implementation
	virtual ~Ingredient(void);

	friend std::ostream& operator<<(std::ostream& stream, Ingredient ingredient);

private:
	std::string name_;
};

std::ostream& operator<<(std::ostream& stream, Ingredient ingredient)
{
	stream << ingredient.name_;
	return stream;
}



And the manager class
class IngredientManager
{
public:
// Init and DeInit functions
	IngredientManager(void);
	~IngredientManager(void);

// Utility functions
	void SaveIngredients();
	void AddNewIngredient(std::string name); 

private:
	typedef std::list<Ingredient> listType;
	listType ingredientList_;
};


void IngredientManager::AddNewIngredient(std::string name) 
{
	ingredientList_.push_back(Ingredient(name));
}


void IngredientManager::SaveIngredients()
{
	std::ofstream fileOut("./DataStore/Ingredients.txt");

	std::copy(ingredientList_.begin(), 
		ingredientList_.end(), 
		std::ostream_iterator<Ingredient>(fileOut, " "));

	fileOut.close();
}



Any help appreciated. Jim. [Edited by - JimPrice on December 4, 2004 2:30:36 PM]

Share this post


Link to post
Share on other sites
Did you remember to include the <string> header? You can get really weird error messages with stream I/O if you forget that.

If that isn't the problem, then you might want to mention what the actual issue is.

Share this post


Link to post
Share on other sites
Quote:

Did you remember to include the <string> header


Yup.

Quote:

If that isn't the problem, then you might want to mention what the actual issue is.


OK, so that might help a little I guess. [embarrass]

The problem is that the ingredient.name_ is never put into the output file. If I change the seperator in the ostream_iterator (to "a", for example), it produces that. If I add something like stream << "FooBar" to the overloaded operator it prints that. It just never prints the ingredient.name_. Suggests that name_ never gets populated, but I'm pretty sure it does.

Thanks,
Jim.

Share this post


Link to post
Share on other sites
And of course, another obvious suggestion would be that since you think that the name_ member isn't being assigned, show the code where it should be populated.

edit: and while, I'm looking at the code, you use pass by value in a lot of places where you should use pass by const reference. For example, you should probably change std::ostream& operator<<(std::ostream& stream, Ingredient ingredient); to std::ostream& operator<<(std::ostream & lhs, const Ingredient & rhs);.

Share this post


Link to post
Share on other sites
Quote:

And of course, another obvious suggestion would be that since you think that the name_ member isn't being assigned, show the code where it should be populated.



std::string itemName;

// callback procedure info for dialog box

case IDSAVE:
if(GetDlgItemText(hDlg, IDC_EDIT1, &itemName[0], 255))
{
IngredientManager::Instance()->AddNewIngredient(itemName);
}




IDSAVE is a push-button on a dialog box, IDC_EDIT1 is a text-field on the same dialog box. The function call is in the original post.

Quote:

you use pass by value in a lot of places where you should use pass by const reference


Yeah, I'm normally pretty good with that - my bad.

Quote:

Run the code in the debugger and manually inspect name_.


Yup, off to do this now. I've just played with my Logger (quick and easy), and I'm starting to think the problem might be with the name_ generation.

Thanks,
Jim.

Share this post


Link to post
Share on other sites
GetDlgItemText(hDlg, IDC_EDIT1, &itemName[0], 255)

That won't work. The string is not 255 characters long by default. It probably starts with a empty buffer, so you're just overwriting random memory. Try using a temporary character array:
char itemName[255];
if (GetDlgItemText(hDlg, IDC_EDIT1, itemName, 255)
{
IngredientManager::Instance()->AddNewIngredient(itemName);
}

The char array will be implicitly converted to a string in the call of AddNewIngredient.

Enigma

Share this post


Link to post
Share on other sites
Quote:

That won't work.


Dagnabit, that's so obvious when it's pointed out. I've seen similar things with std::vector, but hadn't considered the implications for std::string.

Thanks y'all for your patience.
Jim.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this