C++高级编程(8)

news2024/11/14 14:04:19

八、标准IO库

1.输入输出流类

1)非格式化输入输出

2)put

#include <iostream>
#include <string>
​
using namespace std;
int main()
{
    string str = "123456789";
    for (int i = str.length() - 1; i >= 0; i--) 
    {
        cout.put(str[i]); //从最后一个字符开始输出
    }
    
    cout.put('\n');
    return 0;
}

3)write

#include <iostream>
using namespace std;
​
int main() 
{
    const char * str = "www.cplusplus.com";
    cout.write(str, 4);
    
    return 0;
}

4)格式化输入/输出

  • C++提供了大量的用于执行格式化输入/输出的流操纵符和成员函数。

  • 功能:

    • 打印地址: cout << (void*)a;

    • 整数流的基数:dec、oct、hex和setbase

    • 设置浮点数精度:precision、setprecision

    • 设置域宽:setw、width

  • 注:如果用到了含参数的流操纵算子,则必须包含头文件< iomanip >。

5)<<运算符重载

class Complex
{
    double real,imag;
public:
    Complex( double r=0, double i=0):real(r),imag(i){ };
    friend ostream & operator<<( ostream & os,const Complex & c);
};
​
ostream & operator<<( ostream & os,const Complex & c)
{
    os << c.real << "+" << c.imag << "i";
    return os;
}
​
int main()
{
    Complex c(3, 5);
    int n = 220;
    cout << c << "," << n;
    
    return 0;
}

6)hex、oct、dec和setbase

#include <iostream>
#include <iomanip>
using namespace std;
​
int main()
{
    int number;
    cout << "Enter a decimal number: ";
    cin >> number;
    cout << number << " in hexadecimal is: " << hex<< number << endl;
    cout << dec << number << " in octal is: " << oct << number << endl;
    cout << setbase(10) << number << " in decimal is: " << number << endl;
    
    return 0;
}
​
/*
输出结果:
Enter a decimal
number: 20
20 in hexadecimal is:14
20 in octal is: 24
20 in decimal is: 20
*/

7)浮点精度(precision,setprecision)

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
​
int main()
{
    double root2 = sqrt( 2.0 );
    int places;
    
    // use fixed point format
    cout << fixed;
    for ( places = 0; places <= 9;places++ )
    {
        cout.precision( places );
        cout << root2 << endl;
    }
    for ( places = 0; places <= 9; places++ )
    {
        cout << setprecision( places ) <<
        root2 << endl;
    }
    return 0;
}

8)域宽(width,setw)

#include <iostream>
#include <iomanip>
using namespace std;
​
int main()
{
    int widthValue = 4;
    char sentence[ 10 ];
    cout << "Enter a sentence:" << endl;
    cin.width( 5 );
    while ( cin >> sentence )
    {
        cout.width( widthValue++ );
        cout << sentence << endl;
        //cout<<setw(widthValue++) << sentence << endl;
        cin.width( 5 );
    }
    
    return 0;
}

9)用户自定义的流操纵算子

#include <iostream>
using namespace std;
​
ostream& bell( ostream& output )
{
    return output << '\a'; // issue system beep
}
​
ostream& carriageReturn( ostream& output )
{
    return output << '\r'; // issue carriage return
}
​
ostream& tab( ostream& output )
{
    return output << '\t'; // issue tab
}
​
ostream& endLine( ostream& output )
{
    return output << '\n' << flush; // issue endl-like end of line
}
​
int main()
{
    cout << "Testing the tab manipulator:" << endLine<< 'a' << tab << 'b' << tab << 'c' << endLine;
    cout << "Testing the carriageReturn and bell manipulators:"<< endLine << "..........";
    cout << bell; // use bell manipulator
    cout << carriageReturn << "-----" << endLine;
​
    return 0;
}

2.文件操作

  • 临时数据

    • 存储在变量和数组中的数据是临时的,这些数据在程序运行结束后都会消失。

  • 文件

    • 目的:文件用来永久地保存大量的数据。

    • 存储:计算机把文件存储在二级存储设备中(特别是磁盘存储设备)。

1)文件中的数据层次

  • 位(bit): 最小数据项:0和1

  • 字符(character)/字节(byte)

    字符:数字、字母和专门的符号

    字节:0、1序列 (常见的是8位/字节)

    字符用字节表示

  • 域(field):一组有意义的字符

  • 记录(record)

    • 一组相关的域

    • 记录关键字(record key):用于检索

  • 文件(file):一组相关的记录

  • 数据库:一组相关的文件

