首页 > 编程语言 >第8章 C++IO流类库

第8章 C++IO流类库

时间:2024-09-24 17:44:59浏览次数:8  
标签:类库 std const istream Sales C++ IO include data

练习8.1 编写函数,接受一个istream&参数,返回值类型也是istream&。此函数须从给定流中读取数据,直至遇到文件结束标识时停止。它将读取的数据打印在标准输出上。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。

练习8.2 测试函数,调用参数为cin.

答案:

 1 #include <iostream>
 2 using namespace std;
 3 istream& func(istream& os)
 4 {
 5     int v;
 6     while (os >> v, os.eof() != 1)//只有在碰到结束符时才停止输入,windows下为ctrl+z
 7     {
 8         if (os.bad())
 9             throw runtime_error("IO流错误");
10         if (os.fail())//遇到数据型错误时,必须清空缓冲区
11         {
12             cerr << "数据型错误,重新输入" << endl;
13             os.clear();
14             //清理方式1 ,直接清空缓冲区中的当前新行的剩余数据
15             os.ignore(100,'\n');//必须清理缓冲区,清理错误数据,否则过不去
16             continue;
17         }
18         cout << v << endl;
19     }
20     os.clear();//必须复位恢复流正常状态,后续才可继续使用输入
21     return os;
22 }
23 
24 istream& func2(istream& os)
25 {
26     int v;
27     while (os >> v, os.eof() != 1)//只有在碰到结束符时才停止输入
28     {
29         if (os.bad())
30             throw runtime_error("IO流错误");
31         if (os.fail())//遇到数据型错误时,必须清空缓冲区
32         {
33             cerr << "数据型错误,重新输入" << endl;
34             os.clear();
35             //清理方式2,只清空遇到的错误类型数据,后面正确类型的数据保留。
36             while (!isspace(cin.get()))//只把空白符之前(包括空白符)的错误型数据读取出来扔掉
37                 continue;
38             continue;
39         }
40         cout << v << endl;
41     }
42     os.clear();//必须复位恢复流正常状态,后续才可继续使用输入
43     return os;
44 }
45 int main()
46 {
47     //istream mycin; //错误,不能自定义标准IO流对象,其构造函数都是私有的。
48     func(cin);
49     //用于测试如果不复位,能否继续使用cin,  并不能。
50     //cin.clear();
51     //int v;//继续输入
52     //cin >> v;
53     //cout << v << endl;
54 }

 

练习8.3 什么情况下,下面的while循环会终止?

1 while (cin >> i) /*  ...    */ 1 while (cin >> i) /*...*/
1 while (cin >> i) /*...*/1 while (cin >> i) /*...*/

 答案:

当遇到了IO流错误,或者遇到文件结束符,或者读入了无效数据时,会终止循环。

即当badbit,failbit,eofbit任何一个流状态位被置位时将会终止循环。

 

 练习8.4  编写函数,以读模式打开一个文件,将其内容读入到一个stringvector中,将每一行作为一个独立的元素存于vector中。

答案:

 1 #include <iostream>
 2 #include <fstream>
 3 #include <vector>
 4 #include <string>
 5 using namespace std;
 6 int main()
 7 {
 8     //方式1
 9     ifstream fcin("temp.txt");
10     if (!fcin)//如果打开文件失败
11     {
12         cout << "文件打开失败" << endl;
13         return -1;
14     }
15 
16     string strbuf("");
17     vector<string> vi;
18     while (std::getline(fcin, strbuf))
19     {
20         vi.push_back(strbuf);
21     }
22 
23     //读取完毕后打印vector进行测试
24     for (auto iter = vi.begin(); iter != vi.end(); iter++)//传统for
25     {
26         cout << *iter << endl;
27     }
28 
29     fcin.close();
30 }
 1 #include <iostream>
 2 #include <fstream>
 3 #include <vector>
 4 #include <string>
 5 using namespace std;
 6 int main()
 7 {
 8     //方式2
 9     ifstream fcin;
10     fcin.open("temp.txt");
11     if (!fcin)//如果打开文件失败
12     {
13         cout << "文件打开失败" << endl;
14         return -1;
15     }
16     string strbuf("");
17     vector<string> vi;
18     while (std::getline(fcin, strbuf))
19     {
20         vi.push_back(strbuf);
21     }
22 
23     //读取完毕后打印vector进行测试
24     for (auto line : vi)//范围for
25     {
26         cout << line << endl;
27     }
28 
29     fcin.close();
30 }

 

练习8.5 重写上面的程序,将每个单词作为一个独立的元素进行存储。 

