How to get the average from data.txt file with C++? - c++

Our professor wants us to fix the code which counts the amount of values in a data.txt file and computes their average. Here is the code:
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
string s;
ifstream f;
int nItems;
double * data;
double sum=0;
vector < double > data2;
double item;
cout <<"File name: ";
cin >> s;
f.open (s.c_str() );
while (! f.eof() )
{
f >> item;
data2.push_back(item);
}
for (int i =0; i < nItems; i++)
{
sum += data[i];
}
cout << "The average is " << sum/nItems <<".\n";
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
His instructions were:
Modify code worked on today so that the average of data in vector < double > data is computed properly. Right now the code just gives you a value which isn't the average.
I tried changing the nItems variable into 12 and that seemed to work, but the goal of the code is to determine nItems and use that to find the average, which I can't seem to figure out.

You use data for which you haven't allocated any memory when you summarise That causes undefined behaviour. You've stored your values in data2. Remove variables you don't need. Also, using namespace std is considered bad practice.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric> // std::accumulate
int main(int, char**) {
std::string filename;
std::cout << "File name: ";
std::cin >> filename;
std::ifstream f(filename); // no need for .c_str()
std::vector<double> data;
double item;
// instead of checking for eof, check if extraction succeeds:
while(f >> item) {
data.push_back(item);
}
// a standard way to sum all entries in a container:
double sum = std::accumulate(data.begin(), data.end(), 0.);
std::cout << "The sum is " << sum << "\n";
// use the containers size() function. it returns the number of items:
std::cout << "The average is " << (sum / data.size()) << "\n";
}

Hey looks like you weren't reading the numbers in from the txt file.
Here I look through the input file once just to count how many numbers there are
so I can make the array.
Then I look through it again to fill the array.
#include <cstdlib>
#include <iostream>
#include <fstream>
// f here stands for find, fstream gives you files
using namespace std;
int main(int argc, char *argv[]) {
string s;
ifstream f;
// input file stream
int nItems;
double * data;
double sum=0;
cout << "File name: ";
cin >> s;
f.open (s.c_str() );
// s.c_str will return a char array equivalent of the string s
nItems=0;
int input =0;
while (f >> input) {//first loop reading through file to count number of items
nItems++;
}
f.close();
data = new double[nItems]; //Make the array
f.open (s.c_str() );//open file for second read
int i=0;
while (f >> input) {//Second loop through file fills array
data[i] = input;
i++;
}
f.close();
for (int i = 0; i < nItems; i++) {
sum += data[i];
}
cout << "The average is " << sum / nItems << ".\n";
cout << endl;
system("pause");
return 0;
}

Related

Changing size value for an array c++

Making a program that reads integers from a file and creates an array, I have that part completed however I am trying to figure out how to change the SIZE value depending on how many ints are in the file. This file has 15 integers but another file may have more and this array will not take in all the ints.
using namespace std;
const int SIZE = 15;
int intArray[SIZE];
void readData(istream& inFile) {
for (int i = 0; i < SIZE; i++){
inFile >> intArray[i];
cout << intArray[i] << " ";
}
}
int main() {
ifstream inFile;
string inFileName = "intValues.txt";
inFile.open(inFileName.c_str());
int value, count = 0;
while(inFile >> value){
count += 1;
}
cout << count;
readData(inFile);
return 0;
}
As you can see I have a while loop counting the number of ints in the file however when I assign that to the size value I was running into many different issues.
A fixed-sized array simply cannot be resized, period. If you need an array whose size can change at runtime, use std::vector instead.
More importantly, you are reading through the entire file just to count the number of integers, and then you are trying to read the values from where the previous loop left off. You are not seeking the ifstream back to the beginning of the file so you can re-read what you have already read.
Try something more like this instead:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main() {
string inFileName = "intValues.txt";
ifstream inFile(inFileName.c_str());
int value, count = 0;
while (inFile >> value){
++count;
}
cout << count;
std::vector<int> intArray;
intArray.reserve(count);
inFile.seekg(0);
while (inFile >> value){
intArray.push_back(value);
cout << value << " ";
}
// use intArray as needed...
return 0;
}
Alternatively, don't even bother counting the integers, just let the std::vector grow as needed, eg:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main() {
string inFileName = "intValues.txt";
ifstream inFile(inFileName.c_str());
vector<int> intArray;
int value;
while (inFile >> value){
intArray.push_back(value);
cout << value << " ";
}
// use intArray as needed...
// you an get the count from intArray.size()
return 0;
}

