Istream function to read with istream parameter

ⅰ亾dé卋堺 提交于 2020-07-07 06:58:10

问题


I'm trying to understand this code

istream &read(istream &is, Sales_data &item) 
{
    double price = 0;    
    is >> item.bookNo >> item.units_sold >> price;   
    item.revenue = price * item.units_sold;    
    return is;
} 

ostream &print(ostream &os, const Sales_data &item)
{
    os << item.isbn() << " " << item.units_sold << " "    
        << item.revenue << " " << item.avg_price();    
    return os; 
}

I don't understand what are these function , also I can't understand why we use istream for reading and ostream for printing instead of using cin and cout.


回答1:


std::cin and std::cout are specific instances of a std::istream and a std::ostream. Therefore, you could call these functions and pass std::cin or std::cout as the streams you want to use. This allows the functions to be more general-purpose, because we can use streams for more than just command line input and output.

In particular, std::ifstream and std::ofstream for file I/O and std::istringstream and std::ostringstream for string I/O.




回答2:


There are more than a few subtleties at play that you need to understand to understand what is taking place in the read and print functions. From the overview standpoint istream and ostream are general input and output classes that provide a basis for stream I/O in C++. As the other answer and comments correctly indicate, std::cin and std::cout are derived from istream and ostream to provide input/output from the standard stream stdin and stdout.

The stream themselves have a state that determines if the stream is good and can be read from or written to, or whether a stream error has occurred preventing further I/O (some failures are recoverable, some not) See std::basic_ios::rdstate and std::basic_ios::setstate for a discussion of the bits (goodbit, badbit, failbit, eofbit) that make up the stream state.

Now looking at your function prototyes:

istream &read(istream &is, Sales_data &item)

and

ostream &print(ostream &os, const Sales_data &item)

Notice how the first parameter is a refernce to the current stream? And notice how the return is also a reference to that same stream? That's important, because it passes a reference to the stream so any changes to the Steam State occurring within the function will be available on return. So if eof is encountered within the read function, that change in state will be available on return. The same for your print function (though the potential errors that would change the stream are fewer and different)

Within read, you are reading 3-pieces of information from the stream, item.bookNo, item.units_sold and price and updating item.revenue:

is >> item.bookNo >> item.units_sold >> price; 
item.revenue = price * item.units_sold;

You can read from std::cin by passing that as the argument for is or you can pass an open file-stream. The stream operations will work for any valid stream.

The print function does the opposite, it outputs the return of item.isbn(), item.units_sold, item.revenue and the return from item.avg_price() as output. If you pass std::cout as os

The last command in both functions returns the stream including any change in the stream state so the caller can check whether the read or print was successful. That is key for the caller being able to determine whether the I/O took place.

Overly Simplified Example

An overly simplified example exercising the function may help the concepts sink in. Here we declare a simplified struct Sales_data with int bookno, units_sold; and double price, revenue; For example:

#include <iostream>

struct Sales_data
{
    int bookno, units_sold;
    double price, revenue;
};

We then simplify read to read only the bookno, units_sold and price and compute the revenue for that single item, e.g.

std::istream &read(std::istream &is, Sales_data &item) 
{
    is >> item.bookno >> item.units_sold >> item.price;   

    item.revenue = item.price * item.units_sold;    

    return is;
} 

And simplify print to only output the units_sold and revenue:

std::ostream &print(std::ostream &os, const Sales_data &item)
{
    os << "units sold: " << item.units_sold << " revenue: $"  << item.revenue << '\n';

    return os; 
}

Now you can see in a very simple way prompting the user to enter a bookno, units_sold and price how both the read and print functions work, as well as how an error occurring within one of the function changes the stream state. A short main() could be:

int main (void) {

    Sales_data sd;

    std::cout << "enter bookno units_sold price: ";

    if (read (std::cin, sd))        /* if read succeeds */
        print (std::cout, sd);      /* print data */
    else
        std::cerr << "error: invalid input\n";
}

Example Use/Output

$ ./bin/readprintstream
enter bookno units_sold price: 12 100 12.95
units sold: 100 revenue: $1295

or if an error occurs:

$ ./bin/readprintstream
enter bookno units_sold price: 23 banannas 12.28
error: invalid input

Hopefully the discussion and example helps clear the concept up a bit. If you have further questions, let me know.



来源:https://stackoverflow.com/questions/60255516/istream-function-to-read-with-istream-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!