答案:

 1 #include <iostream>
 2 #include <fstream>
 3 #include <vector>
 4 #include <string>
 5 using namespace std;
 6 int main()
 7 {
 8     
 9     ifstream fcin("temp.txt");
10     if (!fcin)//如果打开文件失败
11     {
12         cout << "文件打开失败" << endl;
13         return -1;
14     }
15 
16     string strbuf("");
17     vector<string> vi;
18     while (fcin >> strbuf)//从第一个非空白字符开始按单词读取,到空白符结束
19     {
20         vi.push_back(strbuf);
21     }
22 
23     //读取完毕后打印vector进行测试
24     for (auto iter = vi.begin(); iter != vi.end(); iter++)//传统for
25     {
26         cout << *iter << endl;
27     }
28 
29     fcin.close();
30 }

 

 练习8.6  修改书店程序

重写7.1.1节的书店程序,从一个文件中读取交易记录。将文件名作为一个参数传递给main

答案:

 1 //Sales.cpp
 2 
 3 #include <iostream>
 4 using std::istream; 
 5 using std::ostream;
 6 
 7 #include "Sales_data.h"
 8 Sales_data::Sales_data(std::istream& is)
 9 {
10     // read will read a transaction from is into this object
11     read(is, *this);
12 }
13 
14 double Sales_data::avg_price() const {
15     if (units_sold)
16         return revenue / units_sold;
17     else
18         return 0;
19 }
20 
21 // add the value of the given Sales_data into this object
22 Sales_data& Sales_data::combine(const Sales_data& rhs)
23 {
24     units_sold += rhs.units_sold; // add the members of rhs into 
25     revenue += rhs.revenue;       // the members of ``this'' object
26     return *this; // return the object on which the function was called
27 }
28 
29 Sales_data add(const Sales_data& lhs, const Sales_data& rhs)
30 {
31     Sales_data sum = lhs;  // copy data members from lhs into sum
32     sum.combine(rhs);      // add data members from rhs into sum
33     return sum;
34 }
35 
36 // transactions contain ISBN, number of copies sold, and sales price
37 istream& read(istream& is, Sales_data& item)
38 {
39     double price = 0;
40     is >> item.bookNo >> item.units_sold >> price;
41     item.revenue = price * item.units_sold;
42     return is;
43 }
44 
45 ostream& print(ostream& os, const Sales_data& item)
46 {
47     os << item.isbn() << " " << item.units_sold << " "
48         << item.revenue << " " << item.avg_price();
49     return os;
50 }
View Code

 

 1 //Sales_data.h
 2 
 3 #ifndef SALES_DATA_H
 4 #define SALES_DATA_H
 5 
 6 #include <string>
 7 #include <iostream>
 8 
 9 class Sales_data {
10     friend Sales_data add(const Sales_data&, const Sales_data&);
11     friend std::ostream& print(std::ostream&, const Sales_data&);
12     friend std::istream& read(std::istream&, Sales_data&);//
13 public:
14     // constructors
15     Sales_data()
16         : units_sold(0), revenue(0.0) 
17     {
18     }
19     Sales_data(const std::string& s) 
20         :bookNo(s), units_sold(0), revenue(0.0)
21     {
22     }
23     Sales_data(const std::string& s, unsigned n, double p)//书的isbn字符串,销售数量,单价
24         :bookNo(s), units_sold(n), revenue(p * n) 
25     {
26     }
27     Sales_data(std::istream&);
28 
29     // operations on Sales_data objects
30     std::string isbn() const //返回isbn
31     { return bookNo; } 
32     Sales_data& combine(const Sales_data&);//+=
33     double avg_price() const; //计算本书的单价
34 private:
35     std::string bookNo;//ISBN
36     unsigned units_sold;//本书已销售数量
37     double revenue;//销售总金额
38 };
39 
40 
41 // nonmember Sales_data interface functions
42 Sales_data add(const Sales_data&, const Sales_data&);
43 std::ostream& print(std::ostream&, const Sales_data&);
44 std::istream& read(std::istream&, Sales_data&);
45 
46 // used in future chapters
47 inline
48 bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
49 {
50     return lhs.isbn() < rhs.isbn();
51 }
52 #endif
View Code
 1 #include "Sales_data.h"
 2 #include <iostream>
 3 #include <fstream>
 4 using namespace std;
 5 //已假设文件内同一类书的所有交易项(每单交易项)均是紧挨连续在一起的,且每行都一条订单交易项
 6 
 7 int main(int args,char* argv[])
 8 {
 9     fstream fcin(argv[1]);//关联并打开参数指定的文件
10     if (!fcin)
11     {
12         cout << "文件打开失败" << endl;
13         return -1;
14     }
15 
16     Sales_data total;//用于保存同类书的数据总和
17 
18     if (read(fcin, total))
19     {
20         Sales_data next;
21         while (read(fcin, next))
22         {
23             if (total.isbn() == next.isbn())//如果是相同书,则累加交易量
24             {
25                 total.combine(next);//累加
26             }
27             else//碰到下一种书,则打印上一种书的交易总量
28             {
29                 print(cout, total) << endl;// 打印上一种书的交易总量
30                 total = next;//为统计下一种书做准备
31             }
32         }
33         print(cout, total) << endl;// 补刀,打印最后一种书的交易总量
34     }
35     else
36     {
37         cout << "一条交易数据也没读取到" << endl;
38     }
39 
41     std::cout << "Hello World!\n";
42 }

 