Reading a text file into a vector from the command line

Whenever I try to see the contents inside the vector I get "segmentation fault" any idea why that is? Do I not read in the values properly?
#include <iostream>
#include <cstdlib> // atoi function
#include <vector>
#include <fstream>
using namespace std;
vector<int> list ; // global vector
int main (int args , char * argv[])
{
ifstream in(argv[1]);
//ofstream out(argv[2]);
int listSize = atoi (argv[2]);
cout << listSize << endl;
int i = 0;
cout << argv[1] << endl;
in.open(argv[1]);
while (i < listSize)
{
in >> list[i];
cout << "test2" << endl;
i++;
}
in.close();
for( int k=0; k <listSize; k++){
cout<< list[k] << endl;
}
return 0;
}
the text file contains these numbers:
5 6 7 11 12 13
A vector doesn't automatically come with slots. You have to either reserve slots or use push_backto append items to the vector:
//...
int value;
in >> value;
list.push_back(value);
Read what's in the file using getline. See sample code below:
ifstream InFile(argv[1], ios::in); /*Open file from arg[1]*/
std::string LineContent;
getline(InFile, LineContent); /*Save line per line */
With your line saved in a string, you can now transfer the data from that string to the vector, see:
vector<int> list;
list.push_back(atoi(LineContent.c_str()));
Now, you can print out what's in the file:
for (int i = 0; i < list.size(); i++)
cout << list[i] << endl;

Read a .txt file, calculate sum and mean

I have a .txt file which contains numbers and looks like this:
1
2
3
etc
The numbers are unimportant but they all start on a new line.
I want to then find the sum & mean of the numbers in the text file.
Here's what I have so far:
#include<cmath>
#include<cstdlib>
#include<iomanip>
#include<string>
#include<fstream>
using namespace std;
int main(int argc, char * argv[])
{
std::fstream myfile("numbers.txt", std::ios_base::in);
float a;
while (myfile >> a)
{
printf("%f ", a);
}
getchar();
return 0;
int sum(0);
int sumcount(0);
double average(0);
int even(0);
int odd(0);
ifstream fin;
string file_name;
int x(0);
cout<<"numbers.txt";
cin>> file_name;
fin.open(file_name.c_str(),ios::in);
if (!fin.is_open())
{
cerr<<"Unable to open file "<<file_name<<endl;
exit(10);
}
fin>>x;
while (!fin.fail())
{
cout<<"Read integer: "<<x<<endl;
fin>>x;
sum=sum+x;
sumcount++;
if(x%2==0)
even++;
else
odd++;
}
fin.close();
average=(double)sum/sumcount;
cout<<"Sum of integers: "<<sum<<endl;
cout<<"Average: "<<average<<endl;
cout<<"Number of even integers: "<<even<<endl;
cout<<"Number of odd integers: "<<odd<<endl;
return 0;
}
The start loads the numbers but it won't execute the next step.
i have looked at a lot of other code and tried to implement other ideas to solve the problem; however, some people use loops and arrays and other things and I'm not sure which to use.
How can I get my program to find the sum and mean of numbers in the file?
also any other links for help would be appreciated
EDIT: although the numbers are intergers the mean may not be
Here is your working code.
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char * argv[])
{
std::fstream myfile("numbers.txt", std::ios_base::in);
float a = 0;
myfile >> a;
while (!myfile.fail())
{
printf("%f ", a);
myfile >> a; // here you dispay your numbers
}
getchar(); // waiting for input
float sum(0);
int x(0);
int sumcount(0);
double average(0);
int even(0);
int odd(0);
ifstream fin;
string file_name;
cout<<"numbers.txt" << endl;
cin>> file_name; // waiting for enter file name
fin.open(file_name.c_str(),ios::in);
if (!fin.is_open())
{
cerr<<"Unable to open file "<<file_name<<endl;
exit(10);
}
fin >> x;
while (!fin.fail())
{
cout<<"Read integer: "<<x<<endl; // display number again
sum=sum+x;
sumcount++;
if(x % 2==0) // compuing your file statistics
even++;
else
odd++;
fin>>x;
}
fin.close();
average=(double)sum/sumcount;
cout<<"Sum of integers: "<<sum<<endl; // displaying results
cout<<"Average: "<<average<<endl;
cout<<"Number of even integers: "<<even<<endl;
cout<<"Number of odd integers: "<<odd<<endl;
return 0;
}
I have added some minimal alteration to make your program work correctly.
the result
and more
As soon as your main function encounters the statement return 0 it will exit the program and fail to execute the remaining code. This should generally appear only once in your main function, at the end of your code block
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int n=0;
int sum=0,total=0;
fstream file("numbers.txt");
while(file >> n) // or while(cin >> n) to read from stdin, commandline
{
sum += n;
total++;
}
int average = (float) sum/total;
cout<<"sum: " << sum << endl;
cout << "average: " << average << endl;
return 0;
}
#include <iostream>
#include<fstream>
int main()
{
std::ifstream txtFile;
txtFile.open("data.txt");
//TODO: check if the file fails to open.
double tempNum, mean(0.0), sum(0.0), count(0.0);
while (txtFile >> tempNum)
{
sum += tempNum;
++count;
}
mean = sum/count;
std::cout << "mean: " << mean << " sum: " << sum << std::endl;
return 0;
}

