Reading from file delimited with ',' (commas)

Let's say I have a file open with content of different types.

Say, for this example, file.txt had information stored into it via an fstream function.

Content:

P,123456789,canned,10,25.65,No Error Message

Now let's say I want to extract data from that same file I just wrote to.

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

        someClass : public anotherClass {
			char type;
			long number;
			char* canned_or_not;
			int inventory;
			double price;
			anotherClass* errMsg;
        };

	std::ostream& someClass::write(std::ostream& os) const {
                        char comma = ',';
			os << type << comma;
			os << number << comma;
			os << canned_or_not << comma;
			os << inventory << comma;
			os << price << comma;
			os << errMsg << comma;
        }


	std::fstream& someClass::load(std::fstream& file) {
		someClass temp;
		if (file.is_open()) {
			while (file.good())
			{
                            //what do I do here?
			}


I need to assign what I extract from the file to the the temp someClass object, and then add the line *this = temp; towards the end of the function, assuming all data has been extracted properly.
Last edited on
Line 25: Do not loop on (! stream.eof()) or (stream.good()). This does not work the way you expect. The eof bit is set true only after you make a read attempt on the file. This means after you read the last record of the file, eof is still false. Your attempt to read past the last record sets eof, but you're not checking it there. You proceed as if you had read a good record. This will result in reading an extra (bad) record. The correct way to deal with this is to put the >> (or getline) operation as the condition in the while statement.
1
2
3
  while (stream >> var) // or while (getline(stream,var))
  {  //  Good operation
  }


The easiest way to load a CSV file is to use stringstream. This may be something you haven't covered yet as I know you told me in an earlier thread that you had not learned std::string yet.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
std::fstream & someClass::load (std::fstream& file) 
{   someClass   temp;
    string      rec;
    char        junk;   //  For eating commas
    
	if (file.is_open()) 
	{   while (file >> rec)  // Read an entire record from the file
		{   stringstream    line (rec);  // Load the record into a stringstream
            
            line >> temp.type >> junk;
            line >> temp.num >> junk;                
            getline (line, temp.canned_or_not, ',');  // assumes canned_or_not is allocated
            line >> temp.inventory >> junk;
            line >> temp.price >> junk;
            getline (line, temp->errMsg);  // Assumes errMsg is allocated
            //  Do something with temp
		}
	}
    return file;
}	



Last edited on
Thank you for your help.. seriously, I wouldnt have gotten this far without your suggestions. I am still, however, running into some issues:


https://i.imgur.com/29lPfx6.jpg

I have to overload the >> operator as well -- is this why Im getting the 'no operator matches these operands' error?

1
2
3
4
5
6
7
8
9
10
11
12
These two helper functions should support your class:

std::ostream& operator<<(std::ostream&, const Product&) – a helper that receives a 
reference to an ostream object and an unmodifiable reference to a Product object and 
returns a reference to the ostream object. Implementations of this function will insert a 
Product record into the ostream.

std::istream& operator>>(std::istream&, Product&) – a helper that receives a reference to 
an istream object and an modifiable reference to a Product object and returns a reference 
to the istream object. Implementations of this function will extract the Product record from
 the istream.


My Nonperishable and product classes are designed as such:

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
	class Product {
	public:
		virtual std::fstream& store(std::fstream& file, bool addNewLine)const = 0;
		virtual std::fstream& load(std::fstream& file) = 0;
		virtual std::ostream& write(std::ostream& os, bool linear)const = 0;
		virtual std::istream& read(std::istream& is) = 0;
		virtual bool operator==(const char*) const = 0;
		virtual double total_cost() const = 0;
		virtual const char* name() const = 0;
		virtual void quantity(int) = 0;
		virtual int qtyNeeded() const = 0;
		virtual int quantity() const = 0;
		virtual int operator+=(int) = 0;
		virtual bool operator>(const Product&) const = 0;
	};
	std::ostream& operator<<(std::ostream&, const Product&);
	std::istream& operator>>(std::istream&, Product&);
	double operator+=(double&, const Product&);
	Product* CreateProduct();
	Product* CreatePerishable();
}

class NonPerishable : public Product {
		char type; //type of product
		char sku[max_sku_length + 1]; //sku of product
		char* m_pName; //name of, dynamically allocated
		char unit[max_unit_length + 1]; //
		int inventory; //current inventory
		int qtyNeed; //required
		double price; //before taxes
		bool taxable; //taxes
		ErrorMessage* errMsg;
	protected:
		void name(const char*); //store\override current name with pointer
		const char* name() const; //return name\nullptr
		double cost() const; //returns the price of the product plus any tax that applies to the product.
		void message(const char*); //store message in errMsg
		bool isClear() const; //self-explanatory, but in case you forget, return true if errMsg is clear
	public:
		NonPerishable(char = '\0');
		NonPerishable(const char*, const char*, const char*, int = 0, bool = 0, double = 0, int = 0);
		~NonPerishable();
		NonPerishable(const NonPerishable&);
		NonPerishable& operator=(const NonPerishable&);
		std::fstream& store(std::fstream&, bool newLine = true) const;
		std::fstream& load(std::fstream&);
		std::ostream& write(std::ostream&, bool) const;
		std::istream& read(std::istream&);
		bool operator==(const char*) const;
		double total_cost() const; //a query that returns the total cost of all items on hand.
		void quantity(int);
		bool isEmpty() const;
		int qtyNeeded() const;
		int quantity() const;
		bool operator>(const char*) const;
		int operator+=(int);
		bool operator>(const Product&) const;
		void setEmpty(char = '\0');
	};
	std::ostream& operator<<(std::ostream&, const Product&);//insert Product record into ostream
	std::istream& operator>>(std::istream&, Product&);//extract Product record from istream
	double operator+=(double&, const Product&); //return cost
	Product* CreateProduct(); //creates NonPerishable object in dynamic memory
}
Last edited on
Topic archived. No new replies allowed.