练习8.7 

//修改上一节的书店程序,将结果保存到一个文件中。将输出文件名作为第二个参数传递给main函数。

#include "Sales_data.h"
#include <iostream>
#include <fstream>
using namespace std;
//已假设文件内同一类书的所有交易项(每单交易项)均是紧挨连续在一起的,且每行都一条订单交易项

int main(int args,char* argv[])
{
    fstream fcin(argv[1]);//关联并打开参数指定的文件
    if (!fcin)
    {
        cout << "文件1打开失败" << endl;
        return -1;
    }
    fstream fcout(argv[2]); //关联并打开参数指定的文件 默认打开in|out

    if (!fcout)
    {
        cout << "文件2打开失败" << endl;
        fcin.close();
        return -1;
    }

    Sales_data total;//用于保存同类书的数据总和

    if (read(fcin, total))
    {
        Sales_data next;
        while (read(fcin, next))
        {
            if (total.isbn() == next.isbn())//如果是相同书,则累加交易量
            {
                total.combine(next);//累加
            }
            else//碰到下一种书,则打印上一种书的交易总量
            {
                // 把上一种书的交易总量写入文件
                print(fcout, total) << endl;
                total = next;//为统计下一种书做准备
            }
        }
        print(fcout, total) << endl;// 补刀,写入最后一种书的交易总量
    }
    else
    {
        cout << "一条交易数据也没读取到" << endl;
    }

    fcin.close();
    fcout.close();
}

 

 练习8.8 

 

//修改上一题的程序,将结果追加到给定的文件末尾。对同一个输出文件,运行程序至少两次,检验数据是否得以保留。

#include <iostream>
#include <fstream>
using namespace std;
//已假设文件内同一类书的所有交易项(每单交易项)均是紧挨连续在一起的,且每行都一条订单交易项

int main(int args,char* argv[])
{
    fstream fcin(argv[1]);//关联并打开参数指定的文件
    if (!fcin)
    {
        cout << "文件1打开失败" << endl;
        return -1;
    }
    fstream fcout(argv[2],fstream::app); //关联并打开参数指定的文件 默认打开out|app

    if (!fcout)
    {
        cout << "文件2打开失败" << endl;
        fcin.close();
        return -1;
    }

    Sales_data total;//用于保存同类书的数据总和

    if (read(fcin, total))
    {
        Sales_data next;
        while (read(fcin, next))
        {
            if (total.isbn() == next.isbn())//如果是相同书,则累加交易量
            {
                total.combine(next);//累加
            }
            else//碰到下一种书,则打印上一种书的交易总量
            {
                // 把上一种书的交易总量写入文件
                print(fcout, total) << endl;
                total = next;//为统计下一种书做准备
            }
        }
        print(fcout, total) << endl;// 补刀,写入最后一种书的交易总量
    }
    else
    {
        cout << "一条交易数据也没读取到" << endl;
    }

    fcin.close();
    fcout.close();
}

 

练习8.9
使用你为8.1.2节第一个练习所编写的函数打印一个istringstream对象的内容。

那个题的循环读取的判断方式并不适合用读取字符串流对象上,因为用在字符串输入流对象中的数据结尾可能不存在空白符,导致在最后一次读取数据后无法再进入循环,造成最后一次的数据没有打印。.

或者说之前那个题的写法不好。不通用。

下面是其他人的代码:虽然考虑的简单,但胜在没BUG,通用。

//之前那个题的:

std::istream& func(std::istream &is)
{
    std::string buf;
    while (is >> buf)
        std::cout << buf << std::endl;
    is.clear();
    return is;
}




//现在这个题的:

#include <iostream>
#include <sstream>
using std::istream;

istream& func(istream &is)
{
    std::string buf;
    while (is >> buf)
        std::cout << buf << std::endl;
    is.clear();
    return is;
}

int main()
{
    std::istringstream iss("hello");
    func(iss);
    return 0;
}

 

标签:类库,std,const,istream,Sales,C++,IO,include,data
From: https://www.cnblogs.com/toupifama917/p/18413581

相关文章

  • 谷歌地图 | Navigation SDK 重磅发布!为你的 App 注入导航新体验
    9月17日,Google地图正式发布NavigationSDKforAndroid和iOS!借助NavigationSDK,开发者们现在可以更轻松地为用户打造定制化的导航体验,提升用户满意度,增强用户粘性。无论是界面风格、路线规划还是实时交通信息,SDK都能满足你的需求,帮助你打造一款更具竞争力的App。图例1Nav......
  • ehviewer安卓和IOS怎样安装?(已解决)
    ehviewer是一款非常流行的办公软件套件,它提供了类似Microsoftehviewer的功能,包括文字处理(ehviewerWriter)、电子表格(ehviewerSpreadsheet)和演示文稿(ehviewerPresentation)。以下是安装和配置ehviewerOffice的详细步骤及技巧,适用于Windows操作系统。对于其他操作系统(如......
  • 【每周例题】蓝桥杯 C++ 生物芯片
    生物芯片题目生物芯片题目分析·1.下面是亮灯规律,剩下的以此类推:我们可以看到,不亮灯的都是n的平方 2.所以亮灯的数目=该区间内所有灯的数量-不亮灯的数目(简而言之,所有不亮灯的号码开方后都是整数)代码#include<iostream>#include<cmath>usingnamespacestd;......
  • 分享C++程序员面试八股文(九)
    以下是C++常见八股文(九):一、模板元编程(TemplateMetaprogramming)解释模板元编程的概念和优势概念:模板元编程是一种在编译期进行编程的技术,利用C++模板的强大功能,通过模板参数和特化等机制,在编译期执行各种计算和类型操作。它可以被看作是一种将程序的一部分逻辑在编译......
  • 零基础学Axios
    Axios官网:Axios官网 想用Axios前需要在项目中安装axios,安装方式如下:下列是axios请去方式,本文主要讲解post和get请求,其他请求和这两种请求方法相同。1get请求1.1不带请求参数前端后端 1.2带请求参数 前端写法一(推荐)写法二:但是这种写法在遇到特殊字符,需要......
  • 谷歌地图 | Navigation SDK 重磅发布!为你的 App 注入导航新体验
    9月17日,Google地图正式发布NavigationSDKforAndroid和iOS!借助NavigationSDK,开发者们现在可以更轻松地为用户打造定制化的导航体验,提升用户满意度,增强用户粘性。无论是界面风格、路线规划还是实时交通信息,SDK都能满足你的需求,帮助你打造一款更具竞争力的App。Navigati......
  • Visual Instruction Tuning
    使用机器生成的指令跟踪数据对大型语言模型(LLM)进行指令调整已被证明可以提高新任务的零样本能力,但这个想法在多模态领域的探索较少。我们首次尝试使用纯语言GPT-4生成多模态语言图像指令跟踪数据。通过对此类生成的数据进行指令调整,我们引入了LLaVA:大型语言和视觉助手,这......
  • docker 配置代理访问Error response from daemon: Get “https://index.docker.io/v1/
    一、前言报错原因,docker访问不到外网。并且docker不能直接依赖操作系统环境的proxy,因此需要独立配置docker的proxy才能访问外网。问题描述dockersearchmysql出现以下报错:[root@localhost~]#dockersearchmysqlErrorresponsefromdaemon:Get"https://index.docke......
  • 文件IO:实现高效正确的文件读写
    背景本篇将会讲一些文件读写的推荐使用姿势以及编码时的注意事项,便于新手更好地理解如何高效地进行大文件读写,比如利用好缓冲区避免出现OOM,或者及时地释放资源以保证资源被及时地关闭,避免资源泄露。处理中文时读取到乱码大家都知道,中文的编码和英文的编码使用的字符集是不一样......
  • C++ 大佬 介绍
    1.ScottMeyers:身份:世界知名的C++程序员和作者。贡献:畅销书《EffectiveC++》和《MoreEffectiveC++》的作者,这些书籍被广大C++开发者视为必读经典。ScottMeyers的博客(TheViewfromAristeia)长期更新,内容涵盖C++编程的各个方面,以其深入浅出的分析和实用建议而受到广泛赞誉。......