Storage size unknown

Morning:

I am creating this code to read numbers from a file and then some of the numbers of the file are used to calculate the average of those numbers and then calculate how much the numbers deviate form the average. The code is just on its beginnings but I am getting an error message that I am not sure how to correct
1
2
3
% g++ -o proc proc.cpp
proc.cpp: In function 'int main()':
proc.cpp:10: error: storage size of 'max' isn't known 

The following is my code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
  ifstream in("objv.sky");
  ofstream out("objv.skyc");
  string image;
  int npix,imageCount;
  double mean, stddev, min, max[],forSum,sum,average,avgPct;
  getline(in, image); //to skip the header
  cout << "How many images in the list: ";
  cin >> imageCount;
  while(in >> image >> npix >> mean >> stddev >> min >> max)
    {
		for(int i=0;i=imageCount;i++)
		{
			cout <<"["<<i<<"] "<< max[i] << "\n";
			//out << max[i] << "\n";
		}
	}	
  while(in >> image >> npix >> mean >> stddev >> min >> max)
    {
      sum += max;
      cout << "Sum" <<sum << "\n";
      average = sum/imageCount;
      cout << "Average" << average << "\n";
      avgPct = average*0.10;
      cout << "avgPct" << avgPct << "\n";
    }
  while(in >> image >> npix >> mean >> stddev >> min >> max)
    {
      average = average - max;
      cout << "Max" << average << "\n";
    }
}

and this is the file is reading from
1
2
3
4
5
6
#IMAGE    NPIX      MEAN    STDDEV       MIN       MAX
 1.imh   1048576     1984.     490.1     1870.    65535.
 3.imh   1048576     1984.      471.     1875.    65446.
 4.imh   1048576     1984.     479.1     1872.    65335.
 6.imh   1048576     1984.     473.8     1869.    65535.
 12.imh   1048576     1984.     476.3     1869.    65522.

Also any suggestions on how to improve the code are welcome. Thank you,

Gus
max[]
You never declare how big max should be as an array. If you want something with a storage size that changes as you add elements, try a vector.

EDIT: OH! Here's that respect that we owe you for using code tags in your first post *respect*.

-Albatross
Last edited on
Hi:

I corrected that by giving the string a number but I am getting a new error. Also you suggested vectors, which I have not used before, are vectors a better way to read the file ? Here is the change I did to the code
Original
double mean, stddev, min, max,forSum,sum,average,avgPct;
Change
double mean, stddev, min, max[5],forSum,sum,average,avgPct;

error message
1
2
3
4
% g++ -o proc proc.cpp
proc.cpp: In function 'int main()':
proc.cpp:14: error: no match for 'operator>>' in '((std::basic_istream<char, std::char_traits<char> >*)((std::basic_istream<char, std::char_traits<char> >*)((std::basic_istream<char, std::char_traits<char> >*)((std::basic_istream<char, std::char_traits<char> >*)std::operator>> [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>](((std::basic_istream<char, std::char_traits<char> >&)(& in.std::basic_ifstream<char, std::char_traits<char> >::<anonymous>)), ((std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)(& image))))->std::basic_istream<_CharT, _Traits>::operator>> [with _CharT = char, _Traits = std::char_traits<char>](((int&)(& npix))))->std::basic_istream<_CharT, _Traits>::operator>> [with _CharT = char, _Traits = std::char_traits<char>](((double&)(& mean))))->std::basic_istream<_CharT, _Traits>::operator>> [with _CharT = char, _Traits = std::char_traits<char>](((double&)(& stddev))))->std::basic_istream<_CharT, _Traits>::operator>> [with _CharT = char, _Traits = std::char_traits<char>](((double&)(& min))) >> max'
/usr/include/c++/4.2.1/istream:131: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>& (*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]


Gus
The problem is this:

while(in >> image >> npix >> mean >> stddev >> min >> max)

You need to specify which element in the array you're trying to write into.

