4 .3字符串输入输出流
字符串输人输出流类直接对内存而不是对文件和标准输出进行操作,它使用与 cin 及cout 相同的读取和格式化函数来操纵内存中的数据,所有字符串流类的声明都包含在标准头文件<sstream>中。标准库定义了三种类型的字符串流。
istringstream:字符串输人流,提供读 string 功能。
ostringstream;字符串输出流,提供写 string 功能
stringstream:字符串输人输出流,提供读写 string 功能。
利用字符串输人输出流,可以方便地把多种基本数据类型组合成字符串,也可以反解字符串给各种变量赋值。
例:下列中反解字符串给各变量赋值(拆分)
#include <fstream>
#include <iostream>
#include <sstream>//添加了头文件 <sstream>,因为代码中使用了 istringstream 类
using namespace std;
int main() {
int n; // 声明一个整数变量 n
float f; // 声明一个浮点数变量 f
string strHello; // 声明一个字符串变量 strHello
string strText = "1 3.14 hello"; // 定义一个字符串变量 strText,并赋值为 "1 3.14 hello"
istringstream s(strText); // 创建一个字符串流对象 s,并将 strText 作为其初始化参数
s >> n; // 将字符串流 s 中的一个整数值读取到变量 n 中
s >> f; // 将字符串流 s 中的一个浮点数值读取到变量 f 中
s >> strHello; // 将字符串流 s 中的一个字符串值读取到变量 strHello 中
cout << "n = " << n << endl; // 输出变量 n 的值
cout << "f = " << f << endl; // 输出变量 f 的值
cout << "strHello = " << strHello << endl; // 输出变量 strHello 的值
return 0;
}
例:合并不同类型的数据到字符串(合并)下列中要求用户依次输入一个整数和一个浮点数,然后读取一行字符串。接着,使用字符串流 os 构建一个包含输入数据的字符串,并将其输出到屏幕上
#include <fstream>
#include <iostream>
#include <sstream>//添加了头文件 <sstream>,因为代码中使用了 istringstream 类
using namespace std;
int main() {
cout<<"type an int,a float and a string:";
int i;
float f;
string stuff;
cin>>i>>f;//从标准输入流中依次读取一个整数和一个浮点数,并将它们分别存储到变量 i 和 f 中
getline(cin,stuff);//从标准输入流中读取一行字符串,并将该行字符串存储到变量 stuff 中。
//这里使用 getline 函数是为了读取整数和浮点数后的换行符,以便后续操作
ostringstream os;//创建一个字符串流对象 os,用于构建字符串
os<<"integer="<<i<<endl;//向字符串流 os 中写入 "integer = " 和变量 i 的值,并添加换行符
os<<"float="<<f<<endl;
os<<"string="<<stuff<<endl;
string result=os.str();
cout<<result<<endl;
return 0;
}
综合示例:流和重载的结合。尽管 cin.cout 可以自动对基本数据类型或字符 string 等进行输入输出操作是在基些情况下若想对类对象直接进行输人输出操作是不行的,必须重载 operator <<和operator>>。示例从键盘中输人学生属性值,并在屏幕上重新显示。
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
string strName;
string strSex;
int nAge;
};
//is >> s.strName 从输入流中读取一个字符串,并将其存储到 s.strName 中。
//is >> s.strSex 从输入流中读取一个字符串,并将其存储到 s.strSex 中。
//is >> s.nAge 从输入流中读取一个整数,并将其存储到 s.nAge 中
istream& operator>>(istream& is, Student& s) {
is >> s.strName >> s.strSex >> s.nAge;
return is;//函数返回输入流的引用 is
}
ostream& operator<<(ostream& os, Student& s) {
os << "Student 输出是:" << endl;//将字符串 "Student 输出是:" 输出到输出流 os 中
os << s.strName << "\t" << s.strSex << "\t" << s.nAge << endl;
//将学生对象 s 的姓名、性别和年龄以制表符的形式输出到输出流 os 中,并添加换行符
return os;
}
//定义了一个函数 f,用于输出学生对象的数据
void f(const Student& s) {
cout << s;
}
int main(int argc, char* argv[]) {
Student s;
cout << "输入数据: ";
//使用输入运算符 >> 从标准输入流 cin 中读取数据,并将数据存储到 s 对象中。
//这里调用了之前定义的重载的输入运算符operator>>
cin >> s;
//使用输出流 cout 将学生对象 s 的数据输出到标准输出流。
//这里调用了之前定义的重载的输出运算符 operator<<
cout << s;
//调用函数 f 并传入学生对象 s,以输出学生对象的数据
f(s);
return 0;
}
例:编写一个程序,从文本文件中读人每个学生的各科成绩,并在屏幕上是学生各科成绩及总成绩。
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
using namespace std;
class Student{
public:
string strName;
int nYuwen;
int nMath;
int nForeign;
//重载了输入运算符 >>,用于从输入流中读取数据并存储到 Student 对象 s 的成员变量中
istream& operator>>(istream& is, Student& s){
//输入流的引用 is 和学生对象的引用 s 是函数的参数
is >> s.strName >> s.nYuwen >> s.nMath >> s.nForeign;
return is;
}
//重载了输出运算符 <<,用于将 Student 对象 s 的数据输出到输出流中
ostream& operator<<(ostream& os, Student& s){
int nTotal = s.nYuwen + s.nMath + s.nForeign;
os << s.strName << "\t" << s.nYuwen << "\t" << s.nMath << "\t" << s.nForeign << "\t" << nTotal << "\n";
return os;
//返回输出流 os 的引用,以便实现链式输出
}
};
int main(int argc, char* argv[]){
ifstream in("d:\\data.txt");
Student s;
while (!in.eof()){//eof() 函数用于检查文件流是否已经到达文件末尾
//使用重载的输入运算符 >>,从输入文件流 in 中读取数据,并将数据存储到 Student 对象 s 中。
//这里使用了先前重载的 istream& operator>>(istream& is, Student& s) 函数
in >> s;
cout << s;//同理
}
in.close();
return 0;
}
4.4 习题
1.stringstream和其他流有何区别?
答: 可以把多种基本数据类型组合成字符串,也可以反解字符串给各种变量赋值。Stringstream提供读写string的功能 。字符串输入输出流直接对内存而不是对文件和标准输出进行操作
2.利用字符串流,如何将整型数据50,转换成,50”?
答:
Int(int argc,char *argv)
{
*****************************
Stringstream os;
Os<<int;
Os>>*argv;
******************************
Return 0;
}
3.整型数据与字符串互相转化
#include<string>
#include<sstream>
int main(int argc, char *argv[ ]) {
//将整型10转化成字符串10
int n1=10;
string s1;
stringstream os1;
os1<<n1;
os1>>s1;
cout<<"整型10转化成字符串10:"<<s1<<endl;
//将字符串123转化成整型123
int n2=0;
string s2=”123”;
stringstream os2;
os2<<s2;
os2>>n2;
cout<<"字符串123转化成整型123:”<<n2<<end1;
return 0; }
4.反解字符串给各变量赋值
#include< sstream>
int main(){
int n;
float f;
string StrHello;
string strText=”1 3.14 hello”;
istringstream s(strText);
s>>n;
s>>f;
s>>StrHello;
cout<<"n="<<n<<endl;
cout<<f="<<f<<endl;
cout<<"strHello="<strHello<endl; }
5. 找出字符串中数字2出现的次数,要求使用stringstream, map解决该问题(15分)。
#include <iostream>#include <map>#include <string> #include <sstream>
using namespace std;
int main()
{
string s1 = “1 2 3 4 5 2 2 1 ”;
①选择合理的map结构(数字---->频次)的实例m;
map<int,int>m;
②从s1构建istringstream实例is;
istringstream is(s1);
③从istringstream构造map实例
while(is.eof()!=true)
{ int num;
is>>num;
m[num]++; }
④查询map,返回2出现的频次
cout << "出现2的次数m[2]=" << m[2] << endl;
return 0;
}
6.使用字符串输入流对象需要宣称变量的类型为____istringstream_______。