2)文件和流

  • C++语言把每一个文件都看成一个有序的字节流(把文件看成n个字节)

  • 每一个文件或者以文件结束符(end-of-file marker)结束,或者在特定的字节号处结束

  • 当打开一个文件时,该文件就和某个流关联起来

  • 与这些对象相关联的流提供程序与特定文件或设备之间的通信通道

3)文件输出例子

#include <iostream>
#include <fstream> // file stream
#include <cstdlib>
using namespace std;
​
int main()
{
    ofstream outClientFile( "clients.dat", ios::out );//打开文件
    
    // exit program if unable to create file
    if ( !outClientFile ) // overloaded ! operator
    {
        cerr << "File could not be opened" << endl;
        exit( 1 );
    }
    
    cout << "Enter the account, name, and balance." << endl
    << "Enter end-of-file to end input.\n? ";
    
    int account;
    char name[ 30 ];
    double balance;
​
    // read account, name and balance from cin, then place in file
    while ( cin >> account >> name >> balance )
    {
        outClientFile << account << ' ' << name << ' ' << balance << endl;//写文件
        cout << "? ";
    }
    
    return 0; // ofstream destructor closes file
}
​
/*
输出结果:
Enter the account, name, and balance. Enter end-of-file to end input. ? 100 Jones 24.98
? 200 Doe 345.67
? 300 White 0
? 400 Stone -42.16
? 500 Rich 224.62
? ^z
*/

4)文件访问

  • 定义一个流对象

  • 打开文件

  • 访问文件

  • 关闭文件

(1)测试文件打开是否成功
  • 用重载的ios运算符成员函数operator!确定打开操作是否成功。如果open操作的流将failbit或badbit设置,则这个条件返回非0值(true)。

  • 可能的错误是:

    • 试图打开读取不存在的文件

    • 试图打开读取没有权限的文件

    • 试图打开文件以便写入而磁盘空间不足。

(2)测试文件结束符与不合法输入
  • 另一个重载的ios运算符成员函数operator void将流变成指针,使其测试为0(空指针)或非0(任何其他指针值)。如果failbit或badbit对流进行设置,则返回0(false)。

  • 下列while首部的条件自动调用operator void*成员函数:

    Line 26: while (cin >> account >> name >>balance )只要cin的failbit和badbit都没有设置,则条件保持true。输入文件结束符设置cin的failbit。operator void*函数可以测试输入对象的文件结束符,而不必对输入对象显式调用eof成员函数。

(3)打开输入文件
  • ifstream inClientFile( “clients.dat” , ios::in );

  • 生成ifstream对象inClientFile,并将其与打开以便输入的文件clients.dat相关联。括号中的参数传入ifstream构造函数,打开文件并建立与文件的通信线路。

  • 打开ifstream类对象默认为进行输入,因此下列语句等价:

    ifstream inClientFile( “Clients.dat” );

  • 和ofstream对象一样,ifstream对象也可以生成而不打开特定文件,然后再将用open对象与文件相连接。

//文件输出例子
#include <iostream>
#include <fstream> // file stream
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
​
void outputLine( int, const string, double ); // prototype
​
int main()
{
    // ifstream constructor opens the file
    ifstream inClientFile( "clients.dat", ios::in );
    
    // exit program if ifstream could not open file
    if ( !inClientFile )
    {
        cerr << "File could not be opened" << endl;
        exit( 1 );
    } // end if
    
    int account;
    char name[ 30 ];
    double balance;
    cout << left << setw( 10 ) << "Account" << setw( 13 )<< "Name" << "Balance" << endl << fixed << showpoint;
​
    // display each record in file
    while ( inClientFile >> account >> name >> balance )
    {
        outputLine( account, name, balance );
    }
    return 0; // ifstream destructor closes the file
}
​
    // display single record from file
    void outputLine( int account, const string name, double balance )
    {
    cout << left << setw( 10 ) << account << setw( 13 ) << name<< setw( 7 ) << setprecision( 2 ) << right << balance << endl;
    }

5)文件位置指针

  • 为了按顺序检索文件中的数据,程序通常要从文件的起始位置开始读取数据,然后连续地读取所有的数据,直到找到所需要的数据为止。可能需要反复多次。

  • 文件位置指针( file position pointer):用于指示读写操作所在的下一个字节号;是个整数值,指定文件中离文件开头的相对位置(也称为离文件开头的偏移量)

