Im trying to calculate the average out of a couple of number inside an char array. The reason for this is that i imported data from a text document and i made it read only every 2nd line to get the numbers that i wanted.
Now i need to get the average out of these numbers but i cant make it work. I'm starting to get mad about this and i feel that the solution would be rather simple.
EDIT:
The file consists of names and numbers. I.e:
Jason Smith
32
Mary Jane
52
Stevie Wonder
68
Micheal Jackson
59
#include <fstream>
#include <iostream>
using namespace std;
double averageNum(char array[], int size) { // A function to calculate the average number
int sum = 0;
double avg;
for(int i=0; i<size; i++){
array[i]+= sum;
}
avg = sum / size;
return avg;
}
int main(){
char age [50][30];
double avg;
int rows = 0;
ifstream elevInfo("elevinfo.txt"); // Opens a stream to get data from the document
if (! elevInfo){ // Error message if the file couldn't be found
cout << "Could not find the file elevinfo.txt" << endl;
return (1);
}
while(elevInfo.getline(age[rows/2], 30)){ // Reading every 2nd line to an array
rows++;
}
avg = averageNum(age[], rows); // Function call with the numbers from the array and the variable rows as a pointer
cout << "Average age equals: " << avg << endl;
}
this is one of many possible solutions for your problem:
int main()
{
// Opens a stream to get data from the document
ifstream elevInfo("elevinfo.txt");
// Error message if the file couldn't be found
if (!elevInfo)
{
cout << "Could not find the file elevinfo.txt" << endl;
return (1);
}
int sum = 0;
int lineCounter = 0;
// loop till end of file
while (!elevInfo.eof())
{
// prepare buffer
char line[30];
// read line into buffer
elevInfo.getline(line, 30);
// do this every second line
if (lineCounter % 2 == 1)
{
// get age as int using function atoi()
int age = atoi(line);
// increase sum by the current age
sum += age;
}
// increment line-counter
lineCounter++;
}
// calculate the average
// divide lineCounter by 2 because only every second line in your file contains an age
double avg = sum / (lineCounter / 2.0);
cout << "Average age equals: " << avg << endl;
return 0;
}
As you can see it also doesn't need the function averageNum.
Related
I am trying to expand on previous code by implementing 2D-array's, however I keep getting issues with the console not outputting the correct values. The console is not taking in the right values when calculating the average and outputs 0 instead of the expected value. When running the code, the section where it would display the High and the Low scores would always display the first number that was typed in.
There are restrictions to work under.
Adjust the logic to drop the high score and the low score and average the remaining three scores for each student. The student grade is based on the average of the 3 middle scores.
All data is read in from the keyboard.
Two global constants may be utilized: one for the number of students and one for the number of tests.
Display in a table format the student's name, 5 test scores, average, and grade. Include a header in the table to label each column respectively.
Use iomanip and setw() to format the output.
Main should consist of variable declarations and function calls. This means the for loops to process the arrays resides in the functions, not in main.
Has to follow the base code.
`
using namespace std;
const int SCORES = 5;
const int NUM_STUDENTS = 3;
int main()
{
string name[NUM_STUDENTS];
int test[NUM_STUDENTS][SCORES];
char grade[NUM_STUDENTS];
float avg{};
int total = 0;
int hiIndex{}, loIndex{};
calcData(name, test, grade, total, hiIndex, loIndex, avg);
//display results
displayResults(name, test, grade, avg, loIndex, hiIndex);
system("pause");
return 0;
}
void calcData(string name[], int test[][SCORES], char grade[], int total, int hiIndex, int loIndex, float& avg)
{
for (int counter = 0; counter < NUM_STUDENTS; counter++)
{
getInput(name, test, counter, total);
cin.ignore();
//find index of the highest score and lowest score
findHiAndLow(test, hiIndex, loIndex, counter);
//assign letter grade
assignGrade(avg, grade, counter);
//calculate the class average
calcAvg(total - (test[counter][hiIndex] + test[counter][loIndex]), avg, SCORES - 2);
}
}
void getInput(string arrOne[], int arrTwo[][SCORES], int size, int& t)
{
//get student name
cout << "Input the student name and press enter\n";
getline(cin, arrOne[size]);
for (int i = 0; i < SCORES; i++)
{
//get student test score
cout << "Input the score for the midterm test\n";
cin >> arrTwo[size][i];
//(accumulate scores) total of all scores
t += arrTwo[size][i];
}
cout << endl;
}
int findHiAndLow(int t[][SCORES], int& h, int& l, int row)
{
for (int i = 0; i < SCORES; i++)
{
if (t[row][h] < t[row][i])
h = row;
if (t[row][l] > t[row][i])
l = row;
}
return h, l;
}
float calcAvg(int t, float a, int size)
{
a = static_cast<float>(t) / size;
return a;
}
void displayResults(string n[], int t[][SCORES], char g[], float a, int low, int high)
{
for (int counter = 0; counter < NUM_STUDENTS; counter++)
{
cout << left << setw(10) << n[counter] << ":";
for (int i = 0; i < SCORES; i++)
{
cout << setw(10) << t[counter][i];
}
cout << endl;
}
cout << "\n\nThe class average for this test = " << a << endl << endl;
for (int i = 0; i < NUM_STUDENTS; i++)
{
cout << n[i] << " your highest test score = " << t[i][high] << endl;
cout << n[i] << " your lowest test score = " << t[i][low] << endl << endl;
}
}
`
The expected outcome was for the program to take the average of the 3 middle scores that are left after dropping both the high and low scores from the initial 5 scores that are given. I have tried rearranging the values in both findHiandLow() and getInput(). I have tried having both for loops for getInput() within the function and have switched back to having one on the outside (within calcData()) to include the other functions, with the intent of having it loop for each student.
I wanted the console to print out the average of the three middle scores and not include the High and low, I was also expecting the console to print out the High and low scores for the student but it only prints the first score.
If my numbers were, for example, 12, 89, 45, 100, 23; The expectation would've been that it would drop the 12 and 100 and leave me with 89, 45, and 23. It would then take the average of those 3 numbers which in theory should result in 52.34 and result in an "F", however it prints out 0. and because the number that was first typed in was 12 the lowest and highest number would be listed as 12. It should have been 12 and 100 respectively.
This is another case of the incredibly common newbie confusion over returning values from functions.
This is your function
float calcAvg(int t, float a, int size)
{
a = static_cast<float>(t) / size;
return a;
}
You are trying to calculate the average and return the result, but for some reason you have declared a as a parameter, instead of as a local variable. This is how it should look
float calcAvg(int t, int size)
{
float a = static_cast<float>(t) / size;
return a;
}
Once you see that you should see that it can be further simplified, eliminating a altogether
float calcAvg(int t, int size)
{
return static_cast<float>(t) / size;
}
Now look at how you call calcAvg.
calcAvg(total - (test[counter][hiIndex] + test[counter][loIndex]),
avg, SCORES - 2);
you are calling the function, but doing nothing with the returned value. This is how it should look
avg = calcAvg(total - (test[counter][hiIndex] + test[counter][loIndex]),
SCORES - 2);
Now the return value of calcAvg is being assigned to the variable avg changing it's value. This is clearly what you intended. If you want to change the value of a variable using a functions return value the syntax is x = func(); not func(x).
Really not sure why this is such a stumbling block for newbies. The correct code has always seemed natural and straightforward to me. But, in any case, remember that parameters and return values are different things, with different syntax, and different purposes.
my task is to write a program to read a file called countries.txt which contains a number of countries and their respective land areas and then display the country with the largest and smallest land areas. I am having trouble displaying the country with the smallest land area and would be more then grateful if someone is able to show me how to do it.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream ins; // declare an input file stream object
ins.open("/Users/daneided/Desktop/countries.txt"); // open the file by pasting the path
if (ins.fail()) { // program to check if the file failed to open
cout << "Error opening file";
return -1;
}
string biggestCountry; // name of the biggest country
int biggestArea = 0; // the country with the biggest area
for (int i = 0; i < 5; i++) { // read five lines from the file
string countryName;
int area;
ins >> countryName >> area; // read 2 variables from the stream line
if (area > biggestArea) { // update the current maximum if greater
biggestArea = area;
biggestCountry = countryName;
}
}
ins.close(); // close the file
cout << "Biggest country is: " << biggestCountry <<
" (" << biggestArea << ") " << endl;
return 0;
}
Try adding this belkow your if for the biggest country, you should get the hang of it from here:
int smallestArea = biggestArea; /* because you need a default value that is greater then the minimum area of the smallest country */
if (area < smallestArea) {
smallestArea = area;
smallestCountry = countryName;
}
I am a beginner in c++ coding and i have an assignment for my class. I am trying to read the first line of integers separated by spaces 2 spaces in the file (cannot use arrays or vectors). I have seen many tutorials telling me to use getline () and simply reading each and every integer and storing it into its own variable, but neither method has been working for me. Does anybody have a way to read in the first line with a while loop and have it so that I can then find the maximum and minimum values from the line, as well as calculate the average EXCLUDING the maximum and minimum values?
sample input i was instructed to analyze is as follows
5 7 9 8 7
30032
51111
52000
42000
9 8 6 3 7
70000
23765
24000
41004
Here is what I have so far.
{
void PrintIntro (); {
cout << "*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-" <<endl;
cout << "Welcome to Tallahassee Idol! Where Stars are Born!!!" <<endl;
cout << "*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-" <<endl<<endl;
}
/*******************************************************************************/
void OpenFile (); {
ifstream myFile; // filestream for input file
string fileName; // string for user to input filename
cout <<"Enter a valid filename (no blanks please): ";
cin >> fileName;
myFile.open(fileName);
while (!myFile) {
cout << "Please re-enter a valid filename: "<<endl<<endl;
cin >> fileName;
myFile.open(fileName);
}
}
/*******************************************************************************/
void GetJudgeScore1 (); {
ifstream myFile; // filestream for input file
string fileName; // string for user to input filename
int player1Total = 0; // total score for player 1
int player1Average = 0; // average for player 1
int highScore1 = 0; // highest score to be excluded
int lowScore1 = 100; // lowest score to be excluded
const int judgeAmt = 5;
cout << "Processing Judge Data for Contestant 1" <<endl;
cout << "=====================================" <<endl;
cout << "Judge scores are: ";
if (myFile.is_open()){ // if the file is open, read data in
// here is where i ran into problems
}
}
return 0;
}
You can use a combination of std::string and std::istringstream and std::getline to iterate through the different integers in the line as shown below. The explanation is given in the comments.
#include <iostream>
#include<string>
#include <sstream>
#include <fstream>
#include <climits>
int main()
{
std::string line;//for storing a single line
int max = INT_MIN, min = INT_MAX, num = 0, count =0;
std::ifstream inFile("input.txt");
if(inFile)
{
while(std::getline(inFile, line))//go line by line
{
std::istringstream ss(line);
while(ss >> num)//go number by number
{
if(num > max)
{
max = num;//update the maximum
}
if(num < min)
{
min = num; //update the minimum
}
++count;
}
//you can add an if statement here to print the result only if count > 1
std::cout<<"max is: "<<max<<std::endl;
std::cout<<"min is: "<<min<<std::endl;
count = 0; //make the count 0 for next iteration
max = INT_MIN; //reset max
min = INT_MAX; //reset min
std::cout<<"----------------------"<<std::endl;
}
}
else
{
std::cout<<"input file cannot be opened"<<std::endl;
}
return 0;
}
The output of the above program can be seen here:
max is: 9
min is: 5
----------------------
max is: 30032
min is: 30032
----------------------
max is: 51111
min is: 51111
----------------------
max is: 52000
min is: 52000
----------------------
max is: 42000
min is: 42000
----------------------
max is: 9
min is: 3
----------------------
max is: 70000
min is: 70000
----------------------
max is: 23765
min is: 23765
----------------------
max is: 24000
min is: 24000
----------------------
max is: 41004
min is: 41004
----------------------
Method 2
By looking at your comments below, it seems you do not want(or not allowed) to use climits. The below program shows how you can find the max and min without using climits.
#include <iostream>
#include<string>
#include <sstream>
#include <fstream>
int main()
{
std::string line;//for storing a single line
std::string numWord; //for storing a single number as std::string
int max = 0, min = 0, num = 0, count =0;
std::ifstream inFile("input.txt");
if(inFile)
{
while(std::getline(inFile, line))//go line by line
{
std::istringstream ss(line);
//read the first number in max and min
ss >> max;
min = max;
while(ss >> num)//go number by number
{
if(num > max)
{
max = num;//update the maximum
}
if(num < min)
{
min = num; //update the minimum
}
++count;
}
//you can add an if statement here to print the result only if count > 1
std::cout<<"max is: "<<max<<std::endl;
std::cout<<"min is: "<<min<<std::endl;
count = 0; //make the count 0 for next iteration
max = 0; //reset max
min = 0; //reset min
std::cout<<"----------------------"<<std::endl;
}
}
else
{
std::cout<<"input file cannot be opened"<<std::endl;
}
return 0;
}
The output of the above program can be seen here.
Note
Since this is a homework problem, i am skipping finding out the average of the numbers so that you can modify the above program accordingly and so that i don't give the whole solution myself. Note that since your requirement is that not to use std::vector or arrays, i haven't used them in my program.
Hint:(for finding average) Add a variable called sum or average and add value of variable num to it inside the while loop.
I am unsure as to what you mean by "cannot use arrays or vectors." The following code will read each line and save it to a string, convert it, and add it to an integer array, for easier storage. You could use multiple variables instead.
#include <fstream>
#include <string>
void getData() {
std::string output;
int i = 0, data[10]; // Pre-defined array size, looking at your data set.
std::ifstream myFile;
myFile.open("Path\\To\\Your\\File.txt", ios::in);
while(getline(myFile, output))
{
data[i] = std::stoi(output);
i++;
std::cout << data[i] << "\n";
}
myFile.close();
}
Output:
57987
30032
51111
52000
42000
98637
70000
23765
24000
41004
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
const int NUMBER = 20;
void dataRead(double a[], int size, double& data);
double averageArray(const double a[], double data);
double totalArray(const double a[], double data);
double highCost(const double a[], double data);
double lowCost(const double a[], double data);
int main()
{
// Calling in the file
ifstream in;
char in_file[16];
double data;
double averageSales, higherSale, lowerSale, totalSales, salesData[NUMBER];
cout << "Enter the input file name." << endl;
cin >> in_file;
in.open(in_file);
// Incase the file doesnt open
if(in.fail())
{
cout << "File not found." << endl;
exit(1);
}
// For calling the answers from the formula functions
totalSales = totalArray(salesData, data);
cout << endl << "The total sales are $" << totalSales << endl;
averageSales = averageArray(salesData, data);
cout << "The average sales amount is $" << averageSales << endl;
higherSale = highCost(salesData, data);
cout << "The highest sales amount is $" << higherSale << endl;
lowerSale = lowCost(salesData, data);
cout << "The lowest sales amount is $" << lowerSale << endl;
return 0;
}
// Formula functions used for values
double totalArray(const double sales[], double n)
{
double sum = 0;
for(int count = 0; count < n; count++)
sum += sales[count];
return(sum);
}
double averageArray(const double sales[], double n)
{
return((double)totalArray(sales, n));
}
double highCost(const double sales[], double n)
{
double highest;
highest = sales[0];
for(int count = 1; count < n; count++)
if(highest < sales[count])
highest = sales[count];
return(highest);
}
double lowCost(const double sales[], double n)
{
double lowest;
lowest = sales[0];
for(int count = 1; count < n; count++)
if(lowest > sales[count])
lowest = sales[count];
return(lowest);
}
void readData(int a[], int size, double& data)
{
}
I am having trouble getting my program to read files and calculate the data for answers.. It is supposed to take in a file and return specific values pertaining to what is in the file. Like the average, highest cost value, lowest cost value, and total values together. I am compiling this on c9.io and when I added a new file to grab the information from no matter what values I put in the file it just gives me zeros or weird numbers with remainders. Would appreciate some guidance! Thank you!
You open the file, but never read anything from it (nor close it, for that matter). You read from in in a similar way that you read from in, and this describes how to close: How to close IStream?.
I don't see a line that would actually read the data in the file, you're just opening it.
How to read the contents of a file
If your file has just plain numbers and whitespace in it, like "69 10 38 33 (...)", you'll want to read them like that:
int number;
file>>number;
cout<<number<<endl;
file>>number;
cout<<number<<endl;
- the example program will output the following:
69
10
When your file is written to be more "human-readable", like:
Value1 - 69
Value2 - 10
etc.
it gets tricky. I would recommend just changing the file to the " 69 10 ..." format. If you really want to keep it like that, you could read the values to a string - just as you would with numbers - and check if it's numerical. If yes, convert it to an int using stringstream. These 2 functions may help you
#include <sstream>
int StringToInt(string input)
{
int res;
stringstream ss(input);
ss>>res;
return res;
}
bool IsNumeric(string input)
{
for(int i=0; i<input.size(); i++)
{
if(input[i] < '0' && input[i] > '9')
return false;
}
return true;
}
And by the way: you can't pass arrays to a function like you tried to do.
I'm supposed to write a program that reads student IDs and grades from a file, with 3 functions:
getResults: this function reads from the file and counts how many failed (if score < 55) calculates the average and returns the number of students.
display: displays everything to the screen
isF: checks whether the score is less than 55 and returns true if it is. (In other words, if the student failed it will return true.)
My program is working fine up to the checking how many failed. I'm almost certain its a logical error but I can't figure out where. The number of failed students is not being calculated correctly. I keep getting 1 when it is supposed to be 2 as per the sample file.
#include <iostream>
#include <fstream>
using namespace std;
int getResults(ifstream &input, int &failed, double &average);
bool isF(int score);
void display(int num_students, double average, int num_failed);
int main() {
int numfailed, numOfStudents;
double avg;
ifstream in_stream("grades.txt");
numOfStudents = getResults(in_stream, numfailed, avg);
display(numOfStudents, avg, numfailed);
system("PAUSE");
return 0;
}
int getResults(ifstream &input, int &failed, double &average) {
int studentID, studentGrade, total = 0, numberOfStudents = 0;
while (input >> studentID >> studentGrade) {
total = total + studentGrade;
numberOfStudents = numberOfStudents + 1;
failed = isF(studentGrade);
}
average = total / numberOfStudents;
return numberOfStudents;
}
bool isF(int score) {
if (score < 55)
return true;
else
return false;
}
void display(int num_students, double average, int num_failed) {
cout << "Number of Students: " << num_students << endl;
cout << "Class Average: " << average << endl;
cout << "Number of students failed: " << num_failed << endl;
}
My sample file is as follows:
- 333 95
- 123 40
- 111 88
- 121 70
- 110 55
- 909 45
Sample output:
Number of students: 6
Class Average: 65
Number of students failed: 2
The output I'm getting is exactly the same except that I get 1 student failed.
First initialise your numfailed to 0 (thanks # Peter), then change this:
failed = isF(studentGrade);
To this:
failed += isF(studentGrade);
Or this:
failed += isF(studentGrade) ? 1 : 0;
There are two things you need to change. First initialize failed in your function to zero and then modify to add the count of failures. Here is the modified function:
int getResults(ifstream &input, int &failed, double &average)
{
int studentID, studentGrade, total = 0, numberOfStudents = 0;
failed = 0;
while (input >> studentID >> studentGrade)
{
total = total + studentGrade;
numberOfStudents = numberOfStudents + 1;
failed += isF(studentGrade); //this ensures that every time a student fails, it is added
}
average = total / numberOfStudents;
return numberOfStudents;
}