Alhin
Alhin

Reputation: 11

C++ reading data from a *.txt file to vector of struct

I'm new one in C++ and have some misunderstandings about file read/write...

I have a .txt data file that contains information about the streets i.e. street, home number and number of flats

I have a task to read data from a file, add new one, delete unwanted and make some calculations about the number of flats on certain street

For data storage during the program work I made a vector of struct:

struct homeAdressBook {
    std::string street;
    char homeNumber[255];
    int flats;
};

std::vector<homeAdressBook> HAB;

Program code is below:

std::fstream document;
    document.open("name.txt");
    if (!document) {
        std::ofstream document;
        document.open("name.txt");
    }
    if (!document)
        std::cout << "File open error" << std::endl;
    else {
//Here (while loop) I want to read data from a file and add to my vector of struct for further usage, it partly works somehow but this point is unclear for me
        while (!document.eof()) {
            HAB.push_back(homeAdressBook());
            std::getline(document, HAB[i].street);
            document >> HAB[i].street;
            document >> HAB[i].homeNumber;
            document >> HAB[i].flats;
            i++;
        }
        document.close();
        do {
            switch (menu()) {
            case 0: {
                document.close();
                exit = false;
                break;
            }
//Here (case 1) I add new data and write it in file, here I have no problems at the moment
            case 1: {
                document.open("name.txt", std::ios::app);
                HAB.push_back(homeAdressBook());
                std::cin.ignore();
                std::cout << "Enter the address: ";
                std::getline(std::cin, HAB[i].street);
                std::cout << "Enter home number: ";
                std::cin.getline(HAB[i].homeNumber, 255);
                std::cout << "Enter number of flats: ";
                std::cin >> HAB[i].flats;
                document << HAB[i].street << HAB[i].homeNumber << HAB[i].flats << std::endl;
                document.close();
                i++;
                break;
            }
//Here (case 2) I want to read data from a file, it reads data except first line of data
            case 2: {
                int total = i;
                std::cout << std::setw(20) << "Street" << std::setw(20) << "Home Number" << std::setw(20) << "Number of flats" << std::endl;
                document.open("name.txt", std::ios::in);
                for (int j = 0; j < total; j++) {
                    std::cout << std::setw(20) << HAB[j].street << std::setw(20) << HAB[j].homeNumber << std::setw(20) << HAB[j].flats << std::endl;
                }
                document.close();
                break;
            }
//Here (case 3) data should be deleted from a file if necessary
            case 3: {
                document.open("name.txt", std::ios::out | std::ios::in);
                int strDelete = 0;
                std::cout << "0. Exit to main menu" << std::endl;
                for (i = 0; i < HAB.size(); i++) {
                    std::cout << i + 1 << ". " << HAB[i].street << std::endl;
                }
                std::cout << "\nType number of street to delete: ";
                std::cin >> strDelete;
                if (strDelete)
                    i--;
                else break;
                HAB.erase(HAB.begin() + (strDelete - 1));
                document.close();
                break;
            }
            }
        } while (exit);
    }
    system("pause");
    return 0;
}

Data in .txt file is written like this:

aaa street 10 50
aaa street 10 45
bbb street 1 10
ccc street 1 12
ccc street 1/10 25

Each line in .txt file belongs to [i]-s vector of struct elements I cannot understand how correctly add data from a .txt file to my vector of structs during the program work (name of the street can hold up to 5 or 6 words and how program can separate whether it is the name of the street or it is home number or number of flats)

Upvotes: 0

Views: 4394

Answers (1)

Thomas Matthews
Thomas Matthews

Reputation: 57678

I recommend that you overload operator>> for your structure:

struct homeAdressBook
{
    std::string column1;
    std::string street;
    std::string homeAddress;
    int flats;
    friend std::istream& operator>>(std::istream& input, homeAddressBook& address);
};

std::istream& operator>>(std::istream& input, homeAddressBook& address)
{
  input >> address.column1;
  input >> address.street;
  input >> address.homeAddress;
  input >> address.flats;
  return input;
}

The above will allow you to change your input process to:

std::vector<homeAddressBook> database;
homeAddressBook record;
//...
std::ifstream data_file("addresses.txt");
while (data_file >> record)
{
  database.push_back(record);
}

Notes

  1. Your post describes 3 columns in the data, but your data source shows 4.
  2. You open your document as an output stream (ostream) and you use getline on the output stream.
  3. Your structure name has "book" which implies a collection of items. I recommend using a name such as "Home_Address" to indicate a single item. Use std::vector for the book.

Edit 1:
Prefixed members in operator>> with "address.".

Upvotes: 1

Related Questions