6)文件指针重新定位

  • istream类和ostream类都提供成员函数,使文件位置指针重新定位

    • istream类的seekg (即“seekget”) :每个istream对象有个get指针,表示文件中下一个输入相距的字节数

    • ostream类的seekp (即“seekput”):每个ostream对象有一个put指针,表示文件中下一个输出相距的字节数

  • seekg和seekp的第一个参数通常为long类型的整数,表示偏移量。第二个参数可以指定寻找方向:

    ios::beg(默认)相对于流的开头定位

    ios::cur相对于流当前位置定位

    ios::end相对于流结尾定位

7)获取文件指针值

  • 成员函数tellg和tellp分别返回get和put指针的当前位置。

下列语句将get文件位置指针值赋给long类型的变量

location。

location = filObject.tellg();

8)更新顺序访问文件

  • 格式化和写入顺序访问文件的数据修改时会有破坏文件中其他数据的危险

  • 例如,如果要把名字“White”改为“Worthington” ,则不是简单地重定义旧的名字。White的记录是以如下形式写入文件中的:

    300 White 0.00

    如果用新的名字从文件中相同的起始位置重写该记录,记录的格式就成为:

    300 Worthington 0.00

  • 因为新的记录长度大于原始记录的长度,所以从“Worthington”的第二个“o”之后的字符将重定义文件中的下一条顺序记录。

  • 出现该问题的原因在于:在使用流插入运算符<<和流读取运算符>>的格式化输入,输出模型中,域的大小是不定的,因而记录的大小也是不定的。例如,7、14、-117、2047和27383都是int类型的值,虽然它们的内部存储占用相同的字节数,因此,格式化输入输出模型通常不用来更新已有的记录。

  • 一种解决方法:将在3000 White 0.00之前的记录复制到一个新的文件中,然后写入新的记录并把300 White 0.00之后的记录复制到新文件中。这种方法要求在更新一条记录时处理文件中的每一条记录。如果文件中一次要更新许多记录,则可以用这种方法。

3.STRING类

  • C++、java等编程语言中的字符串。

  • 在java、C#中,String类是不可变的,对String类的任何改变,都是返回一个新的String类对象。

  • String 对象是 System.Char 对象的有序集合,用于表示字符串。String 对象的值是该有序集合的内容,并且该值是不可变的

为什么需要string?

  • 在内部进行内存分配,从而保证应用程序的健壮性

  • 提供了拷贝构造函数和复制运算符,确保字符串的正确复制

  • 减少程序员创建和操作字符串需要做的工作

  • 提供了增删改查的操作,让程序员可以把精力放在应用程序的主要需求上,而不是字符串的操作细节。

1)string对象的定义和初始化

string s1;
string s2(s1);
string s3("value");
string s4(n,'c');

2)string对象的读写

  • 读入未知数目的string对象

    while(cin>>world)

    cout <<world <<endl;

  • 用getline读取整行

    getline(cin, s);

3)string对象的操作

s.empty();
s.size();
s[n]; //下标操作 范围0~?
s1+s2;
s1=s2;
v1==v2;
!= < <=
> >=

4)string对象中字符的处理

4.异常处理

1)C错误处理机制

  1. 函数返回错误编码

  2. 使用全局变量保存错误编码

  3. 出错时终止程序运行

  • 缺点:

    • 难以统一标准

    • 复杂

    • 构造和析构函数没有返回值

    • 出错就返回,用户接受度低

2)异常处理机制

  • C++异常处理的基本思想是简化程序的错误代码,为程序的健壮性提供了一个标准检测机制:若底层发生问题,则逐级上报,直到有能力处理此异常为止。

  • 异常处理的优势:

  1. 增强程序的健壮性。

  2. 使代码变得更简洁优美,更易维护。

  3. 错误信息更灵活丰富。

  • 缺点:

  1. 性能下降5%~14%。

2. 破坏了程序的结构性。

  1. 完成正确的异常安全的代码,需要付出更大的代价。

3)抛出异常

任何时候,程序在执行中遇到了非正常状况都可以抛出异常异常用throw语句抛出

A *p = new A;

if (p == NULL)

{

throw string(“Out of Memory.”);

}

一旦抛出异常,则程序将在throw语句处跳出

4)捕获异常

异常也由程序员负责捕获

用try{…}catch( ){…}语句来捕获异常

没有捕获的异常将被忽略

try{

// 可能抛出异常的语句

}catch(exceptionType variable){

// 处理异常的语句

}

//捕获异常的例子
#include <iostream>
#include <string>
#include <exception>
using namespace std;
​
int main()
{
    string str = "http://www.cplusplus.com";
    try{
        char ch1 = str[100];
        cout<<ch1<<endl;
        }catch(exception e){
            cout<<"[1]out of bound!"<<endl;
        }
    
    try{
    char ch2 = str.at(100);
    cout<<ch2<<endl;
        }catch(exception &e){ //exception类位于<exception>头文件中
            cout<<"[2]out of bound!"<<endl;
        }
    
    return 0;
}
//捕获任意异常例子
#include <iostream>
using namespace std;
int main( )
{
    int a, b;
    a = 8;
    b = 0;
    try
    {
        if (b == 0)
        {
        throw "Divided by Zero!";
        }else
        {
        double c = a/b;
        cout << c << endl;
        }
    }catch(...)
    {
    cout << "Exception caught!" << endl;
    }
}

5)异常处理的流程

抛出(Throw)--> 检测(Try) --> 捕获(Catch)

6)异常的传递

  • 产生异常之后,程序会立刻跳转

    • 跳出到最近的一层捕获异常的语句

    • 如果当前没有捕获语句或者捕获语句中没有匹配的异常,则程序会跳出当前的函数

  • 在函数的调用处,如果没有捕获住异常,则直接跳转到更高一层的调用者

  • 如果一直没有捕获该异常,C++将会使用默认的异常处理函数

    • p 该处理函数可能会让程序最终跳出main函数并导致程序异常终止

7)C++标准的异常

8)异常的说明

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2237637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 分子图分类,GNN Model for HIV Molecules Classification,HIV 分子图分类模型;整图分类问题,代码实战

一、分子图 分子图&#xff08;molecular graph&#xff09;是一种用来表示分子结构的图形方式&#xff0c;其中原子被表示为节点&#xff08;vertices&#xff09;&#xff0c;化学键被表示为边&#xff08;edges&#xff09;。对于HIV&#xff08;人类免疫缺陷病毒&#xff…

如何调整pdf的页面尺寸

用福昕阅读器打开pdf&#xff0c;进入打印页面&#xff0c;选择“属性”&#xff0c;在弹出的页面选择“高级” 选择你想调成的纸张尺寸&#xff0c;然后打印&#xff0c;打印出来的pdf就是调整尺寸后的pdf

查缺补漏----用户上网过程(HTTP,DNS与ARP)

&#xff08;1&#xff09;HTTP 来自湖科大计算机网络微课堂&#xff1a; ① HTTP/1.0采用非持续连接方式。在该方式下&#xff0c;每次浏览器要请求一个文件都要与服务器建立TCP连接当收到响应后就立即关闭连接。 每请求一个文档就要有两倍的RTT的开销。若一个网页上有很多引…

koa、vue安装与使用

koa官网&#xff1a;https://koajs.com/ 首选创建一个文件夹&#xff1a;mkdir koaDemo (cmd即可) 文件夹初始化&#xff1a;npm init (cmd即可) 初始化完成后就会产生一个package.json的文件。 安装&#xff1a; npm install koa --save (vscode的控制台中安装&a…

Linux:版本控制器git的简单使用+gdb/cgdb调试器的使用

一&#xff0c;版本控制器git 1.1概念 为了能够更方便我们管理不同版本的文件&#xff0c;便有了版本控制器。所谓的版本控制器&#xff0c;就是能让你 了解到⼀个文件的历史&#xff0c;以及它的发展过程的系统。通俗的讲就是⼀个可以记录工程的每⼀次改动和版本迭代的⼀个…

ML 系列:第 21 节 — 离散概率分布(二项分布)

一、说明 二项分布描述了在固定数量的独立伯努利试验中一定数量的成功的概率&#xff0c;其中每个试验只有两种可能的结果&#xff08;通常标记为成功和失败&#xff09;。 二、探讨伯努利模型 例如&#xff0c;假设您正在抛一枚公平的硬币 &#xff08;其中正面成功&#xff…

【优选算法篇】微位至简,数之恢宏——解构 C++ 位运算中的理与美

文章目录 C 位运算详解&#xff1a;基础题解与思维分析前言第一章&#xff1a;位运算基础应用1.1 判断字符是否唯一&#xff08;easy&#xff09;解法&#xff08;位图的思想&#xff09;C 代码实现易错点提示时间复杂度和空间复杂度 1.2 丢失的数字&#xff08;easy&#xff0…

存算分离与计算向数据移动:深度解析与Java实现

背景 随着大数据时代的到来&#xff0c;数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构&#xff0c;即计算资源与存储资源紧密耦合&#xff0c;在处理海量数据时逐渐显露出其局限性。为了应对这些挑战&#xff0c;存算分离&#xff08;Disaggrega…

WPS单元格重复值提示设置

选中要检查的所有的单元格 设置提示效果 当出现单元格值重复时&#xff0c;重复的单元格就会自动变化 要修改或删除&#xff0c;点击

