简体   繁体   中英

C++ write file error

My text file:

1:Meat Dish:Steak:11.5  
2:Fish Dish:Fish and chips:12

So basically I'm trying to read a file, select an dish by choosing 1 or 2, then write into a file the name and it's price.

This is my code:

#include <iostream>
#include <fstream>
#include <string>
#include <vector> // We will use this to store Players
using std::string;
using std::ofstream; 
using std::ifstream; 
using std::cout;
using std::cin;
using std::vector;

struct MenuList { // Define a "Menuu" data structure
    string itemNo;
    string category;
    string descript;
    double price;
};

std::istream& operator>>(std::istream& infile, MenuList& menu) {


    getline(infile, menu.itemNo, ':'); 
    getline(infile, menu.category, ':');
    getline(infile, menu.descript, ':');
    infile >> menu.price;
    // When we have extracted all of our information, return the stream
    return infile;
}

std::ostream& operator<<(std::ostream& os, MenuList& menu) {

    os << "" << menu.itemNo << " " << menu.category << " - " <<
     menu.descript;
    // When we have extracted all of our information, return the stream
    return os;
}

void Load(vector<MenuList>& r, string filename) {
    std::ifstream ifs(filename.c_str()); // Open the file name
    if(ifs) {
        while(ifs.good()) { // While contents are left to be extracted

            MenuList temp;
            ifs >> temp;        // Extract record into a temp object
            r.push_back(temp);  // Copy it to the record database
        }
        cout << "Read " << r.size() << " records.\n\n"; 
    }
    else {
        cout << "Could not open file.\n\n";
    }
}

void Read(vector<MenuList>& r) {// Read record contents
    for(unsigned int i = 0; i < r.size(); i++)
        cout << r[i] << "\n";
}

void Search(vector<MenuList>& r) {// Search records for itemNo
    string n;
    int a;
    char cont;
    cout << "Order\n_______\n";
    do {

        cout << "Enter quantity: ";
        cin >> a;
        cout << "Enter dish: ";
        cin >> n;
        for(int i = 0; i < r.size(); i++) {
            if(r[i].itemNo.find(n) != string::npos) 
                cout << r[i].category << " - " <<r[i].descript << ' ' <<
                a*r[i].price;

                std::ofstream ofs;
                ofs.open ("transactions.txt", std::ofstream::out | std::ofstream::app);
                ofs << r[i].category << " - " <<r[i].descript << ' ' << a*r[i].price << "\n";
        }
        cout << "\n\nContinue to add to order?(y)";
        cin >> cont;
    }while(cont == 'y');
}

int main() {
    vector<MenuList> records;
    Load(records, "delete.txt");
    Read(records);
    Search(records);
    return 0;
}

As I enter what dish I want to display on screen and write in file, displaying the dish on screen works just fine, but when it writes the dish into the file, it writes both of them even tho I selected just 1.

Expected output into the file if I select the first dish:
Meat Dish - Steak 11.5
But what I get is:
1:Meat Dish:Steak:11.5
2:Fish Dish:Fish and chips:12

The problem is somewhere around here:

do {

        cout << "Enter quantity: ";
        cin >> a;
        cout << "Enter dish: ";
        cin >> n;
        for(int i = 0; i < r.size(); i++) {
            if(r[i].itemNo.find(n) != string::npos) 
                cout << r[i].category << " - " <<r[i].descript << ' ' <<
                a*r[i].price;

                std::ofstream ofs;
                ofs.open ("transactions.txt", std::ofstream::out | std::ofstream::app);
                ofs << r[i].category << " - " <<r[i].descript << ' ' << a*r[i].price << "\n";
        }
        cout << "\n\nContinue to add to order?(y)";
        cin >> cont;
    }while(cont == 'y');

Anything at this point helps me. Thank you in advance.

Your actual output to the file is clearly coming from the overloaded << operator your define with:

std::ostream& operator<<(std::ostream& os, MenuList& menu) {

in your first code snippet because it starts with a number.

It is not at all clear to me what this line of code

ofs << r[i].category << " - " <<r[i].descript << ' ' << a*r[i].price << "\n";

does given the fact that your << operator takes only the stream and a reference as parameters. I'd have thought you'd get a compile error. Instead, I'm guessing the << function is getting called multiple times.

I'd recommend getting rid of your overloaded << and >> and simply using the system standard ones to read-in and write-out.

OR maybe, use the overloaded operator but pass it the object it is expecting.

An if statement without braces will only affect the following code line. Hence, only the following line is affected by the condition.

if(r[i].itemNo.find(n) != string::npos) 
    cout << r[i].category << " - " <<r[i].descript << ' ' << a*r[i].price;

In order to write only the entries satisfying the condition to the file, you may add the braces as follows:

for(int i = 0; i < r.size(); i++) {
    if(r[i].itemNo.find(n) != string::npos){
        cout << r[i].category << " - " <<r[i].descript << ' ' << a*r[i].price;

        std::ofstream ofs;
        ofs.open ("transactions.txt", std::ofstream::out | std::ofstream::app);
        ofs << r[i].category << " - " <<r[i].descript << ' ' << a*r[i].price << "\n";
    }
}

This will include all the code in the condition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM