I am new to programming, so I have what is probably a basic question. I currently have a text file with 365 lines...one line per day of the year. These are the first four lines of the file:
2003 1 1 18 0 -1 36 50 46
2003 1 2 16 3 -1 43 56 52
2003 1 3 19 7 -1 42 56 49
2003 1 4 14 3 -1 42 58 50
I eventually have to graph these using a special library given to us, but first I want to put the data for each column into an array. This is the part of my code where I attempt to do just that.
#include "library.h"
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
ifstream in;
int yr[364], mo[364], day[364], windSpeed[364], precip[364], snowDepth[364], minTemp[364], maxTemp[364], avgTemp[364];
void main() {
make_window(800, 800);
set_pen_color(color::red);
set_pen_width(8);
// open file, read in data
in.open("PORTLAND-OR.TXT");
if (in.is_open()) {
// read each column into an array
for (int i = 0; i < 364; i++) {
in >> yr[i] >> mo[i] >> day[i] >> windSpeed[i] >> precip[i] >> snowDepth[i] >> minTemp[i] >> maxTemp[i] >> avgTemp[i];
cout << mo[i] << " " << day[i] << endl;
}
in.close();
}
else {
cout << "error reading file" << endl;
exit(1);
}
}
When I attempt to print out all of the values in the second and third columns (month and day), it begins printing from march 8 (3 8) through december 31 (12 31). I need it to print all the way from January 1 to December 31. Is there a reason why the first two months worth of values isn't printing?
Below is a really stupid main-only program that reads your file in with your existing reading code and prints it back out again. I've embedded a running commentary in the code with things you should consider doing.
Basically, this is whaty I was talking about yesterday in loop not displaying all data entries from file
#include <iostream>
#include <fstream>
using namespace std; // bad! Avoid doing this in real life.
int yr[364],
mo[364],
day[364],
windSpeed[364],
precip[364],
snowDepth[364],
minTemp[364],
maxTemp[364],
avgTemp[364]; // bad! define a structure instead
/* Example:
struct stats
{
int yr;
int mo;
int day;
int windSpeed;
int precip;
int snowDepth;
int minTemp;
int maxTemp;
int avgTemp;
};
struct stats statistics[364]; // bad! use a std::vector instead
std::vector<stats> statistics;
*/
int main()
{
// removed all the windowing stuff.
ifstream in;
in.open("PORTLAND-OR.TXT");
if (in.is_open())
{
// read each column into an array
for (int i = 0; i < 364; i++)
{ // what do you do if the file ends early or contains bad information?
in >> yr[i] >>
mo[i] >>
day[i] >>
windSpeed[i] >>
precip[i] >>
snowDepth[i] >>
minTemp[i] >>
maxTemp[i] >>
avgTemp[i];
}
in.close();
}
else
{
cout << "error reading file" << endl;
return 1;
}
// printing out all the stuff that was read
for (int i = 0; i < 364; i++)
{
cout << yr[i] << "," <<
mo[i] << "," <<
day[i] << "," <<
windSpeed[i] << "," <<
precip[i] << "," <<
snowDepth[i] << "," <<
minTemp[i] << "," <<
maxTemp[i] << "," <<
avgTemp[i] << endl;
}
}
Related
My code is split into task 1 and task 2. I want to open and close with each task to reset the pointer to the start position. I did try fseek(OH-in.txt, 0, SEEK_SET) instead of opening a second time but that didn't work.
The tasks don't matter just pay attention to where I open and close the file OH-in.txt.
The file only opens (and outputs data that was read) for the first task!
Here is my code
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string collegeName;
string location;
int currentEnroll;
int tuition;
int numOfSchools = 0; // edit this in code below
/*
TASK 1
*/
// TASK 1: list the schools and the tuition of the schools in Cincinnati with
// tuition below 20,000
ifstream file;
file.open("OH-in.txt");
vector<string> arr; // declare array
// read lines of OH-in.txt
while (file >> collegeName >> location >> currentEnroll >> tuition) {
// add collegeName and location to array if true
if (tuition < 20000 && location == "Cincinnati") {
collegeName = "(" + collegeName + " $" + to_string(tuition) + ") ";
arr.push_back(collegeName);
numOfSchools++;
}
}
for (int i = arr.size() - 1; i >= 0; i--) {
cout << arr[i];
}
cout << numOfSchools << " schools meet this criteria.";
file.close();
/*
TASK 2
*/
// TASK 2 Calculate and display the average tuition of schools with more than
file.open("OH-in.txt");
vector<string> arr2;
double avgTuition = 0;
int expensiveSchools = 0;
// iterate through the list. If a school with enrollment higher than 10,000 is found, add tuition to total. It will later be divided by the total number of expensive schools.
while (file >> collegeName >> location >> currentEnroll >> tuition) {
if (currentEnroll > 10000) {
avgTuition += tuition;
expensiveSchools += 1;
}
if (collegeName == "BGSU") {
cout << "BGSU Tuition: " << tuition << endl;
}
}
file.close();
}
I want to read the data from my input file
70 95 62 88 90 85 75 79 50 80 82 88 81 93 75 78 62 55 89 94 73 82
and store each value in an array. There's more to this particular problem (the other functions are commented out for now) but this is what's really giving me trouble. I looked for hours at the previous question about data and arrays but I can't find where I'm making the mistake.
Here's my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int SIZE = 22;
int grades[SIZE];
void readData() {
int i = 0;
int grades[i];
string inFileName = "grades.txt";
ifstream inFile;
inFile.open(inFileName.c_str());
if (inFile.is_open())
{
for (i = 0; i < SIZE; i++)
{
inFile >> grades[i];
cout << grades[i] << " ";
}
inFile.close(); // CLose input file
}
else { //Error message
cerr << "Can't find input file " << inFileName << endl;
}
}
/*
double getAverage() {
return 0;
}
void printGradesTable() {
}
void printGradesInRow() {
}
void min () {
int pos = 0;
int minimum = grades[pos];
cout << "Minimum " << minimum << " at position " << pos << endl;
}
void max () {
int pos = 0;
int maximum = grades[pos];
cout << "Maximum " << maximum << " at position " << pos << endl;
}
void sort() {
}
*/
int main ()
{
readData();
return 0;
}
and here's my output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Thank you for your time.
The issue is that you're declaring a local grades array with a size of 1, hiding the global grades array. Not only that, you are now accessing the array beyond the bounds, since the local grades array can only hold 1 item.
So get rid of the line:
int grades[i];
However, it needs to be mentioned that this:
int i = 0;
int grades[i];
is not valid C++ syntax. You just stumbled into this by mistake, but that code would not compile if compiled using a strict ANSI C++ compiler.
An array in C++ must be declared using a constant expression to denote the number of entries in the array, not a variable. You, by accident, are using a non-standard compiler extension called Variable Length Arrays or VLA's for short.
If this is for a school assignment, do not declare arrays this way (even if you meant to do it), as it is not officially C++. If you want to declare a dynamic array, that is what std::vector is for.
I don't see any issue in reading the file , you have just confused the global vs local variable of grades
You don't need this
int i = 0;
int grades[];
Inside the function readData
#include <string>
using namespace std;
const int SIZE = 22;
int grades[SIZE];
void readData() {
string inFileName = "grades.txt";
ifstream inFile;
inFile.open(inFileName.c_str());
if (inFile.is_open())
{
for (int i = 0; i < SIZE; i++)
{
inFile >> grades[i];
cout << grades[i] << " ";
}
inFile.close(); // CLose input file
}
else { //Error message
cerr << "Can't find input file " << inFileName << endl;
}
}
int main()
{
readData();
return 0;
}
Your original global array grades, of size 22, is replaced by the local array with the same name but of size 0.
(It is not overwritten, just any code using the variable grades, inside the scope that the second one was defined, will read the value of the second grades array, as it has a higher precedence.)
Both inFile >> grades[i]; and cout << grades[i] << " "; should return runtime errors as you are reading beyond their size (It appears that you are not using a strict compiler).
[int grades[i]; would return a compile time error normally as you shouldn't / usually can't initialize a fixed array with a variable]
I think what is happening, instead of your program crashing, is that grades[i] is just returning an anonymous instance of a variable with value 0, hence your output.
The simplest fix to your problem would be to just delete int grades[i].
(Also delete one of the int i = 0's as you don't need that to be defined twice)
I have to create a school library as an OOP assignment. I'm finding it very difficult to understand, my question here is:
int RANGE = total_books;
the total_books should represent the current books in the text file.
The formatting makes it read 3 parts of info (title, author, genre). How can I point to this between functions?
I want to load the program and read the file in order to see how many there are currently (lets say 7 books, so the variable should be 7 * 3 = 21). Then when the user views the file, it will display the 7 books.
Currently it's static: I have it set to 21. if I add another book it will only read the first 7 books. If I set it to 24 and there are 7 books (not 8 as needed) it will crash. I've tried looking on these forums and other places online, got the "C++ Programming in easy steps" book, it's where I got this formatting code but it's not very useful.
#include "stdio.h"
#include "malloc.h"
#include "stdlib.h"
#include "string.h"
#include "conio.h"
#include "fstream"
#include "iostream"
using namespace std;
unsigned int number_of_books = 0; //this is based on the number of books *3
int total_books = number_of_books * 3; //*3 to read 1 more book
class Book
{
private: // properties
char Title[16];
char Author[16];
char Genre[16];
public: // methods
int iDetailsGet(void);
int iDetailsShow(void);
int iRecordWrite(void);
};
int Book::iDetailsGet(void)
{
// prompt for the data
fflush(stdout);
puts("\n \t !USE_UNDERSCORE_FOR_SPACE!");
puts("\n \t Please enter the Book name: ");
fflush(stdin);
scanf("%s", Title, 16);
fflush(stdout);
puts("\n \t Please enter the Author: ");
fflush(stdin);
scanf("%s", Author, 16);
fflush(stdout);
puts("\n \t Please enter the Genre: ");
fflush(stdin);
scanf("%s", Genre, 16);
// Get total number of lines(books)
FILE *infile = fopen("books.txt", "r");
int ch;
while (EOF != (ch = getc(infile)))
if ('\n' == ch)
++number_of_books; // read from variable above but static.
printf("%u\n", number_of_books);
//return to menu
int main();
} // end method definition
int Book::iDetailsShow()
{
system("CLS");
int RANGE = total_books; // should be dynamically read on start up
string tab[RANGE];
int i = 0, j = 0;
ifstream reader("books.txt");
if(!reader)
{
cout << "Error Opening input file" << endl;
return -1;
}
while(!reader.eof())
{
if((i + 1) % 3 == 0) // the 3 read title,author,genre then adds new line
getline(reader, tab[i++], '\n');
else
getline(reader, tab[i++], '\t');
}
reader.close();
i = 0;
while (i < RANGE)
{
cout << endl << "Record Number: " << ++j << endl;
cout << "Title: " << tab[i++] << endl;
cout << "Author: " << tab[i++] << endl;
cout << "Genre: " << tab[i++] << endl;
}
int main();
} // end method definition
// code for the method: iRecordWrite(void)
int Book::iRecordWrite(void)
{
ofstream NewBook("books.txt", ios::app);
if (!NewBook)
{
printf("Error Recording Book");
return -1;
}
NewBook << " " << Title << " " << Author << " " << Genre << endl;
NewBook.close();
int main();
} // end of method deinition
Thanks!
Instead of initialising total_books based on number_of_books when it's declared, you should probably set it after actually reading number_of_books. Variables, whether global or in a scope, don't update themselves dynamically. So, you could have something like this:
int number_of_books = 0;
void read_number_of_books() {
// parse input file for value
total_books = number_of_books * 3;
}
Is that what you're looking for?
This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 8 years ago.
I have a weird problem, so my instructor told us to create a simple program using vectors that will first ask the user how many integers they want to enter, and after the numbers were entered via a space as a delimiter the output should add 2 to each vector element.
Ex -
How many numbers are you going to enter = 4 (Lets assume the user enters 4)
Enter the numbers = 11 45 71 24 (Lets assume the user entered these 4 numbers)
THE OUTPUT SHOULD BE THIS = 13 47 73 26 (with spaces added 2)
Since using vectors is a must, i know how to add add 2 with a normal integer vector output but when it comes with spaces i have no idea, so far the program i wrote will accept everything before the space into the vector and will add 2 to it.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector <int> userInput;
int input;
int number;
int num1;
cout << "How many numbers are you going to enter ? :";
cin >> number;
cout << "Enter the Numbers : " << endl;
cin >> input;
userInput.push_back(input);
cout << "Vector Contains : ";
for (unsigned int i = 0; i < userInput.size(); i++)
{
cout << userInput[i] + 2;
}
system("pause>nul");
return 0;
}
The reason you're only taking in one input is because you're only taking in one int from std::cin. The other ints are still remaining in the stream. You should do this:
while(/*we still have stuff to extract*/)
{
std::cin >> input;
userInput.push_back(input);
}
However, we still need to know when to stop. Since we're only expecting one line of input from the user, we can do std::cin.peek() != '\n' to check if we've reached the point where the user pressed the Enter key earlier.
Thank you for reading.
The standard extraction operator for int expects whitespace as the separator between items so you don't need to do anything special there. Just read ints, put them in your vector, do the addition, and print out the results. Assuming you've already read n for the count, the real work could look something like this:
std::copy_n (std::istream_iterator<int>(std::cin),
n,
std::back_inserter(your_vector));
std::transform(your_vector.begin(), your_vector.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int i){ return i + 2; });
Try the following
#include <iostream>
#include <vector>
#include <cstdlib>
int main()
{
std::cout << "How many numbers are you going to enter ? :";
size_t n = 0;
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " numbers : " << std::endl;
int x;
for ( size_t i = 0; i < n && std::cin >> x; i++ ) v[i] = x;
for ( int x : v ) std::cout << x + 2 << ' ';
std::cout << std::endl;
std::system( "pause>nul" );
return 0;
}
If to input
4
11 45 71 24
the output will be
13 47 73 26
Other approach is to use standard function std::getline and std::istringstream instead of the operator >>
For example
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <sstream>
#include <limits>
int main()
{
std::cout << "How many numbers are you going to enter ? :";
size_t n = 0;
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " numbers : " << std::endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
std::string s;
std::getline( std::cin, s );
std::istringstream is( s );
int x;
for ( size_t i = 0; i < n && is >> x; i++ ) v[i] = x;
for ( int x : v ) std::cout << x + 2 << ' ';
std::cout << std::endl;
std::system( "pause>nul" );
return 0;
}
Hey guys I am new to reading txt files to arrays, so I need to read this txt file temperature.txt to a two dimensional array. Here is the file I need to read, and the code I tried writing up it complies but Im not sure if it is reading it correctly
T(F) R1 R2 R3 R4
95.0 95.20 66.10 43.10 29.00
96.0 96.10 67.60 43.50 31.20
97.0 97.40 67.00 43.70 30.50
98.0 97.20 69.10 44.10 30.70
99.0 98.90 68.00 44.70 32.80
100.0 99.50 71.10 45.10 31.50
101.0 101.00 71.20 45.30 31.60
102.0 101.60 71.00 45.70 30.50
103.0 101.80 73.10 46.30 32.50
104.0 103.70 73.50 46.60 32.70
105.0 105.60 72.80 47.10 33.60
UPDATE I re did this again without looking at your answers but will this work ?
using namespace std;
#include<fstream>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<stdlib.h>
int main ()
{
char temp[11] [5];
ifstream tempin ("c:\\mydoc2\\temperaturedata.txt");
tempin>>temp[0]>>temp[1]>>temp[2]>>temp[3]>>temp[4]>>temp[5]>>temp[6]>>temp[7]>>temp[8]
>>temp[9]>>temp[10];
while(!tempin.fail())
{
cout<< temp[0] << " " << temp[1] << " " << temp[2] << " " << temp[3]<< " " << temp[4]<< " " << temp[5] << " " << temp [6] <<
" " << temp [7] << " " << temp[8] << " " << temp[9] << " " << temp[10];
tempin>>temp[0]>>temp[1]>>temp[2]>>temp[3]>>temp[4]>>temp[5]>>temp[6]>>temp[7]
>>temp[8]>>temp[9]>>temp[10];
}
cout << endl << endl;
system("pause");
return 0;
}
You have a string myArray[5]; but you're reading 55 elements - that should not work!
There are lots of errors in your code.
1) You have written a read function but you never call it, so it never executes.
2) There is no 2D array in your code. 2D arrays look like this double myArray[10][10];. (that's a 10 by 10 2D array of doubles).
3) You're trying to read floating point numbers, but your array is an array of strings.
4) Your array is size 5 but you try and read 55 items into it.
5) After you open the file you have an infinite loop which just prints out "No file\n". Not sure why you want to print out error messages in a loop. Normally you just print an error message once.
I could go on, but I think the main point is that you're a beginner, and you currently aren't able to write three lines of code without introducing an error (sorry to be harsh but based on the above that is true). So the important lesson is that you should not try to write more than three lines of code at once.
Try something like this
a) Write some code which opens a file, test it and check that it does open the file
b) Add some code to a) to read one number, test it and check that it does read one number.
c) Replace the read one number code with code that reads a 1D array of numbers. Test it and check that it works.
etc. etc.
The point is to build up gradually to the program you want, and test each stage as you go. I can't emphasise how important that is. Every professional programmer works like this, but because you're a beginner the steps you have to take are much smaller than an experienced programmer.
Try something like this:
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
string line;
ifstream myfile ("C:/temps.txt");
int dim_x = 12;
int dim_y = 5;
double temps[dim_x][dim_y] ;
//init the array if neccesary
for(int x = 0;x<dim_x;x++)
for(int y = 0; y<dim_y;y++)
temps[x][y]=0;
if (myfile.is_open()){
for ( int x=0; getline (myfile,line); x++ ){
int y=0;
istringstream iss(line);
while(iss){
string sub;
iss >> sub;
temps[x][y] = ::atof(sub.c_str());
y++;
}
}
myfile.close();
}
cout << "TEMPS:" << endl;
for(int x = 0;x<dim_x;x++){
for(int y = 0; y<dim_y;y++)
cout<<temps[x][y]<<" ";
cout<<endl;
}
return 0;
}
I made some improvements
#include <fstream>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
void read ();
int main ()
{
read();
return 0;
}
void read()
{
ifstream indata(".\\temperaturedata.txt");
if(indata == NULL)
{
cout<< "Opening file failed."<< endl;
return;
}
const int columns = 5;
const int rows = 11;
double myArray[rows][columns];
string tmp;
getline(indata, tmp);
for(int i = 0; i < rows; ++i)
{
for (int j = 0; j < columns; ++j)
{
cout << "\t" << flush;
indata >> myArray[i][j];
cout.setf(ios::fixed);
cout << setprecision(2) << myArray[i][j] <<flush;
}
cout << endl;
}
indata.close();
}
If the content of your file is like this:
95.0 95.20 66.10 43.10 29.00
96.0 96.10 67.60 43.50 31.20
97.0 97.40 67.00 43.70 30.50
98.0 97.20 69.10 44.10 30.70
99.0 98.90 68.00 44.70 32.80
100.0 99.50 71.10 45.10 31.50
101.0 101.00 71.20 45.30 31.60
102.0 101.60 71.00 45.70 30.50
103.0 101.80 73.10 46.30 32.50
104.0 103.70 73.50 46.60 32.70
105.0 105.60 72.80 47.10 33.60
then, it's quite easy for you to get these values. But there are some errors in your code:
while(!indata.fail()) : This line will cause a dead loop. Use if(!indata) instead.
You will need a 2-dimension array of type double instead of string
Here is what could work:
#include<fstream>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<stdlib.h>
using namespace std;
void read ();
int main ()
{
read();
system("PAUSE");
return 0;
}
void read()
{
ifstream indata("E:\\temperature.txt"); //that's my path,you should use yours.
if(!indata)
{
cout<<"No file."<< endl;
}
if(indata.is_open())
{
double myArray[11][5];
for(int i = 0; i < 11; ++i)
{
for(int j = 0; j < 5; ++j)
{
indata >> myArray[i][j];
//cout<<myArray[i][j]<<"\t";
}
//cout<<endl;
}
}
}
This could work when your txt file doesn't include the first line:T(F) R1 R2 R3 R4, if this line did exit,you should use getline() to move your file pointer to the second line, where you could read the data.