created a data file to store integers and after the program reads the numbers from the data file, i want to calculate the sum total and average of the numbers and output the total and the average from the second code that reads the data file. what do i need to do to get to that to work?
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
//declarations
ofstream outputfile;
int num, integer, sentinel;
//open file for output
outputfile.open("savedata.dat");
//get input from user
cout << "How many integers would you like to enter? " << endl;
cin >> integer;
//use a for loop to get integers from user and store them in the file
for (int i = 0; i < integer; ++i)
{
cout << "Enter integer: " << endl;
cin >> num;
outputfile << num << endl;
}
//close file
outputfile.close();
return 0;
}
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
//open file for input and read contents
ifstream inputfile;
int num;
inputfile.open("savedata.dat");
cout << "Contents of file: " << endl;
while (inputfile >> num) // read until end of file
{
cout << num << endl;
}
//close file
inputfile.close();
return 0;
}
tried adding int sum to find sum total but am lost
This is not that complicated. As per definition, the average can be calculated by divdiding the sum of the values by the count of the values.
So, we need to add 2 variables
counter --> To count the values in the file
sum --> To sum up the values
The variables will be defined and initialized to 0 before your read-loop.
In the for loop, we can simply incremented the counter add the newly read value to the sum. After the for loop, we can output all values. But we need to "cast" the values for "counter" and "sum" to a double value, because the average is typically not an integer.
Your second program could then look like the below:
int main()
{
main2();
//open file for input and read contents
ifstream inputfile;
int num;
inputfile.open("savedata.dat");
cout << "Contents of file: " << endl;
int counter = 0;
int sum = 0;
while (inputfile >> num) // read until end of file
{
cout << num << endl;
sum += num;
++counter;
}
//close file
inputfile.close();
cout << "\nNumber of value: " << counter << "\tSum: " << sum << "\t\tAverage: " << (double)sum/(double)counter << '\n';
return 0;
}
I'll preface this by noting that I'm very new to C++ and programming in general so if I'm doing something improperly or writing code in an odd way, it's because i've only learned so much so far.
Anyways, I was given an assignment to write a program that first
Reads integers from a file of the user's choice
Outputs the sum and average of all the numbers greater than or equal to zero ,
Outputs the sum and average of all the numbers less than zero
Outputs the sum and average of all the numbers, whether positive, negative, or zero.
Then finally asks the user if they'd like to choose another file to run on again
The only catch is that I have to use a dynamic array within the code, I'm assuming in order to allow the file to hold any amount of integers.
So far, I have everything except for the implementation of the dynamic array. The code is currently programmed to only accept 10 integers (as there are no arrays in the code yet).
Here's my code:
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
//Variables
string inFile;
int numbers, i = 0;
double avg, neg_avg, total_sum, total_avg, sum = 0, neg_sum = 0;;
double count = 0, neg_count = 0, pos_count = 0;
char answer;
do
{
//Input Question
cout << "Enter the file name.\n";
cin >> inFile; // Input from User
ifstream fin; // Open File
fin.open(inFile);
if (fin.fail()) // Check to see if file opens properly
{
cout << "An error occurred while attempting to open the file.\n";
exit(1);
}
while (count < 10)
{
fin >> numbers;
if (numbers >= i)
{
sum += numbers;
count += 1;
pos_count += 1;
}
if (numbers < i)
{
neg_sum = neg_sum + numbers;
count = count + 1;
neg_count = neg_count + 1;
}
}
//Calculations
avg = sum / pos_count;
neg_avg = neg_sum / neg_count;
total_sum = sum + neg_sum;
total_avg = total_sum / 10.0;
//OUTPUT
cout << "The sum of all positive numbers is: " << sum << endl;
cout << "The average of all positive numbers is: " << setprecision(3) << avg << endl;
cout << "The sum of all negative numbers is: " << neg_sum << endl;
cout << "The average of all negative numbers is: " << setprecision(3) << neg_avg << endl;
cout << "The sum of all numbers is: " << total_sum << endl;
cout << "The average of all numbers is: " << setprecision(3) << total_avg << endl;
cout << "-------------------------------------------------" << endl;
cout << "Want us to read another file?\n";
cout << "Enter 'Y' or 'y' for yes, any other character for no." << endl;
cin >> answer;
} while ((answer == 'y') || (answer == 'Y'));
return 0;
}
Any help would be greatly appreciated!
Thanks in advance
UPDATE:
I've gotten this far but when I compile, the program runs continuously.Not sure what I'm doing wrong.
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
//Variables
string file;
int i = 0;
double avg, neg_avg, total_sum, total_avg, sum = 0, neg_sum = 0;;
double neg_count = 0, pos_count = 0, totcount = 0;
char answer;
//Input Question
do
{
cout << "Enter the file name.\n";
cin >> file; // Input from User
ifstream fin; // Open File
fin.open(file);
if (fin.fail()) // Check to see if file opens properly
{
cout << "An error occurred while attempting to open the file.\n";
exit(1);
}
while (!fin.eof())
{
int numbers;
fin >> numbers;
int *dynamicArray;
dynamicArray = new int[numbers];
if (numbers >= i)
{
sum += numbers;
pos_count += 1;
totcount += 1;
}
if (numbers < i)
{
neg_sum = neg_sum + numbers;
neg_count = neg_count + 1;
totcount += 1;
}
//Calculations
avg = sum / pos_count;
neg_avg = neg_sum / neg_count;
total_sum = sum + neg_sum;
total_avg = total_sum / totcount;
//OUTPUT
cout << "The sum of all positive numbers is: " << sum << endl;
cout << "The average of all positive numbers is: " << setprecision(3) << avg << endl;
cout << "The sum of all negative numbers is: " << neg_sum << endl;
cout << "The average of all negative numbers is: " << setprecision(3) << neg_avg << endl;
cout << "The sum of all numbers is: " << total_sum << endl;
cout << "The average of all numbers is: " << setprecision(3) << total_avg << endl;
cout << "-------------------------------------------------" << endl;
delete [] dynamicArray;
}
fin.close();
cout << "Want us to read another file?\n";
cout << "Enter 'Y' or 'y' for yes, any other character for no." << endl;
cin >> answer;
} while ((answer == 'y') || (answer == 'Y'));
return 0;
}
UPDATE:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
//Variables
string file;
int i = 0, value = 0, e = 0;
double avg, neg_avg, total_sum, total_avg, sum = 0, neg_sum = 0;;
double neg_count = 0, pos_count = 0, totcount = 0;
char answer;
//Input Question
do
{
cout << "Enter the file name.\n";
cin >> file; // Input from User
ifstream fin; // Open File
fin.open(file);
if (fin.fail()) // Check to see if file opens properly
{
cout << "An error occurred while attempting to open the file.\n";
exit(1);
}
// <---------- This works to get the size of the file
int elements;
vector<int> eCount;
while (fin >> elements)
{
eCount.push_back(elements);
}
int size = static_cast<int> (eCount.size());
cout << "size = " << size << endl;// <-----------Test to see if working
//From this point, size of the file is held in the variable, 'size'.
int array_size = size;
int* p;
p = new int[array_size];
int location = 0;
while (!fin.eof())
{
fin >> p[location];
location++;
}
cout << "P[12] is equal to " << p[12] << endl;// <----Test to see if array is initialized
while (fin >> p[location])
{
if (p[e] >= i)
{
sum = sum + p[location];
pos_count = pos_count + 1;
totcount = totcount + 1;
}
else
{
neg_sum = neg_sum + p[location];
neg_count = neg_count + 1;
totcount = totcount + 1;
}
location++;
}
//Calculations
avg = sum / pos_count;
neg_avg = neg_sum / neg_count;
total_sum = sum + neg_sum;
total_avg = total_sum / totcount;
fin.close();
//OUTPUT
cout << "The sum of all positive numbers is: " << sum << endl;
cout << "The average of all positive numbers is: " << setprecision(3) << avg << endl;
cout << "The sum of all negative numbers is: " << neg_sum << endl;
cout << "The average of all negative numbers is: " << setprecision(3) << neg_avg << endl;
cout << "The sum of all numbers is: " << total_sum << endl;
cout << "The average of all numbers is: " << setprecision(3) << total_avg << endl;
cout << "-------------------------------------------------" << endl;
cout << "Want us to read another file?\n";
cout << "Enter 'Y' or 'y' for yes, any other character for no." << endl;
cin >> answer;
} while ((answer == 'y') || (answer == 'Y'));
return 0;
}
Thank you to everyone who's pitched in. I wish I didn't have to use a dynamic array but unfortunately I won't receive if I don't implement one. I updated my code but I can't seem to get the array working properly as it does not seem to load the input from the file properly. Anything helps!
Well, the biggest I/O problem you have is attempting to read with while (!fin.eof()). See Why !.eof() inside a loop condition is always wrong.. The biggest logic problem you are having is including the //Calculations in the same loop you are reading your integers from your file.
Since you read and integer and are keeping a running sum of the positive and negative values, there is no need for a dynamic array at all. You are currently keeping pos_count, neg_count, and totcount which are all you need to compute the respective averages when you leave your read loop.
To tidy things up a bit, let's look at your variables. While you can use double for pos_count, neg_count, and totcount, it's better to use an unsigned type for a counter. C++ provides size_t as a preferred sizetype for counts and lengths, but it's not mandatory -- it just makes sense. While you can use a separate file and answer, it is better to read each input into a std::string to ensure a single keystroke (like the user typing "Yes" instead of 'Y') doesn't leave additional characters unread in stdin. You can also use the same std::string for both your file and answer and just check the if the first character is 'y' or 'Y' to control your read another file loop.
Putting that together, your variables could simple be:
int main (void) {
std::string buffer; /* use single buffer for filename & answer */
do
{ // Variables (will be reinitialized for each file)
int number; /* you are reading one number at a time */
size_t neg_count = 0, pos_count = 0, totcount = 0;
double avg, neg_avg, total_sum, total_avg, sum = 0., neg_sum = 0.;
(note: buffer to read the answer into is the only variable that must be declared before your do {...} while(); loop to be used as the test condition at the end)
If you remember nothing else, remember to validate every input, e.g.
std::cout << "Enter the file name: ";
if (!(std::cin >> buffer)) { // VALIDATE Input from User
std::cerr << "(user canceled input)\n";
return 1;
}
While you can check if the .fail() bit is set on the stream, a more general test is if the file stream goodbit is not set, e.g.
std::ifstream fin(buffer); // open file stream
if (!fin.good()) { // Check to see if file opens properly
std::cerr << "error: file open failed - " << buffer << ".\n";
return 1;
}
(note: either way will work)
When you read in a loop, condition your loop on a successful read. Your read loop here needs to be nothing more than:
while (fin >> number) { /* control read loop with read itself */
if (number >= 0) { /* handle positive numbers */
sum += number;
pos_count += 1;
}
else { /* if it's not >= 0, it's negative */
neg_sum = neg_sum + number;
neg_count = neg_count + 1;
}
totcount += 1; /* total count incremented each time */
}
fin.close();
That will capture all the information you need from your file. Now do the average calculations, but what happens if pos_count, neg_count, or totcount == 0. Dividing by zero is generally a really, really bad thing. Always validate your denominator, e.g.
// Calculations
if (pos_count > 0)
avg = sum / pos_count;
else
avg = 0;
if (neg_count > 0)
neg_avg = neg_sum / neg_count;
else
neg_avg = 0;
total_sum = sum + neg_sum;
if (totcount > 0)
total_avg = total_sum / totcount;
else
total_avg = 0;
Now for your output. How many times do you want to call cout for one continual block of output? (hint: once)
//OUTPUT (you only need one std::cout)
std::cout << "\nThe sum of all positive numbers is: "
<< sum << std::endl
<< "The average of all positive numbers is: "
<< std::setprecision(3) << avg << std::endl
<< "The sum of all negative numbers is: "
<< neg_sum << std::endl
<< "The average of all negative numbers is: "
<< std::setprecision(3) << neg_avg << std::endl
<< "The sum of all numbers is: " << total_sum << std::endl
<< "The average of all numbers is: " << std::setprecision(3)
<< total_avg << std::endl
<< "-------------------------------------------------\n\n"
<< "Want to read another file?\n"
<< "Enter 'Y' or 'y' for yes, any other character for no.\n";
That handles all your output needs in a single call (including your prompt for 'Y' or 'y'). Now just use the same std::string to take input on whether to continue or not, e.g.
if (!(std::cin >> buffer)) {
std::cerr << "(user canceled input)\n";
return 1;
}
/* condition on 1st char in buffer */
} while ((buffer.at(0) == 'y') || (buffer.at(0) == 'Y'));
}
That's it you are done. Putting it altogether, and replacing the fragile use of std::cin >> buffer with getline (std::cin, buffer) you would have:
#include <iostream>
#include <fstream>
#include <iomanip>
int main (void) {
std::string buffer; /* use single buffer for filename & answer */
do
{ // Variables (will be reinitialized for each file)
int number; /* you are reading one number at a time */
size_t neg_count = 0, pos_count = 0, totcount = 0;
double avg, neg_avg, total_sum, total_avg, sum = 0., neg_sum = 0.;
std::cout << "Enter the file name: ";
if (!getline(std::cin, buffer)) { // VALIDATE Input from User
std::cerr << "(user canceled input)\n";
return 1;
}
std::ifstream fin(buffer); // open file stream
if (!fin.good()) { // Check to see if file opens properly
std::cerr << "error: file open failed - " << buffer << ".\n";
return 1;
}
while (fin >> number) { /* control read loop with read itself */
if (number >= 0) { /* handle positive numbers */
sum += number;
pos_count += 1;
}
else { /* if it's not >= 0, it's negative */
neg_sum = neg_sum + number;
neg_count = neg_count + 1;
}
totcount += 1; /* total count incremented each time */
}
fin.close();
// Calculations
if (pos_count > 0)
avg = sum / pos_count;
else
avg = 0;
if (neg_count > 0)
neg_avg = neg_sum / neg_count;
else
neg_avg = 0;
total_sum = sum + neg_sum;
if (totcount > 0)
total_avg = total_sum / totcount;
else
total_avg = 0;
//OUTPUT (you only need one std::cout)
std::cout << "\nThe sum of all positive numbers is: "
<< sum << std::endl
<< "The average of all positive numbers is: "
<< std::setprecision(3) << avg << std::endl
<< "The sum of all negative numbers is: "
<< neg_sum << std::endl
<< "The average of all negative numbers is: "
<< std::setprecision(3) << neg_avg << std::endl
<< "The sum of all numbers is: " << total_sum << std::endl
<< "The average of all numbers is: " << std::setprecision(3)
<< total_avg << std::endl
<< "-------------------------------------------------\n\n"
<< "Want to read another file?\n"
<< "Enter 'Y' or 'y' for yes, any other character for no.\n";
if (!getline(std::cin, buffer)) {
std::cerr << "(user canceled input)\n";
return 1;
}
/* condition on 1st char in buffer */
} while ((buffer.at(0) == 'y') || (buffer.at(0) == 'Y'));
}
(note: getline (std::cin, buffer) has been used in the code above to make the user input a bit more robust -- see the the section below the example output for the reasons)
Example Use/Output
Testing with three files, the first a 50x5 set of positive integers, then next a set of 10 integers with one negative value (-2213) and the last a file of 100 mixed positive and negative values would give:
$ ./bin/pos_neg_total
Enter the file name: dat/50x5.txt
The sum of all positive numbers is: 122180
The average of all positive numbers is: 489
The sum of all negative numbers is: 0
The average of all negative numbers is: 0
The sum of all numbers is: 1.22e+05
The average of all numbers is: 489
-------------------------------------------------
Want to read another file?
Enter 'Y' or 'y' for yes, any other character for no.
y
Enter the file name: ../../..//src-c/tmp/dat/10int_nl.txt
The sum of all positive numbers is: 2.03e+05
The average of all positive numbers is: 786
The sum of all negative numbers is: -2.21e+03
The average of all negative numbers is: -2.21e+03
The sum of all numbers is: 2.01e+05
The average of all numbers is: 774
-------------------------------------------------
Want to read another file?
Enter 'Y' or 'y' for yes, any other character for no.
Y
Enter the file name: ../../../src-c/tmp/dat/100int.txt
The sum of all positive numbers is: 1.93e+06
The average of all positive numbers is: 5.55e+03
The sum of all negative numbers is: -2.29e+05
The average of all negative numbers is: -1.76e+04
The sum of all numbers is: 1.7e+06
The average of all numbers is: 4.71e+03
-------------------------------------------------
Want to read another file?
Enter 'Y' or 'y' for yes, any other character for no.
n
There are many, many ways to put this together, and you are free to use as many variables or calls to std::cout as you like, but hopefully this will help you think further along the lines of "What does my program require?".
Using >> for User-Input is Fragile
As a final note, know that using std::cin >> string for user-input is horribly fragile as any whitespace the user types as part of the input will not be read (and it will be left unread in stdin. It is far better to use getline which will read the complete line into your string. Don't mix using the >> iostream for input with getline without accounting for any '\n' that may be left in stdin. You can then use std::cin.ignore() to clear. In your case it would simply be more robust to take all user input with getline, e.g.
if (!getline(std::cin, buffer)) { // VALIDATE Input from User
std::cerr << "(user canceled input)\n";
return 1;
}
Then filenames with whtespace would be properly handled, and if the user wanted to type "Yes I want to enter another file!" as his answer to your continue question, that would pose no problem at all. If you haven't got there yet in your class, put it in your hip-pocket. For an experiment, try replacing both user inputs with what is shown above with your original std::cin >> buffer and see what happens if you type "Yes I want to enter another file!" at the prompt :)
Let me know if you have further questions.
So why you need a vector(dynamic array) to store the integers since your code can handle the all cases by add a "break" expression on the condition of EOF.
If you really need it, below is what you need:
#include<vector>
vector<int> my_vec;
Having trouble with the second if statement to only read ten values. If I remove the program will compile. I need it in for the assignment I have tried several modifications, so what is here may not reflect my last attempt. C++ homework compile error with if statement. Details how many more details do I need to add before this will post, more details
#include <iostream>
#include <fstream>
using namespace std;
/**********************************************************************
* Get File
* This function will prompt the user for the name of the file and
* return it.
*********************************************************************/
void getFileName(char fileName[])
{
//prompt the user
cout << "Please enter the filename: ";
cin >> filename;
ofstream fout(fileName);
}
/**********************************************************************
* Read
* This function will read the file and return the average score of the
* ten values.
*********************************************************************/
float readFile(char fileName[])
{
cout.setf(ios::fixed); //no scientific notation
cout.precision(0); //no decimals
//In case of error
ifstream fin(filename);
if (fin.fail())
{
cout << "Error reading file \"" << fileName << "\"" << endl;
exit(0);
}
float data; //always need a variable to store the data
float i = 0; //don't forget to initialize the variable
float gradeSum = 0;
float average;
//Add up all the grades
while (fin >> data) //while there was not an error
{
gradeSum += data; //do the work
i++;
}
// Hint: Make sure you only read ten values.
if (i != 10)
{
//tell the user what happened
cout < "Error reading file \"" << fileName << "\"" << endl;
exit(0);
}
//Calculate average grade
average = gradeSum / i;
//Close file
fin.close();
return average;
}
/**********************************************************************
* Display function
* This function will display the average score to zero decimals of
* accuracy.
*********************************************************************/
void display(float average)
{
cout << "Average Grade: " << average << "%" << endl;
}
/**********************************************************************
* main calls average grade and file name
***********************************************************************/
int main()
{
char fileName[256];
getFileName(fileName);
int average = readFile(fileName);
return 0;
}
Note the position of your if statement in relation to your while loop. When does your if statement run? When does your while loop run?
With these in mind, how would you adjust your while loop to take into consideration your restriction (while loop stops executing when i = 10)?
I hope this helps you better understand what you need to do without spoiling too much of the answer.
P.S. The contents of the if block will quit the program on the spot if i != 10, without executing anything beyond.
if (i != 10)
{
//tell the user what happened
cout < "Error reading file \"" << fileName << "\"" << endl;
exit(0);
}
Simple typo with regards to the stream operator.
This line:
cout < "Error reading file \"" << fileName << "\"" << endl;
Should be:
cout << "Error reading file \"" << fileName << "\"" << endl;
Also, you have other typos preventing your code from compiling: namely the mixed case usage of filename and fileName throughout. After I fixed those variable namings to be consistently fileName, it compiled.
your cout is invalid. cout << "Average Grade: " << average << "%" << endl; instead of "cout < Average Grade: " << average << "%" << endl;
I have a c++ program that is supposed to read data from a file into an array. Once the array is set up, the user inputs a row number they want displayed and the program is supposed to display the value stored in that row. The program successfully reads the data into the array but it doesn't display the value stored in the row, instead it displays the memory location. Here is the code I wrote:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
ifstream SeatPrices;
static const int NUM_ROWS = 15;
static const int NUM_SEATS = 30;
string SeatStructures[NUM_ROWS][NUM_SEATS];
double price[NUM_ROWS];
int rowRequested;
SeatPrices.open("SeatPrices.dat");
if (!SeatPrices)
cout << "Error opening SeatPrices data file.\n";
else
{
for (int rows = 0; rows < NUM_ROWS; rows++)
{
SeatPrices >> price[NUM_ROWS];
cout << endl << "Row " << (rows + 1) << ":\t";
cout << "$" << price[NUM_ROWS];
}
cout << endl << endl;
}
SeatPrices.close();
cout << "In which row would you like to find seats(1 - 15)? ";
cin >> rowRequested;
cout << fixed << showpoint << setprecision(2);
cout << "Price per seat: $" << price[rowRequested] << endl;
return 0;
}
It looks like you're reading all the data from the file into price[NUM_ROWS], which is one past the end of the array. Since you immediately cout this value, it'll look like the program is working. You probably want to read values into price[rows].
this is the code im working with, this is the first part, I want to get/count the number of rows and columns in the file, the program successfully counted the number of rows.... But the number of columns is wrong, it says its 0 when its suppose to be 26; can someone help me identify the issue?
// variable declarations
string LineA;
int x;
int col = 0;
int row = 0;
int arrayA[10][10] = { {0} };
//open files
fs_chola.open("CHOLAWCODE.xlsx"); //i'll convert this file to .csv later
if (fs_chola.is_open()){
cout << "chola file successfully opened\n";
}
if (fs_chola.fail()){
cerr << "file(chola) not found!"<< endl;
}
fs_master_menu.open("master_menu.csv");
if (fs_master_menu.is_open()){
cout << "master menu file successfully opened\n";
}
if (fs_master_menu.fail()){
cerr << "file(master menu) not found! " << endl;
}
// read file
while (fs_master_menu.good()){
while (getline(fs_master_menu, LineA)){
istringstream streamA(LineA);
while (streamA >>x){
arrayA[row][col] = x;
col++;
}
row++;
}
}
cout << "done \n";
// show colums and rows (checking to make sure everything is right)
cout << "number of rows: " << row << endl;
cout << "number of columns: " << col << endl;
system("PAUSE");
return 0;
}