Linux笔记之pandoc实现各种文档格式间的相互转换

Linux笔记之pandoc实现各种文档格式间的相互转换 code review! 文章目录 Linux笔记之pandoc实现各种文档格式间的相互转换1.安装 Pandoc2.Word转Markdown3.markdown转html4.Pandoc 支持的一些常见格式4.1.输入格式4.2.输出格式 1.安装 Pandoc sudo apt-get install pandoc # …

MySQL重难点(一)索引

目录 一、引子&#xff1a;MySQL与磁盘间的交互基本单元&#xff1a;Page 1、重要问题&#xff1a;为什么 MySQL 每次与磁盘交互&#xff0c;都要以 16KB 为基本单元&#xff1f;为什么不用多少加载多少&#xff1f; 2、有关MySQL的一些共识 3、如何管理 Page 3.1 单个 P…

solo博客使用非docker方式进行https部署

solo博客使用非docker方式进行https部署 数据库配置启动命令讲解设置自定义访问端口&#xff1a;9168 配置https访问部署效果 服务器上请通过 Docker 部署。但是我服务器资源有限&#xff0c;不想安装docker&#xff0c;直接以编译包的形式运行&#xff0c;节省资源。 如果不会…

【Steam登录】protobuf协议逆向 | 续

登录接口&#xff1a; ‘https://api.steampowered.com/IAuthenticationService/BeginAuthSessionViaCredentials/v1’ 精准定位&#xff0c;打上条件断点 this.CreateWebAPIURL(t) ‘https://api.steampowered.com/IAuthenticationService/BeginAuthSessionViaCredentials/v1…

环形链表问题(图 + 证明 + 题)

文章目录 判断链表是否有环返回链表开始入环的第一个结点 判断链表是否有环 题目链接 思路&#xff1a; 可以明确的是&#xff1a;若一个链表带环&#xff0c;那么用指针一直顺着链表遍历&#xff0c;最终会回到某个地方。 我们可以定义两个指针&#xff08;快慢指针&#xf…

Linux Centos7 如何安装图形化界面

如果系统是以最小安装的话,一般是不带有图形化界面的,如果需要图形话界面,需要单独安装。本篇教程,主要介绍如何在CentOS7中安装图形化界面。 1、更新系统 首先,保证系统依赖版本处于最新。 sudo yum update -y2、安装 GNOME 桌面环境 sudo yum groupinstall "GNOME…

Spark的学习-02

Spark Standalone集群的安装 架构&#xff1a;普通分布式主从架构 主&#xff1a;Master&#xff1a;管理节点&#xff1a;管理从节点、接客、资源管理和任务 调度&#xff0c;等同于YARN中的ResourceManager 从&#xff1a;Worker&#xff1a;计算节点&#xff1a;负责利用自己…

Linux相关概念和易错知识点(20)(dentry、分区、挂载)

目录 1.dentry &#xff08;1&#xff09;路径缓存的原因 &#xff08;2&#xff09;dentry的结构 ①多叉树结构 ②file和dentry之间的联系 ③路径概念存在的意义 2.分区 &#xff08;1&#xff09;为什么要确认分区 &#xff08;2&#xff09;挂载 ①进入分区 ②被挂…

《Linux运维总结:基于银河麒麟V10+ARM64架构CPU部署redis 6.2.14 TLS/SSL哨兵集群》

总结:整理不易,如果对你有帮助,可否点赞关注一下? 更多详细内容请参考:《Linux运维篇:Linux系统运维指南》 一、简介 Redis 哨兵模式是一种高可用性解决方案,它通过监控 Redis 主从架构,自动执行故障转移,从而确保服务的连续性。哨兵模式的核心组件包括哨兵(Sentine…

vue3实现一个无缝衔接、滚动平滑的列表自动滚屏效果,支持鼠标移入停止移出滚动

文章目录 前言一、滚动元素相关属性回顾一、实现分析二、代码实现示例&#xff1a;2、继续添加功能&#xff0c;增加鼠标移入停止滚动、移出继续滚动效果2、继续完善 前言 列表自动滚屏效果常见于大屏开发场景中&#xff0c;本文将讲解用vue3实现一个无缝衔接、滚动平滑的列表自…

腾讯云nginx SSL证书配置

本章教程,记录在使用腾讯云域名nginx证书配置SSL配置过程。 一、nginx配置 域名和证书,替换成自己的即可。证书文件可以自定义路径位置。服务器安全组或者防火墙需要开放80和443端口。 server {#SSL 默认访问端口号为 443listen 443 ssl; #请填写绑定证书的域名server_name c…