Reading integers from a data file

Hi, I am inexperienced with c++ and as such am unsure how to do this, I was wondering if someone could give me some help. I have a data file with 2 columns of values separated by a space. I need to design a program that reads the values, then takes all the values from 1 column, adds them all up and this goes into an equation for a value.

I am completely stuck on this, have a vague idea how to read a text file but not how to add the values up and then certainly not how to be able to put these values into the function. Can anybody point me in the right direction? I've read a lot of the forums and helps around but not really got anywhere so far.

I am only meant to use fstream and iostream for this too so I assume it must be fairly simple. I just can't work out where to start.
Last edited on
Well you could make two arrays called
 
int c1[100],c2[100];

then read the data from a text file (let's name it file.txt)
1
2
3
4
5
ifstream read("file.txt");
int lines;
read>>lines;//number of lines
for(int i=1;i<=lines;i++)
read>>c1[i]>>c2[i];

If you don't know the number of lines then use this instead
1
2
3
4
5
6
7
8
int n,m,i=1,lines;
ifstream read("file.txt");
while(read>>n>>m){
c1[i]=n;
c2[i]=m;
i++;
}
lines=i-1;//in case you need to know the number of lines 

So now your 2 columns of data are stored into 2 arrays so that means you can use them with your function like this
1
2
your_function_name(c1,plus other stuff you may need)//for your first column
your_function_name(c2,plus other stuff you may need)//for your second column 

I hope this helps. If you still have problems then feel free to post again and I will be happy to help you : )
Ok excellent, thank you for the help. This is my attempt so far, using the code you suggested. I have included my formula however I had to define c1 and c2 as vectors as such it will not let me include it in the formula. Was this what you meant. The formula wants to use all the values of column 1 added up divided by all the values starting from the 2nd value. Can you see what I'm doing wrong and how best I could change it. Thank you

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
/using namespace std;

double Variance0(double X)
{
 double sigma0;
 sigma0=(1/13-1)*pow((log(X),2)-(13/13-1)*pow((1/13)*log(X),2));

 return sigma0;
}

int main () {

vector<int> c1,c2;
int n,m,i=1,lines;
ifstream read("data.txt");
while(read>>n>>m){
c1[i]=n;
c2[i]=m;
i++;
}
lines=i-1;
return 0;

cout << Variance0(c1) << endl;
}
Well if you defined c1 and c2 as vectors then you should change
1
2
3
c1[i]=n;
c2[i]=m;
i++;

to
1
2
c1.push_back(n);
c2.push_back(m);

and
 
lines=c1.size();

Also Variance0(c1) wont work because c1 is a vector not a number. You defined your function like this
1
2
double Variance0(double X)
...

so that means it will only accept double type variables not vector <int>...
Also you said "The formula wants to use all the values of column 1 added up divided by all the values starting from the 2nd value."; from what I understand you want to divide the sum of all elements from c1 with the sum of all elements from c2. Then use the result in your formula variance0.
Well that isn't hard because you can make a function called sum and 1 called result
1
2
3
4
5
6
7
8
9
int sum(vector <int> vect){
int s=0;
for(int i=0;i<vect.size;i++)
s+=vect[i];
return s;
}
double result(vector <int> v1,vector <int> v2){
return (double)(sum(v1)/sum(v2));
}

And then ofcourse just call your function
 
cout<<Variance0(result(c1,c2))<<endl;

Hope I helped you : )
Last edited on
Thanks again this is very much appreciated. I tried this out however I'm getting an error in the line:
/for(int i=0;i<vect.size;i++)

invalid use of member (did you forget the '&' ?)|

Why would this be? Sorry I'm not very proficient in the use of vectors. Do you have to use vectors? Also in the equation I was slightly wrong. It actually just wants the sum of the first column minus the 1st value divided by the full sum of the first column. Would it be simple to do this or would you need a 2nd for loop?

Thanks again this is all very helpful, also is there a way of counting how many values are in each column?
Oh sorry it's
 
for(int i=0;i<vect.size();i++)

