Member Avatar for nalasimbha

Hi,

I am trying to extract data from a text file into an array or even a vector. The example data in the file "data.txt" is in the following manner

Home number = 123456
Mobile number = 789012
Office number = 567987
Balance = 46.56
...
...
...

I want to extract the values after the '=' sign and store them in an array.

i tired using the getline and ignore functions to extract the data, but it doesnt seem to be working fine.

the code i wrote is

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main()
{
	char *arr;
	vector<double> v(4);
	int length;
	int i = 0;

	ifstream input("data.txt", ios::in);
	
	// Obtaining the length of file
	input.seekg (0, ios::end);
 	length = input.tellg();
 	input.seekg (0, ios::beg);

	arr = new char [length];

	if(input)
	{
		input.ignore('=');
		input.getline(arr,length);
		v[i] = atof(arr);
		i++;	
	}

	for(i = 0; i < 4; i++)
	cout << v[i] << endl;
}

Thanks

Recommended Answers

All 4 Replies

You need to get rid of the preceding data. So first find the position of the '=' in the string: size_t pos = mystring.find_first_of("="); Then erase everything up to and including that position: mystring.erase(0, pos + 1); You can then use atof to parse it to a floating point datatype: double d = std::atof(mystring.c_str());

Member Avatar for nalasimbha

I did try what you said, but the output is 0. What am i missing here?

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

int main()
{
	char *arr;
	vector<double> v(4);
	int length;
	int i = 0;
	string mystring;

	ifstream input("data.txt", ios::in);
	
	// Obtaining the length of file
	input.seekg (0, ios::end);
 	length = input.tellg();
 	input.seekg (0, ios::beg);

	arr = new char [length];

	if(input)
	{
//		input.ignore('=');
		input.getline(arr, length);
		mystring = arr;
		size_t pos = mystring.find_first_of("=");
		mystring.erase(0, pos+1);
		v[i] = atof(mystring.c_str());
		i++;	
	}

	for(i = 0; i < 4; i++)
	cout << v[i] << endl;
}

Thanks

Before doing any string manipulation output the string (the data that you have read in from the file) to ensure that is correct.
And in this case you wouldn't use the ignore method at all.

Also when you loop through the data it is better to use iterators, what you have there is a count (i) of the number of items you have read from the file. You have then discarded that by re-assigning it a value of 0 in the for loop and hard-coded the value 4, which is what you expect i to equal after reading in from the file.
You are better of with either:

for( std::vector<double>::iterator it = v.begin(); it != v.end(); ++it)
{
std::cout << (*it) << std::endl;
}

or

for( int index = 0; index < i; ++index)
{
std::cout << v[index] << std::endl;
}

An ifstream is a stream in dedicated ios::in mode. You only need to use that syntax on an fstream to put it in ios::in mode, but it's not needed with and ifstream.

Unless you have some discreet reason for determining the length of a file in terms of the number of char present, that knowledge isn't necessary to read the file, and indeed you never use it.

Since you are storing the information extracted from the file in a vector you don't need array to be some specific size, just choose a size big enough that it's likely to work, or better yet, since you are already using STL vectors use STL strings too.

An if statement lets you do something once, if the conditional is true. A loop allows to do things as long as the conditional is true. I suspect quite strongly you want to use a loop, not an if.

I wouldn't check to see if stream exists as the control of the loop. I would use the return value from an attempt at reading something from the file. In this case I would use the getline() version for STL strings using '=' as the delimiting char and ignore the input into the string. Within the body of the loop I would read the numerical portion of the line directly into a variable of type double using the >> operator. I would then call the ignore() function passing it a reasonably large value to clear the ifstream buffer. I would then use push_back() to store the variable's value in the vector before retrying the string input in the conditional phrase. Using iterators with STL containers is fine, but using the [] operator with vectors is fine, too, IMO.

vector<double> v;
string mystring;
ifstream input("data.txt");
double temp;

while(getline(input, mystring, '='))
{
    input >> temp;
    v.push_back(temp);
    input.ignore(1086);
}

int length = v.size();
for(i = 0; i < length; i++)
  cout << v[i] << endl;

There are other things that should probably be done to increase the robustness of the code, but in terms of the algorithm to read the file, storing all the numerical values at the end of each line, I think this way should work quite well.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.