Alright - this is my conundrum. As a noob to C++ I am only in chapter 9 of my book, having just covered object oriented programs and the exciting world of vectors and arrays. I have an assignment that asks me to run a loop to get and calculate a set of values, validate them against a set standard, and then print them to a file. I can do that.

My problem is that I am supposed to allow infinite entry and the assignment explicitly states that I cannot use an array to store the entered values. Initially I tried incrementing a structure, but apparently you can't do that unless it's an array of structures, which I think violates the assignment guidelines. As far as I know, vectors also require a size declarator, so I run into the problem of allowing the user to enter as many values as they like. So . . . I started looking into appending to a file? I don't really understand it; it's not covered in my book so far, and I haven't been able to get it to work. I'm trying to use a while loop that terminates on value -1 with a nested loop that terminates at EOF - supposedly to allow the user to enter the values, then call a function to validate the entries and make calculations based on them - then write it to a file on each loop iteration. I can post code when I get home if that helps.

My question amounts to - what is the most efficient way for a noob programmer to store data from a loop without resorting to an array?

Is there anywhere in your problem description that states you must save each input somewhere?

Well, I have to print the info to a file. My assumption was that I needed to store it, then send all data to a function that will write it to a file. Right now I'm trying to read up on appending to a file and trying to incorporate that into a loop so that instead of storing the data I just write it to the open txt file with each iteration. I just want to make sure I'm going in the right direction. I spent nearly two days wasting time on ideas that didn't work . . .

Am I still barking up the wrong tree?

So why not
1) open the file before the loop
2) write the data to the file when you get it
3) close the file after the loop
:icon_question:

I didn't know I could do that. So it would read:
Open the file
Start the loop
Call the functions to get and calculate data
write them to the file
close the loop
close the file

If that's wrong, feel free to smack me ^_^
I will try it . . . if the append file loop doesn't work. Nearly done with it, though I haven't debugged yet. If it's wrong that's just another day down the tubes.

That's right! And the OPEN, WRITE, and CLOSE can all be functions if you want. I would recommend the WRITE be one.

The append is an interesting but unnecessary solution. It means you must open and close the file for each and every write -- not very efficient. There are times when it's useful, but not here.

So I wrote the code, but I keep getting my error message that the file can't be opened, and of course, nothing is written to the file. I'm still pouring over it to find the error, but I'm not seeing anything so far. Any ideas?

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;

//structure to pass several values between functions
struct Package
{
	int	weight,
		side1,
		side2,
		side3,
		girth,
		count;
	string status;
	float cost;
} package;

//function declarations  
int menuSelection ();
void openFile();
void printToFile(Package);
void getData(Package &);
float validate(Package);
void closeFile();

//main function 
int main()
{
	
	openFile();	//open file prior to running loop.
	getData(package);	//primary function to get and process data
	
	return 0;
}

//open file function
void openFile()
{
	ofstream package_file;
		package_file.open("package_file.txt", ios::out);
}

//close file function
void closeFile()
{
	ofstream package_file;
	package_file.close();
}

//menu function used to set option variable 
int menuSelection()
{
	int option;
	cout << "Enter any number to process a package or -1 to end: ";
	cin >> option;
	return option;
}

//write to file function
void printToFile(Package)
{	
		ofstream package_file;
		if(!package_file.is_open())
		{
			cout << "The file could not be opened." << endl;
		}

		else
		{
			package_file << fixed << showpoint << setprecision(2);
			package_file << setw(5) << "Trans" << setw(10) << "Status" << setw(7) << "Weight" << setw(7) << "Cost" << endl;
			package_file << setw(5) << package.count << setw(10) << package.status << setw(7) << package.weight << setw(7) << package.cost << endl;
		}
		
	}
	
//primary function to get and process data
void getData(Package &)
{
	int option = menuSelection();	//call menu
	int count = 1;					//set counter to get transaction number

	//loop to gather info and call calculate, validate, and print to file functions
	while(option != -1)
	{
		int	largest;
		float girthCompare;
	
	cout << "Please enter the package weight in whole pounds.\n";
			cin >> package.weight;
			while(package.weight < 1)
			{
				cout << "Please enter a valid package weight in whole pounds: ";
				cin >> package.weight;
			}

			cin.get();
			cout << "Please enter the measurements of 3 sides of the package in inches.\n";
			cin >> package.side1 >> package.side2 >> package.side3;
	
			while(package.side1 < 1)
			{
				cout << "Please enter a valid side 1 measurement: ";
				cin >> package.side1;
			}
			while(package.side2 < 1)
			{
				cout << "Please enter a valid side 2 measurement: ";
				cin >> package.side2;
			}
			while(package.side3 < 1)
			{
				cout << "Please enter a valid side 1 measurement: ";
				cin >> package.side3;
			}
			package.count = count++;
			if(package.side1 > package.side2 && package.side1 > package.side3)
				largest = package.side1;
			if(package.side2 > package.side1 && package.side2 > package.side3)
				largest = package.side2;
			if(package.side3 > package.side1 && package.side3 > package.side2)
				largest = package.side3;
			package.girth = 2 * (package.side1 + package.side2 + package.side3 - largest);
			girthCompare = package.girth / 12;
			if(package.weight <= 50 && girthCompare <= 5)
			{
				package.status = "Accepted";
				package.cost = validate(package);
			}
			else
				package.status = "Rejected";
			validate(package);			//call validate function prior to ending loop
			printToFile(package);		//call to write data to file
			option = menuSelection();	//call menu selection to reset option variable and return to loop or end

		//set action if user decides to end program
		if(option == -1)
	{
		cout << "You have chosen to end the program" << endl;
		closeFile();	//close file after all iterations of loop have been processed.
	}			
}
}

//function to return cost and validate package size
float validate(Package)
{
	//arrays used to evaluate cost based on weight 
	int validWeight[15] = {1, 2, 3, 5, 7, 10, 13, 16, 20, 25, 30, 35, 40, 45, 50};
	float price[15] = {1.5, 2.1, 4.0, 6.75, 9.9, 14.95, 19.40, 24.2, 27.3, 31.9, 38.5, 43.5, 44.8, 47.4, 55.2};
	
	// loop to search array value by value to get correct cost
	for(int target = 0; target < 15; target++)
	{
		if(validWeight[target] <= package.weight)
		{
			package.cost = price[target];
		}
	}
	return package.cost;	//return value to structure
}

When you use open a file in a function, you have to pass the file information (package_file) back to the calling function. You can't just create a file stream and read it, which is what you are doing.

OPEN: passes back the ostream
READ,WRITE,CLOSE: pass the ostream into the function.

I'm not sure I understand. It makes sense that I need to pass the file info to the calling function, but does it work as a pass-by-reference or do I return an ofstream as a value at the end of the open file function? I've actually tested both and am still getting the error, so I may have run down a tangent path again and missed your point. Would you elaborate?

Thanks much for your help so far! It's great to have someone who knows more than I do to bounce ideas off of ^_^

Alright, I figured it out. Thanks for all your help!

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.