Vectors are much more flexible than raw arrays. You wouldn't need to know beforehand how many elements you're going to read, for instance. If you have no particular reason to use arrays, it's probably better to use an std::vector.
Ok I am following y'all advice. I don't know vectors but I am giving it a try. I have cut my code a bit and here is the new code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
  ifstream in("objv.sky");
  ofstream out("objv.skyc");
  string image;
  int npix,imageCount;
  double mean, stddev, min,forSum,sum,average,avgPct;
  vector<double> max (5);
  getline(in, image); //to skip the header
  cout << "How many images in the list: ";
  cin >> imageCount;
  for(int i=0;i<imageCount;i++)
    {
		cout <<"["<<i+1<<"] " ;
		while(in >> image >> npix >> mean>> stddev >> min >> max[i])
		{
			cout << max[i] << "\n";
		}
		average += max[i];
		cout << "The average is : " << average << "\n";
	}
	return 0;
}


My problem is that I am not getting the correct answer. I was hoping for the following
1
2
3
4
5
6
[1] 65535.
[2]65446
[3]65335.
[4]65535.
[5]65522
The average is = 65,474

What I am getting is the following
1
2
3
4
5
6
7
8
9
10
11
12
% ./test
How many images in the list: 5
[1] 65535
65446
65335
65535
65522
The average is : 65522
[2] The average is : 65522
[3] The average is : 65522
[4] The average is : 65522
[5] The average is : 65522


I know I must not be stating my code right. Any suggestions, also I looked at some information out there but is there any good vectors tutorials out there. Thanks,

Gus
Last edited on
First of all, you cout your average inside your loop, so it will be printed 5 times.

Second, your while loop will read everything up until the end of your file into element 0 of your vector, which is not allocated and therefore you run the risk of a segmentation fault. Kill that while loop, and note that the proper way to enlarge a vector is to use vector::push_back(some_type). Example of usage for your case:
max.push_back(temp);

Where temp is a temporary int that you read into via cin.

Keep up the good work!

-Albatross
Last edited on
Albatross is right about the first thing he said. The actual problem is this:

1
2
3
4
while (in >> image >> npix >> mean>> stddev >> min >> max[i])
{
    cout << max[i] << "\n";
}

My guess is that you wanted to write something like:

1
2
3
4
5
6
7
8
9
if (in >> image >> npix >> mean>> stddev >> min >> max[i])
{
    cout << max[i] << "\n";
}
else
{
    cout << "error reading file!" << endl;
    break;
}

You see, the way you do it you read the whole file while i is still 0. Albatross also noticed that. But you may forget everything about the seg-fault and push_back function. Since you initialize your vector like this: vector<double> max (5); it's ok to do it the way you do it. Your vector initialization isn't done properly. Either do it like vector<double> max;, and then modify your for loop to use push_back like Albatross suggests, or do it like vector<double> max (imageCount); after you get the imageCount, and leave your for loop as is.

One more thing is that you don't initialize your average variable. Put something like average=0; before your for loop.
Last edited on
You guys are awesome. I got my code to produce pretty much the way I want. Now I got a second query about the second part. I need to take the average and then subtract it from every value of max[i], which will produce new numbers(the amount of numbers depends on the imageCount value). I believe what I need to do, but I am not certain that I can put this part into the loop because the average value is out of the loop. I created a new for loop but i don't believe is been read since the code already went through another loop. Can a create a all around loop to read both for loops (I doubt this is the case) or is there a smarter way to do it. Thanks,

Gus
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
	ifstream in("objv.sky");
	ofstream out("objv.skyc");
	string image;
	int npix,imageCount;
	double mean, stddev, min,forSum,sum,average,avgPct;
	vector<double> max (imageCount);
	vector<double> imageDiff (imageCount);
	getline(in, image); //to skip the header
	cout << "How many images in the list: ";
	cin >> imageCount;
	for(int i=0;i<imageCount;i++)
	{
		average=0;
		if(in >> image >> npix >> mean>> stddev >> min >> max[i])
			{
				cout <<"["<<i+1<<"] "<< max[i] << "\n";
				sum += max[i];
			}
	}
	average = sum/imageCount;
	cout << "The average is : " << average << "\n";
	for(int j=0;j<imageCount;j++)
	{
		while (in >> image >> npix >> mean >> stddev >> min >> max[j]) 
		{
			imageDiff[j] = average - max[j];
			cout << "The image difference between the average and the image is "<< imageDiff[j] << "\n";
		}
	}	
	return 0;
}
I actually found out that if I create a function I may be able to run the code. I did that but now I got a segmentation fault error. I am looking at the code but I can't see where the error lies, any ideas,

