问题
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