Streams and overloaded [SOLVED]

Started by
6 comments, last by JimPrice 19 years, 4 months ago
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]
Advertisement
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.
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.
Run the code in the debugger and manually inspect name_. It is possible that, for some reason, it isn't being initialized.
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);.
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.
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
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.

This topic is closed to new replies.

Advertisement