向内存中的一个字符数组写数据就如同向数据文件写数据一样,但有3点不同:
ostrstream::ostrstream(char *buffer,int n,int mode=ios::out);
ostrstream strout(ch1,20);
,作用是建立输出字符串流对象strout,并使strout与字符数组ch1关联(通过字符串流将数据输出到字符数组ch1),流缓冲区大小为20。istrstream::istrstream(char *buffer); istrstream::istrstream(char *buffer,int n);
istrstream strin(ch2);
,作用是建立输入字符串流对象strin,将字符数组ch2中的全部数据作为输入字符串流的内容。istrstream strin(ch2,20);
,流缓冲区大小为20,因此只将字符数组ch2中的前20个字符作为输入字符串流的内容。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中的数据全部是以ASCII代码形式存放的字符,而不是以二进制形式表示的数据。
- 在建立字符串流strout时指定流缓冲区大小为30字节,与字符数组c的大小不同,这是允许的,这时字符串流最多可以传送30个字符给字符数组c
- 字符数组c中的数据之间没有空格,连成一片,这是由输出的方式决定的。如果以后想将这些数据读回赋给程序中相应的变量,就会出现问题,因为无法分隔两个相邻的数据。为解决此问题,可在输出时人为地加入空格。
例:在一个字符数组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; }
程序分析:
- 对字符串流的几点说明:
- 用字符串流时不需要打开和关闭文件
- 通过字符串流从字符数组读数据就如同从键盘读数据一样,可以从字符数组读入字符数据,也可以读入整数、浮点数或其他类型数据。如果不用字符串流,只能从字符数组逐个访问字符,而不能按其他类型的数据形式读取数据。这是用字符串流访问字符数组的优点,使用方便灵活。
- 程序中先后建立了两个字符串流strin和strout,与字符数组c关联。strin从字符数组c中获取数据,strout将数据传送给字符数组。分别对同一字符数组进行操作。甚至可以对字符数组交叉进行读写,输入字符串流和输出字符串流分别有流位置标记指示当前位置,互不干扰。
- 用输出字符串流向字符数组c写数据时,是从数组的首地址开始的,因此更新了
数组的内容。- 字符串流关联的字符数组并不一定是专为字符串流而定义的数组,它与一般的
字符数组无异,可以对该数组进行其他各种操作。
通过以上对字符串流的介绍,可以看到:与字符串流关联的字符数组相当于内
存中的临时仓库,可以用来存放各种类型的数据(以ASCII形式存放),在需要时再从中读回。它的用法相当于标准设备(显示器与键盘),但标准设备不能保存数据,而字符数组中的内容可以随时用ASCII字符输出。它比外存文件使用方便,不必建立文件(不需打开与关闭),存取速度快。但它的生命周与其所在的模块(如主函数)相同,该模块的生命周期结束后,字符数组也不存在了。因此只能作为临时的存储空间。