I want to calculate total and average of data from text file using C++

I want to calculate total and average of data from text file using C++.
Here is my code and text file.
This code is not showing anything on run
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
using namespace std;
string double2string(double);
double string2double(string);
int main(int argc, char* argv[]){
fstream dfile;
string s1;
string amount;
double damount;
double sum = 0;
dfile.open(argv[1]);
dfile >> amount;
damount = string2double(amount);
while(damount){
sum = sum + damount;
}
string total = double2string(sum);
dfile.clear();
dfile.close();
cout << total;
return 0;
}
Functions to convert string to double and double to string
string double2string(double d){
ostringstream outstr;
outstr << setprecision(2) << fixed << setw(10) << d;
return outstr.str();
};
double string2double(string s1){
istringstream instr(s1);
double n;
instr >> n;
return n;
}
Here is my text file "data.txt"
234
456
789
You need to use a while loop. You're reading in only one line, so you need to make sure that you keep reading in lines until the end of the file.
Also, you might want to use a standard library function: std::stoi is the C++11 and onward version that works for std::string, but std::atoi from <cstdlib> works just as well with std::string.c_str().
#include <iostream>
#include <fstream>
#include <string>
//Compile with C++11; -std=c++11
int main(int argc, char** argv) {
std::fstream file;
//Open the file
file.open(argv[1]);
std::string buffer = "";
int sum = 0;
int n = 0;
//Check for file validity, and keep reading in line by line.
if (file.good()) {
while (file >> buffer) {
n = std::stoi(buffer);
sum += n;
}
std::cout << "Sum: " << sum << std::endl;
} else {
std::cout << "File: " << argv[1] << "is not valid." << std::endl;
}
return 0;
}

C++ program to read a txt file and sort data