I forgot the ()s : )
You said "It actually just wants the sum of the first column minus the 1st value divided by the full sum of the first column. " so you mean you find out the sum of all elements from c1 (let's call it sum1) then you do
 
(sum1-c1[0])/sum1?

Sorry if I don't understand but can you please explain me using the variables from the program? Also if that is your formula why do you need the second column?
Btw to answer your question "is there a way of counting how many values are in each column?" yes it is. The number of values from a column is the number of lines which is c1.size() or c2.size() because they both have the same number of values (from what i understand).
Well if your formula is (sum1-c1[1])/sum1 then you can change the function result to
1
2
3
4
double result(vector <int> v1){
int s=(sum(v1));
return (double)((s-v1[0])/s);
}

Also you asked me if do you have to use vectors. Well you can use arrays if you want but with vectors it is safer because you don't have to define the maximum number of lines. When you define an array you say
1
2
variable_type array[capacity]
//where variable_type can be float, double, int, short, char etc and capacity is a number 

So when you don't know the capacity( number of values) it's better to use vectors.
Sorry for my long post but I tried to answer all your questions. Hope I helped you. Post again if you have any problems. Happy coding!
I need to do the exact same thing with the 2nd column but I'll just use a separate function for this. Ok it sounds like I should be using vectors. I have put all these things into the program however when I run it, the code it just hangs and nothing is printed out. Can you think of any reason this might be?

It also comes up with this warning, not sure if it is important?
warning: comparison between signed and unsigned integer expressions in the line /for(int i=0;i<vect.size();i++)

Finally, can you just pick out a single value similar to how you've done above? Ie value 3 in column 2 v2[3]?

Thanks again, let me know if you need any more details.
The warning you receive can be ingored so don't worry about it. To pick up the value 3 from column 2 you use v2[2]. Because your vectors start from v[0] so the 3rd value is v2[2], 4th value is v2[3].....n value is v2[n-1].
You said that nothing is printed on the screen. When you called the function result did you do it like this:
1
2
cout<<result(c1)<<endl;
cout<<result(c2)<<endl;

?
If you did print the function and the program was blank then I don't know what may be the problem, the code seems correct. Can you please show me how you called the function result or can you please post the entire code to see if there is something wrong with it?
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
using namespace std;

int sum(vector <int> vect){
int s=0;
for(int i=0;i<vect.size();i++)
s+=vect[i];
return s;
}
double result(vector <int> v1){
int s=(sum(v1));
return (double)((s-v1[0])/s);
}


double Sol(double result, double h)
{
 double sang, dig,top;
 top=0.5;
 dig=sqrt((1/h-1)*pow(log(result),2)-(h/h-1)*pow((1/h)*log(result),2));
 sang=dig/sqrt(top);
 return sang;
}

int main () {

vector<int> d1,d2;
int e,f,i=1,lines;
ifstream read("data.txt");
while(read>>e>>f){
d1.push_back(e);
d2.push_back(f);
i++;
}
lines=d1.size();


cout<<Sol(result(d1),lines)<<endl;

return 0;
}


This is the code however I realised that's not quite how its meant to work anyway. It's meant to be the log of the 2nd value in the column divided by the first value then this value is squared. Then it's meant to add up all these values in the column. So for this would it be something like

1
2
3
for(int i=0;i<vect.size();i++)
s+=log(vect[i+1]/vect[i])
return s;


Again thanks for your help, hopefully it should work soon :)
Last edited on
Change
1
2
3
for(int i=0;i<vect.size();i++)
s+=log(vect[i+1]/vect[i])
return s;

to
1
2
3
for(int i=0;i<vect.size()-1;i++)
s+=log(vect[i+1]/vect[i])
return s;

because you have i+1 so when i reaches the last element vect[i+1] will receive a random value.
Also you said that this value
 
log(vect[i+1]/vect[i])

should be squared so you should add pow() or
 
log(vect[i+1]/vect[i])*log(vect[i+1]/vect[i])

If your program still doesn't print anything maybe the problem is that the vectors are empty. Did you name your file "data.txt" or just "data" ? Try printing the vectors to see if they have the right values. If the program doesn't print anything then it is not reading the file. Also try
1
2
3
 (dobule)dig=(double)(sqrt((1/h-1)*pow(log(result),2)-(h/h-1)*pow((1/h)*log(result),2)));
 (double)sang=(double)(dig/sqrt(top));
//to be sure that the result is double and not int 

Contact me if you find anything : )
Ok I've edited in the changes. I realised that I needed to use log(vect[i+1]/vect[i]) and the power of that separately so I made a separate function sum2 to do the same as sum except for it is squared too. However now in the dig function I no longer need the log part as I've done this earlier. Therefore I just put it as result. However this did not work as it is now coming up with the error
error: invalid operands of types 'double' and 'double(std::vector<int, std::allocator<int> >)' to binary 'operator*'

I also added the (double) types as suggested above, however this produced an error
error: lvalue required as left operand of assignment

1
2
(double)dig=(double)(sqrt((1/h-1)*result-(h/h-1)*pow((1/m)*result2,2)));
 (double)sang=(double)(dig/sqrt(top));


Here is the code currently producing the error. How would I test printing out the vectors?
For the first error we need to see hte code, but the second is easy. If the type of dig and sang is int, and an (int) just after the "=" sign, and remove the (double) casting, like so:
1
2
dig=(double)(sqrt((1/h-1)*result-(h/h-1)*pow((1/m)*result2,2)));
 sang=(double)(dig/sqrt(top));
. If they are doubles, just remove the (double)!
Last edited on
viliml is right remove the (double). Sorry I was wrong, it happends. For printing the vectors just do a loop and a cout
1
2
for(int i=0;i<d1.size();i++)
cout<<d1[i]<<"  "<<d2[i]<<endl;

This should print your 2 columns. If they don't show then the program is not reading the file or is not loading the vectors. Btw can you please post the code that gives you this error "invalid operands of types 'double' and 'double(std::vector<int, std::allocator<int> >)' to binary 'operator*'
"?
Topic archived. No new replies allowed.