首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Istream参数读取的istream函数

使用Istream参数读取的istream函数
EN

Stack Overflow用户
提问于 2020-02-17 11:22:33
回答 2查看 1.2K关注 0票数 2

我正在尝试理解这段代码

代码语言:javascript
复制
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; 
}

我不明白这些函数是什么,我也不明白为什么我们使用istream读取和ostream打印而不是使用cincout

EN

回答 2

Stack Overflow用户

发布于 2020-02-17 11:28:48

std::cinstd::coutstd::istreamstd::ostream的特定实例。因此,您可以调用这些函数并将std::cinstd::cout作为要使用的流进行传递。这使得函数更具通用性,因为我们可以使用streams进行更多的命令行输入和输出。

特别是,用于文件I/O的std::ifstreamstd::ofstream以及用于字符串I/O的std::istringstreamstd::ostringstream

票数 3
EN

Stack Overflow用户

发布于 2020-02-17 12:00:37

要理解readprint函数中发生的事情,您需要了解许多微妙之处。从概述的角度来看,istreamostream是通用的输入和输出类,它们为C++中的流I/O提供了基础。正如其他答案和评论正确指出的那样,std::cinstd::cout派生自istreamostream,以提供来自标准流stdinstdout的输入/输出。

流本身具有一种状态,该状态确定流是否良好且可以读取或写入,或者是否发生流错误以阻止进一步的I/O (有些故障是可恢复的,有些则不是)。有关构成流状态的位(goodbit, badbit, failbit, eofbit)的讨论,请参阅std::basic_ios::rdstatestd::basic_ios::setstate

现在看看你的函数原型:

代码语言:javascript
复制
istream &read(istream &is, Sales_data &item)

代码语言:javascript
复制
ostream &print(ostream &os, const Sales_data &item)

注意到第一个参数是如何引用当前流的吗?注意到return也是对同一个流的引用吗?这一点很重要,因为它传递了一个对流的引用,因此在函数中发生的任何Steam State更改都将在返回时可用。因此,如果在read函数中遇到eof,则状态更改将在返回时可用。您的print函数也是如此(尽管更改流的潜在错误较少且各不相同)

read中,您将从流、item.bookNo, item.units_soldprice中读取3条信息,并更新item.revenue

代码语言:javascript
复制
is >> item.bookNo >> item.units_sold >> price; 
item.revenue = price * item.units_sold;

您可以通过将其作为is的参数传递来读取std::cin,也可以传递一个打开的文件流。流操作将适用于任何有效的流。

print函数则相反,它输出item.isbn(), item.units_sold, item.revenue的返回值和item.avg_price()的返回值作为输出。如果将std::cout作为os传递

这两个函数中的最后一个命令返回流,包括流状态的任何更改,以便调用者可以检查readprint是否成功。这是调用者能够确定I/O是否发生的关键。

过于简化的示例

使用该函数的一个过于简单的示例可能有助于深入理解这些概念。在这里,我们使用int bookno, units_sold;double price, revenue;声明一个简化的结构Sales_data,例如:

代码语言:javascript
复制
#include <iostream>

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

然后,我们将read简化为只读取bookno, units_soldprice,并计算该单个项目的revenue,例如

代码语言:javascript
复制
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_soldrevenue

代码语言:javascript
复制
std::ostream &print(std::ostream &os, const Sales_data &item)
{
    os << "units sold: " << item.units_sold << " revenue: $"  << item.revenue << '\n';

    return os; 
}

现在,您可以非常简单地看到提示用户输入bookno, units_soldpricereadprint函数是如何工作的,以及其中一个函数中发生的错误如何改变流状态。简短的main()可以是:

代码语言:javascript
复制
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";
}

示例使用/输出

代码语言:javascript
复制
$ ./bin/readprintstream
enter bookno units_sold price: 12 100 12.95
units sold: 100 revenue: $1295

或者如果发生错误:

代码语言:javascript
复制
$ ./bin/readprintstream
enter bookno units_sold price: 23 banannas 12.28
error: invalid input

希望本文的讨论和示例能够帮助我们理清一些概念。如果您有进一步的问题,请让我知道。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60255516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档