ifstream - Skip words

Hi,

I have to import data from a .txt file formatted like this:

 Name: AAAAA BBBBBB; Address: Road Square Circus; Data: XXXXXXXXX; 


I have correctly set the print on file function, but I am having issue when setting the import from file function. Can you help me to set it up?

I should need to skip "Name:" "Address:" "Data:" and store the three strings in the Order object. I tried to use getline function (so I added delimiter ';') but I cannot configure it well.

Hrader:
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
#pragma once
#include <string>
#include <vector>

using namespace std;

class Order
{
protected:
	string name;
	string address;
	string data;
	char delim, delim1,delim2;
public:
	Order()
		: name{ "" }, delim{ ';' }, address{ "" }, delim1{ ';' }, data{ "" }, delim2{ ';' } {};
	Order(string name1, string address1, string data1)
		: name{ name1 }, delim{ ';' }, address{ address1 }, delim1{ ';' }, data{ data1 }, delim2{ ';' } {};
	~Order() {};
	string get_name() const { return name; };
	string get_address() const { return address; };
	string get_data() const { return data; };
	char get_delim() const { return ';'; };
};

class Purchase : Order
{
private:
	string product;
	double unit_price;
	int count;
public:
	Purchase()
		: product{ "" }, unit_price{ 0.0 }, count{ 0 } {};
	Purchase(string product1, double unit_price1, int count1)
		: product{ product1 }, unit_price{ unit_price1 }, count{ count1 } {};
	~Purchase() {};
	string get_product() const { return product; };
	double get_unitprice() const { return unit_price; };
	int get_count() const { return count; };
};

istream& operator>>(istream& is, Order& o);
ostream& operator<<(ostream& os,const  Order& o);
istream& operator>>(istream& is, Purchase& p);
ostream& operator<<(ostream& os, const Purchase& p);
void orders_from_file(vector<Order>& o);
void orders_to_file(const vector<Order>& o);
void orders_vec_print(const vector<Order>& o);


Source:
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "stdafx.h"
#include "Header.h"
#include <iostream>
#include <fstream>

istream& operator>>(istream& is, Order& o)
{
	string name1, address1, data1;
	char delim = ';';
	cout << "Name: ";
	getline(is, name1);
	// is.ignore();   // Avoiding "rubbish" still in the buffer http://www.cplusplus.com/forum/general/51433/
	cout << "Address: ";
	getline(is, address1);
	//is.ignore();
	cout << "Data: ";
	getline(is, data1);
	//is.ignore();

	o = Order{ name1, address1, data1 };

	return is;
}
ostream& operator<<(ostream& os,const  Order& o)
{
	return os << "Name: " << o.get_name()
		<< endl << "Address: " << o.get_address()
		<< endl << "Data: " << o.get_data();
}
istream& operator>>(istream& is, Purchase& p)
{
	string product1;
	double unit_price1;
	int count1;

	cout << "Product: ";
	getline(is, product1);
	//is.ignore();
	cout << "Unitary Price: ";
	is >> unit_price1;
	cout << "Number of purchases: ";
	is >> count1;

	p = Purchase{ product1, unit_price1, count1 };

	return is;
}
ostream& operator<<(ostream& os, const Purchase& p)
{
	return os << "Product: " << p.get_product()
		<< endl << "Price: " << p.get_unitprice()
		<< endl << "Count: " << p.get_count();
}

void orders_from_file(vector<Order>& o)
{
	string iname;
	cout << "Please type filename input: ";
	cin >> iname;

	ifstream ifs{ iname };
	if (!ifs) throw runtime_error("Error while importing data.");

	while (ifs)
	{
		Order o_t;
		ifs >> o_t;
		o.push_back(o_t);
	}

}

void orders_to_file(const vector<Order>& o)
{
	string oname;
	cout << "Please type output filename: ";
	cin >> oname;

	ofstream ofs{ oname };
	if (!ofs) throw runtime_error("Error while writing file.");

	for (int i = 0; i < o.size(); ++i)
	{
		ofs << "Name: " << o[i].get_name() << o[i].get_delim()
			<< "\t" << "Address: " << o[i].get_address()
			<< o[i].get_delim() << "\t" << "Data: " 
			<< o[i].get_data() << o[i].get_delim() << endl;
	}
}

void orders_vec_print(const vector<Order>& o)
{
	for (int i = 0; i < o.size(); ++i)
	{
		cout << "Order number " << i + 1 << endl;
		cout << o[i] << endl;
	}
}


Thanks!
Last edited on
There are two getline() functions:
1
2
istream& getline (istream&, string&, char);
istream& getline (istream&, string&);

Which one do you call?
I call this one istream& getline (istream&, string&, char);.
My main difficult is to split string. I am trying to deal this with stringstream but I am pretty stucked:

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
void orders_from_file(vector<Order>& o)
{
	string iname;
	cout << "Please type filename input: ";
	cin >> iname;

	ifstream ifs{ iname };
	if (!ifs) throw runtime_error("Error while importing data.");

	while (ifs)
	{
		string s;
		string temp1;
		getline(ifs, s);
		stringstream ss{ s };
		for (string temp; ss >> temp;)
		{
			for (char& c : temp)
			{
				if (c == ';') continue;  // How can I save current word and write a new one?
				temp += c;
			}

		}
	}

}
Last edited on
I call this one

Could you tell the line numbers of your posted code, where you do call that function?
I have tried to use it but I am not able to to configure it! That's what I meant..!
I have tried to set another way to solve this problem by writing the last code I posted. Can you show me please how to use getline with ifs in my code? Many thanks
Last edited on
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 <string>
#include <regex>
#include <sstream>

struct info
{
    std::string name ;
    std::string address ;
    std::string data ;
};

bool parse( const std::string& line, info& inf )
{
    /*
        ^    - beginning of line
        \s*  - zero or more white space
        (.+) - one or more characters (numbered capture group)
        $    - end of line
    */
    static const std::regex re( R"(^\s*Name:\s*(.+);\s*Address:\s*(.+);\s*Data:\s*(.+);\s*$)" ) ;

    std::smatch match ;
    if( std::regex_match( line, match, re ) )
    {
        inf = { match[1].str(), match[2].str(), match[3].str() } ;
        return true ;
    }
    else
    {
        inf = {} ;
        return false ;
    }
}

int main()
{
    std::istringstream file( " Name: AAAAA BBBBBB; Address: Road Square Circus; Data: XXXXXXXXX; \n"
                             " Name: ccc d eeee; Address: address two; Data: data #2; \n"
                             " Name: name number three; Address: address #three; Data: data for line three; \n"
                           ) ;

    std::string line ;
    while( std::getline( file, line ) )
    {
        info inf ;
        if( parse( line, inf ) )
            std::cout << "name: '" << inf.name << "'\naddress: '" << inf.address << "'\ndata: '" << inf.data << "'\n" ;
        else std::cerr << "parse error in line '" << line << "'\n" ;
        std::cout << '\n' ;
    }
}

http://coliru.stacked-crooked.com/a/299a5640ee334363
Thank you very much JLBorges! :D I was starting to get crazy! lol
Topic archived. No new replies allowed.