this is my program for reading data from a text file and storing it into a vector, im having trouble compiling this, any suggesting would be great.
id like to in this example to call all the data for year and month.
im hoping its something simple ive missed.
#include <iostream>
#include <libscat.h>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
struct Weather
{
int year;
int month;
double tempmax;
double tempmin;
};
int main()
{
vector<Weather> data_weather;
string line;
std::ifstream myfile ("weatherdata.txt");
if (myfile.is_open())
{
while ( getline(myfile, line) )
{ int count = 0;
if (count > 8)
{
std::istringstream buffer(line);
int year, mm;
double tmax, tmin;
if (buffer >> year >> mm >> tmax >> tmin)
{
Weather objName = {year, mm, tmax, tmin};
data_weather.push_back(objName);
count++;
}
}
for (auto it = data_weather.begin(); it != data_weather.end(); it++){
std::cout << it->year << " " << it->month << std::endl;}
myfile.close();
}
else
{
cout << "unable to open file";
}
scat::pause("\nPress <ENTER> to end the program.");
return 0;
}
}
Here's a fixed version with explanation since there still wasn't any real answer.
#include <iostream>
#include <libscat.h>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
struct Weather
{
int year;
int month;
double tempmax;
double tempmin;
};
int main()
{
std::vector<Weather> data_weather;
std::string line;
std::ifstream myfile("weatherdata.txt");
if (myfile.is_open())
{
int count = 0; // you gotta put it in front of the while loop or you'll
// create a new variable and initialize it to 0 every time
// you enter the loop
while ( getline(myfile, line) )
{
// int count = 0; // placed it just before the loop
if ( count > 8)
{
std::istringstream buffer(line);
int year, mm;
double tmax, tmin;
if (buffer >> year >> mm >> tmax >> tmin)
{
Weather objName = {year, mm, tmax, tmin};
data_weather.push_back(objName);
// count++; // you're still inside the if (count > 8)
// you'd probably want to have it outsided the if statement
// instead.
}
}
++count; //the count from inside. it'll probably do what you wanted
//it to do here.
// you'll probably want to run the for loop AFTER the while loop
// when the data_weather vector got fully filled
}
// the for loop from inside the while now outside
for (auto it = data_weather.begin(); it != data_weather.end(); ++it)
{
std::cout << it->year << " " << it->month << std::endl;
myfile.close();
}
}
else
{
std::cout << "unable to open file";
}
scat::pause("\nPress <Enter> to end the program.");
return 0;
}
Related
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;
}
I am trying to read a csv file into C++, but I kept got the message that "Program ended with exit code:255". I tried restart the Xcode, restart the Mac, but it did not work. Is anyone have the same problem?
Here is my code:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <fstream>
using namespace std;
// defind the type of longitude and latitude as the key
typedef struct {
double lat;
double lon;
} location;
struct Stud{
location key;
string date;
double temp;
double concen;
string descrip;
};
int main()
{
int counter = 0;
string line;
Stud items;
ifstream file("data.csv");
if( !file.is_open()) {
cout << "File not found." << endl;
exit(-1);
}
while ( getline( file, line) ) { // To get the number of lines in the file
counter++;
}
Stud* item = new Stud[counter]; // Add number to structured array
for (int i = 0; i < counter; i++) {
file >> item[i].date >> item[i].key.lon>> item[i].key.lat>> item[i].temp >> item[i].concen >> item[i].descrip;
}
cout << item[1].date << endl;
file.close();
return 0;
}
I appreciate any help!
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
I need to read data from a text file, and insert the data in an array of struct. The data file is in the following format:
productname price quantity
my main concern is to read the product name, which consist of one, and two words. Should I approach product name as a c-string or as a string literal?
any help appreciated
#include <iostream>
#include <fstream>
using namespace std;
const int SIZE = 15; //drink name char size
const int ITEMS = 5; //number of products
struct drinks
{
char drinkName[SIZE];
float drinkPrice;
int drinkQuantity;
};
int main()
{
//array to store drinks
drinks softDrinks[ITEMS];
//opening file
ifstream inFile;
inFile.open("drinks.txt");
char ch;
int count = 0; //while loop counter
if(inFile)
{
while(inFile.get(ch))
{
//if(isalpha(ch)) { softDrinks[count].drinkName += ch; }
//if(isdigit(ch)) { softDrinks[count].drinkPrice += ch; }
cout << ch;
}
cout << endl;
count++;
}
else
{
cout << "Error opening file!\n";
system("pause");
exit(0);
}
system("pause");
return 0;
}
Since you ask for "any help", here's my view: Forget everything you wrote, and use C++:
#include <fstream> // for std::ifstream
#include <sstream> // for std::istringstream
#include <string> // for std::string and std::getline
int main()
{
std::ifstream infile("thefile.txt");
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
std::string name;
double price;
int qty;
if (iss >> name >> price >> qty)
{
std::cout << "Product '" << name << "': " << qty << " units, " << price << " each.\n";
}
else
{
// error processing that line
}
}
}
You could store each line of data in a std::tuple<std::string, int, double>, for example, and then put those into a std::vector as you go along.
I just want to read a text file and store the data into a vector. Thereby the value weight should be sum till the limit is reached. The first four lines will be read correctly but the following will not read. What is the mistake?
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <limits>
/*
Data.txt
John
6543
23
Max
342
2
A Team
5645
23
*/
struct entry
{
// passengers data
std::string name;
int weight; // kg
std::string group_code;
};
void reservations()
{
std::ofstream file;
file.clear();
file.open("reservations.txt");
file.close();
}
entry read_passenger(std::ifstream &stream_in)
{
entry passenger;
if (stream_in)
{
std::getline(stream_in, passenger.name);
stream_in >> passenger.weight;
std::getline(stream_in, passenger.group_code);
stream_in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return passenger;
}
return passenger;
}
int main(void)
{
std::ifstream stream_in("data.txt");
std::vector<entry> v; // contains the passengers data
const int limit_total_weight = 10000; // kg
int total_weight = 0; // kg
entry current;
while (!stream_in.eof())
{
current = read_passenger(stream_in);
total_weight = total_weight + current.weight;
std::cout << current.name << std::endl;
if (total_weight >= limit_total_weight)
{
break;
}
}
return 0;
}
These two lines,
std::getline(stream_in, passenger.group_code);
stream_in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
should be in the opposite order:
stream_in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(stream_in, passenger.group_code);
Think about what the purpose of the ignore is.
Also, instead of checking only for EOF, check for general error.
I.e., instead of
while (!stream_in.eof())
write
while (stream_in)
Maybe there's more wrong, but the above is what I saw immediately.
Cheers & hth.,
I try not to mix formatted and line-oriented input for precisely this reason. If it were me, and I had to use getline anywhere, I would use getline everywhere:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <limits>
#include <sstream>
struct entry
{
// passengers data
std::string name;
int weight; // kg
std::string group_code;
};
void reservations()
{
std::ofstream file;
file.clear();
file.open("reservations.txt");
file.close();
}
std::istream& operator>>(std::istream& stream_in, entry& passenger)
{
std::getline(stream_in, passenger.name);
std::string weightString;
std::getline(stream_in, weightString);
std::istringstream (weightString) >> passenger.weight;
std::getline(stream_in, passenger.group_code);
return stream_in;
}
void read_blankline(std::istream& stream_in) {
std::string blank;
std::getline(stream_in, blank);
}
int main(void)
{
std::ifstream stream_in("data.txt");
std::vector<entry> v; // contains the passengers data
const int limit_total_weight = 10000; // kg
int total_weight = 0; // kg
entry current;
while (stream_in >> current)
{
total_weight = total_weight + current.weight;
std::cout << current.name << std::endl;
if (total_weight >= limit_total_weight)
{
break;
}
read_blankline(stream_in);
}
return 0;
}