Reputation:
My data is on a text file that contains two columns, x-values, and y-values. The number of data points on this file can be different but never exceeds 1000. So I have declared two arrays x[1000] and y[1000]. I have to read the data file and assign each number a specific variable so that I can use it later to do some calculation. Let's say, I have 319 data points in my text file:
x y
1 2.3
1.5 2.2
2.0 2.5
... ...
160.0 35.5
Using my code below, I store the data in the following way:
x[0]=1, x[1]=1.5, x[2]=2.0, ............., x[318]=160.0
y[0]=2.3, y[1]=2.2, y[2]=2.5, ............., y[318]=35.5
Now I would like to count the number of elements that x is holding. In other words, I would like to know the size of my array x and/or y.
#include <iostream>
#include <fstream>
using namespace std;
int main(){
int i=0;
ifstream fin;
fin.open("mydata.txt");
if (fin.fail()){
std::cerr << "Error opening file!" << endl;
exit(1);
}
double x[1000], y[1000];
fin.ignore(1000,'\n');
while(!fin.eof()){
mufile >> x[i];
mufile >> y[i];
i++;
}
I tried:
int N=sizeof(x)/sizeof(*x);
This gives me 1000, the size of the array that I declared in the beginning, (not 319 the size of the updated x).
Upvotes: 0
Views: 1060
Reputation: 238461
How to count the number of elements in an array in c++?
You cannot "count" the number of elements in an array.
So I have declared two arrays
x[1000]
andy[1000]
OK, therefore each array contains exactly 1000 elements each. No more, no less.
What you want is to find out how many times you extracted a pair of numbers from the stream. You'll find that in the variable i
, which you have cleverly used to count what you need. You'll want to deduct 1 from that since the last pair of numbers are the ones that reached EOF.
Note that the program will have undefined behaviour if:
The off-by-one of i
and the problem with the end condition can both be fixed by correct checking of successful extraction before using the extracted value. See: Why is iostream::eof inside a loop condition considered wrong?
Upvotes: 3
Reputation: 74
As a rule, every time you define an array, you must initialize your array values first. After then non-empty array values can be separated as it is done in the following code.
//define a negative large number for empty array values.
#define EMPTY -1.0E30
#include <iostream>
#include <fstream>
using namespace std;
int main(){
int i=0;
ifstream fin;
fin.open("mydata.txt");
if (fin.fail()){
std::cerr << "Error opening file!" << endl;
exit(1);
}
double x[1000], y[1000];
//fin.ignore(1000,'\n'); You don't need this line.
//Initialize all your array values first.
for (int i = 0; i < 1000; i++) {
x[i]= EMPTY;
y[i]= EMPTY;
}
while(!fin.eof()){
fin >> x[i];
fin >> y[i];
i++; //non-empty array values have already been counted on this line.
}
int size=i;
/*
// You may also count non-empty array values again by using
// the following code.
int size=0;
for (int i = 0; i < 1000; i++) {
if (x[i] > EMPTY && y[i] > EMPTY) size++;
}
*/
cout<<"Size of array : "<<size<<endl;
}
The most advisable solution would be to use a vector, instead. Here is the sample code for that.
#include<iostream>
#include <fstream>
#include<vector>
using namespace std;
int main(){
int i=0;
ifstream fin;
fin.open("mydata.txt");
if (fin.fail()){
std::cerr << "Error opening file!" << endl;
exit(1);
}
vector<double> x, y;
//fin.ignore(1000,'\n'); You don't need this line.
double xval, yval;
while(!fin.eof()){
fin >> xval;
fin >> yval;
x.push_back(xval);
y.push_back(yval);
}
// x.size() give you the number of array values stored in vector x.
cout<<"Size of array : "<< x.size() <<endl;
}
Upvotes: -1
Reputation: 27934
Arrays are basic structures and they don't hold information about how many elements you actually filled with data, you can only tell it's total size in memory with sizeof(x)
and the size of one of it's elements with sizeof(*x)
.
However, we are in C++, not C, and there's really no reason you should be using arrays here. Use std::vector
instead.
std::vector<double> x;
std::vector<double> y;
x.reserve(1000); // reserve 1000 elements, optional,
y.reserve(1000); // it will resize automatically if needed
while (true)
{
double d;
fin >> d;
if (fin.eof()) break; // end found
x.push_back(d);
fin >> d;
y.push_back(d);
}
Now you can tell the number of elements from x.size()
, you don't have to worry about buffer overflow because it will resize automatically if there are more than 1000 elements, also don't have to worry about counting how many times you looped, etc.
Someone put a lot of work on making those standard C++ templates so that you don't have to waste time reinventing the wheel every time, use them.
Upvotes: 0