要了解read 和print 函数中发生的事情,您需要了解更多的细微之处。从概述的角度来看,istream 和 ostream 是通用输入和输出类,它们为 C++ 中的流 I/O 提供了基础。正如其他答案和 cmets 正确指出的那样,std::cin 和 std::cout 派生自 istream 和 ostream 以提供来自标准流 stdin 和 stdout 的输入/输出。
流本身有一个状态来确定流是否良好并且可以读取或写入,或者是否发生了流错误以防止进一步的 I/O(有些故障是可恢复的,有些则不能)参见std::basic_ios::rdstate和std::basic_ios::setstate 讨论构成流状态的位 (goodbit, badbit, failbit, eofbit)。
现在查看您的函数原型:
istream &read(istream &is, Sales_data &item)
和
ostream &print(ostream &os, const Sales_data &item)
注意第一个参数是如何引用当前流的?并注意返回如何也是对同一流的引用?这很重要,因为它传递了对流的引用,因此函数内发生的对 Steam 状态 的任何更改都将在返回时可用。因此,如果在read 函数中遇到eof,则状态更改将在返回时可用。 print 函数也是如此(尽管会改变流的潜在错误更少且不同)
在read 内,您正在从流中读取3 条信息,item.bookNo, item.units_sold 和price 并更新item.revenue:
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
您可以通过将std::cin 作为is 的参数传递来读取std::cin,或者您可以传递打开的文件流。流操作适用于任何有效的流。
print 函数则相反,它输出item.isbn(), item.units_sold, item.revenue 的返回值和item.avg_price() 的返回值作为输出。如果您将std::cout 传递为os
两个函数中的最后一个命令返回流,包括流状态的任何变化,因此调用者可以检查read 或print 是否成功。这是调用者能够确定 I/O 是否发生的关键。
过度简化的例子
一个过分简化的例子执行函数可能有助于理解概念。这里我们声明一个简化的结构Sales_data 和int bookno, units_sold; 和double price, revenue; 例如:
#include <iostream>
struct Sales_data
{
int bookno, units_sold;
double price, revenue;
};
然后我们将read 简化为仅读取bookno, units_sold 和price 并计算该单个项目的revenue,例如
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;
}
并将print 简化为仅输出units_sold 和revenue:
std::ostream &print(std::ostream &os, const Sales_data &item)
{
os << "units sold: " << item.units_sold << " revenue: $" << item.revenue << '\n';
return os;
}
现在您可以通过一种非常简单的方式查看提示用户输入bookno, units_sold 和price 的read 和print 函数是如何工作的,以及其中一个函数如何发生错误更改流状态。简短的main() 可以是:
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";
}
使用/输出示例
$ ./bin/readprintstream
enter bookno units_sold price: 12 100 12.95
units sold: 100 revenue: $1295
或者如果发生错误:
$ ./bin/readprintstream
enter bookno units_sold price: 23 banannas 12.28
error: invalid input
希望讨论和示例有助于澄清概念。如果您还有其他问题,请告诉我。