字符串流
- 文件流是以外存文件为输入输出对象的数据流,字符串流不是以外存文件为输入输出的对象,而以内存中用户定义的字符数组(字符串)为输入输出的对象,即将数据输出到内存中的字符数组,或者从字符数组(字符串)将数据读入。字符串流也称为内存流。
向内存中的一个字符数组写数据就如同向数据文件写数据一样,但有3点不同:
- 输出时数据不是流向外存文件,而是流向内存中的一个存储空间。输入时从内存中的存储空间读取数据。在严格的意义上说,这不属于输入输出,称为读写比较合适。因为输入输出一般指的是在计算机内存与计算机外的文件(外部设备也视为文件)之间的数据传送。但由于C++的字符串流采用了C++的流输入输出机制,因此往往也用输入和输出来表述读写操作。
- 字符串流对象关联的不是文件,而是内存中的一个字符数组,因此不需要打开和关闭文件
- 每个文件的最后都有一个文件结束符,表示文件的结束。而字符串流所关联的字符数组中没有相应的结束标志,用户要指定一个特殊字符作为结束符,在向字符数组写入全部数据后要写入此字符
建立输出字符串流对象
- ostrstream类提供的构造函数的原型为:
ostrstream::ostrstream(char *buffer,int n,int mode=ios::out);
- buffer是指向字符数组首元素的指针,n为指定的流缓冲区的大小(一般选与字符数组的大小相同,也可以不同),第3个参数是可选的,默认为ios::out方式。
- 可以用以下语句建立输出字符串流对象并与字符数组建立关联:
ostrstream strout(ch1,20);
,作用是建立输出字符串流对象strout,并使strout与字符数组ch1关联(通过字符串流将数据输出到字符数组ch1),流缓冲区大小为20。
建立输入字符串流对象
- istrstream类提供了两个带参的构造函数,原型为:
istrstream::istrstream(char *buffer);
istrstream::istrstream(char *buffer,int n);
- buffer是指向字符数组首元素的指针,用它来初始化流对象(使流对象与字符数组建立关联)。
- 可以用以下语句建立输入字符串流对象:
istrstream strin(ch2);
,作用是建立输入字符串流对象strin,将字符数组ch2中的全部数据作为输入字符串流的内容。istrstream strin(ch2,20);
,流缓冲区大小为20,因此只将字符数组ch2中的前20个字符作为输入字符串流的内容。
建立输入输出字符串流对象
- strstream类提供的构造函数的原型为:
strstream::strstream(char *buffer int n,int mode);
- 可以用以下语句建立输入输出字符串流对象:
strstream strio(ch3,sizeof(ch3),ios:in | ios:out);
,作用是建立输入输出字符串流对象,以字符数组ch3为输入输出对象,流缓冲区大小与数组ch3相同。
以上个字符串流类是在头文件strstream中定义的,因此程序中在用到istrstream、 ostrstream 和strstream 类时应包含头文件strstream (在GCC中,用头文件strstream) 。
例:将一组数据保存在字符数组中
#include <strstream>
using namespace std;
struct student
{
int num;
char name[20];
float score;
};
int main()
{
student stud[3] = { 1001, "Li", 78, 1002, "Wang", 89. 5, 1004, "Fun",90 };
char c[50]; //用户定义的字符数组
ostrstream strout(c, 30); //建立输出字符串流,与数组c建立关联,缓冲区长30
for (int i = 0; i < 3; i++) //向字符数组c写3个学生的数据
strout << stud[i].num << stud[i].name << stud[i].score;
strout << ends; //ends是C++的I/O操作符,插入一个'\0'
cout << "array c:" << c << endl; //显示字符数组c中的字符
return 0;
}
运行结果:
array C:
1001Li781002Wang89.51004Fung9O
程序分析:
例:在一个字符数组c中存放了个整数,以空格相间隔,要求将它们放到整型数组中,再按大小排序,然后再存放回字符数组c中
#include <strstream>
using namespace std;
int main()
{
char c[50] = "12 34 65 -23 -32 33 61 99 321 32";
int a[10], i, j, t;
cout << "array c:" << c << endl; //显示字符数组中的字符串
istrstream strin(c, sizeof(c)); //建立输入串流对象strin并与字符数组c关联
for (i = 0; i < 10; i++) strin >> a[i]; //从字符数组c读入个整数赋给整型数组a
cout << "array a:";
for (i = 0; i < 10; i++) cout << a[i] << " "; //显示整型数组a各元素
cout << endl;
for (i = 0; i < 9; i++) // 用起泡法对数组a排序
for (j = 0; j < 9 - i; j++)
if (a[j] > a[j + 1])
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
ostrstream strout(c, sizeof(c)); //建立输出串流对象strout并与字符数组c关联
for (i = 0; i < 10; i++) strout << a[i] << " "; //将个整数存放在字符数组c
strout << ends; //加入'\0'
cout << "arry c:" << c << endl; //显示字符数组c
return 0;
}
程序分析:
通过以上对字符串流的介绍,可以看到:与字符串流关联的字符数组相当于内
存中的临时仓库,可以用来存放各种类型的数据(以ASCII形式存放),在需要时再从中读回。它的用法相当于标准设备(显示器与键盘),但标准设备不能保存数据,而字符数组中的内容可以随时用ASCII字符输出。它比外存文件使用方便,不必建立文件(不需打开与关闭),存取速度快。但它的生命周与其所在的模块(如主函数)相同,该模块的生命周期结束后,字符数组也不存在了。因此只能作为临时的存储空间。