This loop has a few problems:
while (!file.eof()) {
file >> arr[i].name >> arr[i].DOB ....
- You never increase
i
so the same arr[i]
will be overwritten time and time again.
- You use
!file.eof()
as a condition to stop reading. eof()
does not get set until after you've tried to read beyond the end of the file, which means that if you had increased i
as you should, the last arr
would be empty / broken. Instead check if the extraction from the stream succeeded. Since the stream is returned when you do stream >> var
and has an overload for explicit operator bool() const
which returns !fail()
you can do this check directly in your loop:
while(stream >> var) { extraction success }
Using formatted input (>>
) for string fields that are likely to contain spaces is however not a good idea. Your name, nung khual
, would be split so nung
would go into name
and khual
would go into DOB
. It's better to use a field separator that is very unlikely to be included in anyone's name. \n
is usually good and works well with std::getline
.
std::getline
returns the stream that you gave as an argument which means that you can chain getline
s similarly to stream >> var1 >> var2
, except it's a little more verbose.
getline(getline(stream, var1), var2)
will put the first line in var1
and the second line in var2
.
To make input and output a little simpler you can add stream operators for your data type and make the input stream operator use getline
for your fields.
Example:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
struct data_t {
std::string name;
std::string DOB;
std::string address;
std::string Dr_name;
std::string V_date;
};
// input stream operator using chained getlines
std::istream& operator>>(std::istream& is, data_t& d) {
using std::getline;
return getline(getline(getline(getline(getline(is,
d.name), d.DOB), d.address), d.Dr_name), d.V_date);
}
// output stream operator
std::ostream& operator<<(std::ostream& os, const data_t& d) {
return os << d.name << '\n'
<< d.DOB << '\n'
<< d.address << '\n'
<< d.Dr_name << '\n'
<< d.V_date << '\n';
}
int main() {
std::vector<data_t> arr;
if(std::ifstream file("Patient.txt"); file) {
data_t tmp;
while(file >> tmp) { // remember, no eof() needed
arr.push_back(tmp);
}
}
if(std::ofstream file("Patients_2.txt"); file) {
for(const data_t& d : arr) {
file << d;
}
}
if(std::ifstream patientss("Patients_2.txt"); patientss) {
data_t tmp;
while(patientss >> tmp) {
std::cout << tmp;
}
}
}