I'm a physics PhD student with some experience coding in java, but I'm trying to learn C++.
The problem I'm trying to solve is to read in data from a .txt file and then output all the numbers > 1000 in one file and all those <1000 in another.
What I need help with is writing the part of the code which actually reads in the data and saves it to an array. The data itself is only separated by a space, not all on a new line, which is confusing me a bit as I don't know how to get c++ to recognise each new word as an int. I have canabalised some code I have got from various sources online-
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include<cmath>
using namespace std;
int hmlines(ifstream &a) {
int i=0;
string line;
while (getline(a,line)) {
cout << line << endl;
i++;
}
return i;
}
int hmwords(ifstream &a) {
int i=0;
char c;
a >> noskipws >> c;
while ((c=a.get()) && (c!=EOF)){
if (c==' ') {
i++;
}
}
return i;
}
int main()
{
int l=0;
int w=0;
string filename;
ifstream matos;
start:
cout << "Input filename- ";
cin >> filename;
matos.open(filename.c_str());
if (matos.fail()) {
goto start;
}
matos.seekg(0, ios::beg);
w = hmwords(matos);
cout << w;
/*c = hmchars(matos);*/
int RawData[w];
int n;
// Loop through the input file
while ( !matos.eof() )
{
matos>> n;
for(int i = 0; i <= w; i++)
{
RawData[n];
cout<< RawData[n];
}
}
//2nd Copied code ends here
int On = 0;
for(int j =0; j< w; j++) {
if(RawData[j] > 1000) {
On = On +1;
}
}
int OnArray [On];
int OffArray [w-On];
for(int j =0; j< w; j++) {
if(RawData[j]> 1000) {
OnArray[j] = RawData[j];
}
else {
OffArray[j] = RawData[j];
}
}
cout << "The # of lines are :" << l
<< ". The # of words are : " << w
<< "Number of T on elements is" << On;
matos.close();
}
But if it would be easier, i'm open to starting the whole thing again, as I don't understand exactly what all the copied code is doing. So to summarise, what I need is it to-
Ask for a filepath in the console
Open the file, and store each number (separated by a space) as an element in a 1D array
I can manage the actual operations myself I think, if I could just get it to read the file the way I need.
Thanks very much
Using C++11 and the Standard Library makes your task fairly simple. This uses Standard Library containers, algorithms, and one simple lambda function.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <vector>
int main()
{
std::string filename;
std::cout << "Input filename- ";
std::cin >> filename;
std::ifstream infile(filename);
if (!infile)
{
std::cerr << "can't open " << filename << '\n';
return 1;
}
std::istream_iterator<int> input(infile), eof; // stream iterators
std::vector<int> onvec, offvec; // standard containers
std::partition_copy(
input, eof, // source (begin, end]
back_inserter(onvec), // first destination
back_inserter(offvec), // second destination
[](int n){ return n > 1000; } // true == dest1, false == dest2
);
// the data is now in the two containers
return 0;
}
Just switch the type of variable fed to your fistream, created from new std:ifstream("path to file") into a int and c++ will do the work for you
#include <fstream> //input/output filestream
#include <iostream>//input/output (for console)
void LoadFile(const char* file)
{
int less[100]; //stores integers less than 1000(max 100)
int more[100]; //stores integers more than 1000(max 100)
int numless = 0;//initialization not automatic in c++
int nummore = 0; //these store number of more/less numbers
std::ifstream File(file); //loads file
while(!file.eof()) //while not reached end of file
{
int number; //first we load the number
File >> number; //load the number
if( number > 1000 )
{
more[nummore] = number;
nummore++;//increase counter
}
else
{
less[numless] = number;
numless++;//increase counter
}
}
std::cout << "number of numbers less:" << numless << std::endl; //inform user about
std::cout << "number of numbers more:" << nummore << std::endl; //how much found...
}
This should give you an idea how should it look like(you shoudnt use static-sized arrays tough) If you got any probs, comment back
Also, please try to make nice readable code, and use tabs/ 4 spaces.
even though its pure C, this might give you some hints.
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#define MAX_LINE_CHARS 1024
void read_numbers_from_file(const char* file_path)
{
//holder for the characters in the line
char contents[MAX_LINE_CHARS];
int size_contents = 0;
FILE *fp = fopen(file_path, "r");
char c;
//reads the file
while(!feof(fp))
{
c = fgetc(fp);
contents[size_contents] = c;
size_contents++;
}
char *token;
token = strtok(contents, " ");
//cycles through every number
while(token != NULL)
{
int number_to_add = atoi(token);
//handle your number!
printf("%d \n", number_to_add);
token = strtok(NULL, " ");
}
fclose(fp);
}
int main()
{
read_numbers_from_file("path_to_file");
return 0;
}
reads a file with numbers separated by white space and prints them.
Hope it helps.
Cheers