Gus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int averageResult(int average, int imageCount)
{
	ifstream in("objv.sky");
	ofstream out("objv.skyc");
	string image;
	int npix;
	double mean, stddev, min,forSum,sum,avgPct;
	vector<double> max (imageCount);
	int subtractionNumber[imageCount];
	getline(in, image); //to skip header
	for (int i=0;i<imageCount;i++) 
	{
		if (in >> image >> npix >> mean >> stddev >> min >> max[i])
		{
			subtractionNumber[i] = average - max[i];
			return(subtractionNumber[i]);
		}
	}
}


int main()
{
	ifstream in("objv.sky");
	ofstream out("objv.skyc");
	string image;
	int npix,imageCount;
	double mean, stddev, min,forSum,sum,average,avgPct;
	vector<double> max (imageCount);
	vector<double> imageDiff (imageCount);
	getline(in, image); //to skip the header
	cout << "How many images in the list: ";
	cin >> imageCount;
	for(int i=0;i<imageCount;i++)
	{
		average=0;
		if(in >> image >> npix >> mean>> stddev >> min >> max[i])
			{
				cout <<"["<<i+1<<"] "<< max[i] << "\n";
				sum += max[i];
			}
	}
	average = sum/imageCount;
	cout << "The average is : " << average << "\n";
	cout << averageResult(average,imageCount) << "\n";
	return 0;
}

*shy grin*
I did warn you that it might be a good idea to use push_back(). It's considerably more foolproof (not to imply that you are a fool), especially considering that imageCount has not been initialized to any value when you declared your vectors in main().

Also, check this line:
return(subtractionNumber[i]);

Considering it's in a loop, are you sure you want to do that? It's not the cause of your problem, however it might still ring a few bells.

-Albatross
Last edited on
Thanks for the advice Albatross, I forgot about that part.
I pretty much got my code running how I want it but for one thing, is there anything else better than a return 0 for the function. I say because I get a 0 at the end of the code. Here is my soon to be final code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
double averageResult(double average, int imageCount)
{
	ifstream in("objv.sky");
	ofstream out("objv.skyc");
	string image;
	int npix;
	double mean, stddev, min,forSum,sum,avgPct;
	vector<double> max (imageCount);
	double subtractionNumber[imageCount];
	getline(in, image); //to skip header
	for (int i=0;i<imageCount;i++) 
	{
		if (in >> image >> npix >> mean >> stddev >> min >> max[i])
		{
			subtractionNumber[i] = average - max[i];
			cout << "The number ("<< image << ") is away from average by: " << subtractionNumber[i] << endl;
		}
	}
	return 0;
}


int main()
{
	ifstream in("objv.sky");
	//ofstream out("objv.skyc");
	string image;
	int npix,imageCount;
	double mean, stddev, min,forSum,sum,average,avgPct;
	getline(in, image); //to skip the header
	cout << "How many images in the list: ";
	cin >> imageCount;
	vector<double> max (imageCount);
	for(int i=0;i<imageCount;i++)
	{
		average=0;
		if(in >> image >> npix >> mean>> stddev >> min >> max[i])
			{
				cout <<"["<<i+1<<"] "<< max[i] << "\n";
				sum += max[i];
				max.push_back(imageCount);
			}
	}
	average = sum/imageCount;
	cout << "The average is : " << average << "\n";
	cout << averageResult(average,imageCount) << "\n";
	return 0;
}


and here is the result

1
2
3
4
5
6
7
8
9
10
11
12
13
How many images in the list: 5
[1] 65535
[2] 65446
[3] 65335
[4] 65535
[5] 65522
The average is : 65474.6
The number (1) is away from average by: -60.4
The number (2) is away from average by: 28.6
The number (3) is away from average by: 139.6
The number (4) is away from average by: -60.4
The number (5) is away from average by: -47.4
0


How do I get rid of the zero ? Thank you for all the help,

Gus
Topic archived. No new replies allowed.