Writing and reading from a file using fstream

In this incomplete project I happen to firstly write to a file and then extract data (read) from it, but the inserted data is not shown in output and some trash data is shown instead, like a long sequence of underscores:

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
#include <iostream>
#include <vector>
#include <string>
#include <fstream>

//Product class
class Purchase {

public:
	std::string prdct_name{};
	double unit_price;
	int count;
};

// customer class
class Order {

public:
	std::string cstr_name{};
	std::string cstr_data{};
	std::string cstr_address{};
	std::vector<Purchase> cstr_vp;
};

int main() try
{
	// Open file for both reading and writing
	std::fstream myFile("my_order.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
	if (!myFile.is_open()) throw("Can't open file! :(");
	
	std::string name, data, address, product_name;
	double unit_prc;
	int counts;

	std::cout << "Enter customer's info: 'name', 'data' and 'address' each followed by enter: ";
	
	std::getline(std::cin, name);
	std::getline(std::cin, data);
	std::getline(std::cin, address);

	std::cout << "Enter customer's purchases: Product 'name', numerical 'unti price' and numerical"
		" 'count', each followed by enter: ";
	std::getline(std::cin, product_name);
	std::cin >> unit_prc >> counts;
	
	// Writing to the file
	myFile << name << '\n' << data << '\n' << address << '\n' << product_name
		<< ' ' << unit_prc << ' ' << counts << '\n';
	
	Purchase myPurchase(product_name, unit_prc, counts);
	std::vector<Purchase> cp;
	cp.push_back(myPurchase);

	Order myOrder(name, data, address, cp);

	// Reading from the file
	std::cout << "\nCustomer's info, 'name', 'data' and 'address' is: ";
	std::string str;
	while (std::getline(myFile, str))
		std::cout << str << '\n';
	
	myFile.close(); 
	
	system("pause");
	return 0;
}

catch (std::exception& e) {
	std::cerr << e.what() << '\n';
	abort();
} 


Is it because the control in the file is at the end at the time of reading? If so, how to get it back to the beginning for a correct reading, please?
Last edited on
The fstream might have something. See http://www.cplusplus.com/reference/fstream/fstream/

However, why not make it simple? Close output stream before you open input stream.
You need to set the file stream back to the beginning and flush before trying to read.

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
#include <iostream>
#include <vector>
#include <string>
#include <fstream>

//Product class
class Purchase {

public:
	std::string prdct_name;
	double unit_price {};
	int count {};
};

// customer class
class Order {

public:
	std::string cstr_name;
	std::string cstr_data;
	std::string cstr_address;
	std::vector<Purchase> cstr_vp;
};

int main() try
{
	// Open file for both reading and writing
	std::fstream myFile("my_order.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
	if (!myFile.is_open()) throw("Can't open file! :(");

	std::string name, data, address, product_name;
	double unit_prc {};
	int counts {};

	std::cout << "Enter customer's info: 'name', 'data' and 'address' each followed by enter:\n";

	std::getline(std::cin, name);
	std::getline(std::cin, data);
	std::getline(std::cin, address);

	std::cout << "Enter customer's purchases: Product 'name', numerical 'unti price' and numerical"
		" 'count', each followed by enter:\n";
	std::getline(std::cin, product_name);
	std::cin >> unit_prc >> counts;

	// Writing to the file
	myFile << name << '\n' << data << '\n' << address << '\n' << product_name
		<< ' ' << unit_prc << ' ' << counts << '\n';

	Purchase myPurchase(product_name, unit_prc, counts);
	std::vector<Purchase> cp;
	cp.push_back(myPurchase);

	Order myOrder(name, data, address, cp);

	// Reading from the file
	std::cout << "\nCustomer's info, 'name', 'data' and 'address' is:\n";
	std::string str;

	myFile.clear();
	myFile.flush();
	myFile.seekg(0);

	while (std::getline(myFile, str))
		std::cout << str << '\n';
}

catch (std::exception& e) {
	std::cerr << e.what() << '\n';
	abort();
}

I'd open it for writing only (std::ifstream) to write to it, then close the in filestream and open it for writing (std::ofstream), then close the out filestream.

You could also flush the buffer at the beginning of main, before you do anything else.
Is clear() not enough after closing the file and before re-opening it? In my project it's working fine, now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//....
// Open file for writing
std::fstream myFile("my_order.txt", std::fstream::out | std::fstream::trunc);
if (!myFile.is_open()) throw("Can't open file for writing! :(");

//....

myFile.close();
myFile.clear();

//....

// Open file for reading
myFile.open("my_order.txt", std::fstream::in);
if (!myFile.is_open()) throw("Can't open file for reading! :(");

// ...
myFile.close(); 

@seeplus
Why have you used the default initializer "{}" for built-in types int and double but not for std::string!?
Last edited on
1
2
3
4
5
6
class Purchase {
  std::string prdct_name; // Initialized with default constructor string::string()
  std::string another {}; // same, see https://en.cppreference.com/w/cpp/language/value_initialization
  double unit_price; // nothing is done
  double other {}; // value initialized https://en.cppreference.com/w/cpp/language/value_initialization
};
Why have you used the default initializer "{}" for built-in types int and double but not for std::string!?


std::string has a default constructor - whereas the built-in types int, double et al don't.
seeplus,

Except for myfile.clear() you've also used two other methods myFile.flush() and myFile.seekg(0) (of course you've forgotten to close the stream/file!). But the questions is: are those other two methods needed for the project?

One question for admins: I'm not aware of admin's list to report a bug of the website when creating a new thread. The question body (including the code and text) accepts no format at the time of posting it for the first time making it look like plain text. Each time I have to firstly post the thread and then step forward to editing it to look better. How to work this issue out?
.seekg() sets the get (read) pointer to the beginning. May not be needed (not tried) but when mixing read and write with the same stream it doesn't hurt to make sure the file pointer is where you think it is when you start reading after writing.

.flush() as you're reading/writing with the same stream, best to make sure that all writes have been completed before reading starts. I've had issues with not doing this in the past.

I didn't forget to close the stream! :) Don't do what will be done for you.

Topic archived. No new replies allowed.