字符串流
字符串流是以内存中用户定义的字符数组为输入输出对象,与内存相关,所以也称内存流。它也有相应的缓冲区,开始时流缓冲区是空的,如果向字符数组存入数据,随着向流插入数据,流缓冲区中的数据不断增加,待缓冲区满了(或遇到换行),一起存入字符数组;如果是从字符数组读数据,则先将字符数组~~串~~的数据~~组~~送到流缓冲区,然后从缓冲区提取数据赋给有关变量。
字符串流类有istrstream、ostrstream、strstream三个类,类名前的str是string的缩写,它们都包含在strstream头文件中,因此使用时要包含strstream头文件。这三个类也都是由istream、ostream和iostream类派生,因此对字符串流的操作方法与文件流是相同的,例如插入提取运算符、read()、write()函数等。接下来我们先来学习如何构造字符串流对象。
1、构造输出字符串流对象
ostrstream类用于构造输出字符串流对象,格式如下所示:
ostrstream ostr; //调用默认构造函数
ostrstream ostr(char* buf, int n, int mode = ios::out);
第一种形式是调用ostrstream类的~~默认~~无参构造函数,直接创建输出字符串流对象;第二种模式是调用ostrstream的带参构造函数,buf是与流关联的字符数组,n是指定的缓冲区大小(一般与字符数组大小相同,也可以不同),第三个参数是可选的,默认为ios::out模式。例如可以用下面的语句构造输出字符串流对象并与字符数组关联:
char buf[20];
ostrstream ostr(buf, 20);
建立输出字符串流对象并与字符数组buf关联(通过字符串流将数据输出到字符数组buf),流缓冲区大小为20。
2、构造输入字符串流对象
istrstream类用于构造输入字符串流对象,格式如下所示:
istrstream istr(char* buf,int mode = ios::in);
istrstream istr(char* buf, int n);
第一种形式是调用中,buf是与流关联的字符数组,第二个参数是可选的,默认模式是ios::in,这种形式并未指定缓冲区的大小,它是将buf中的全部数据作为输入字符串流的内容。第二种流对象构造形式与构造输出流对象相同,buf是与流关联的字符数组,n是流缓冲区大小。例如用这两种形式构造输入字符串流对象,代码如下所示:
char buf[20];
istrstream istr1(buf);
istrstream istr2(buf, 20);
3、构造输入输出字符串流对象
strstream类用于构造输入输出字符串流对象,格式如下所示:
strstream str;
strstream str(char* buf, int n , int mode = ios::in | ios::out);
它和构造输出字符串流相似,第一种形式是调用默认构造函数构造无参流对象;第二种形式是调用有参数构造函数构造流对象,参数含义与输出字符串流相同,第三个可选参数默认模式是ios::in|ios::out。例如可以用下列语句构造输入输出字符串流对象:
char buf[20];
strstream str(buf, 20);
str字符串流对象与buf关联,则它既可以从buf中读取数据又可以将数据写入到buf中。
为了让读者更好的掌握字符串流的用法,接下来我们将一个字符数组中的整数数值提取出来存入一个整型数组,按从小到大排序后再放回字符数组中,具体代码如例1所示。
例1
1 #include <iostream>
2 #include <strstream>
3 using namespace std;
4 int main()
5 {
6 char buf[50] = "12 25 68 -68 25 27 15 65 69 144";
7 int arr[10];
8 cout << "buf: " << buf << endl;
9
10 istrstream istr(buf, sizeof(buf)); //构造输入字符串流与buf关联
11 for (int i = 0; i < 10; i++)
12 istr >> arr[i]; //从字符数组buf中读入10个整数赋给整型数组arr
13 cout << "arr: ";
14 for (int i = 0; i < 10; i++)
15 cout << arr[i] << " ";
16 cout << endl;
17
18 for (int i = 0; i < 9; i++) //冒泡法对数组arr进行排序
19 {
20 for (int j = 0; j < 9 - i; j++)
21 {
22 if (arr[j] > arr[j + 1])
23 {
24 int temp = arr[j];
25 arr[j] = arr[j + 1];
26 arr[j + 1] = temp;
27 }
28
29 }
30 }
31 ostrstream ostr(buf, sizeof(buf)); //构造输出字符串流与buf关联
32 for (int i = 0; i < 10; i++)
33 ostr << arr[i] << " "; //将10个整数存放入字符数组buf
34 ostr << ends; //ends是C++的I/O操作符,插入一个'\0'
35 cout << "buf: " << buf << endl;
36
37 system("pause");
38 return 0;
39 }
运行结果如图1所示。
图1 例1运行结果
在例1中,先构造了输入字符串流并与字符数组buf关联,将buf中的整数值读取出来存入整型数组arr中,对arr进行冒泡排序。然后再构造输出字符串流,将arr中的数值存入字符数组buf中,由图6-18所知,两次读取写入都成功。
字符串流与文件流操作有很多相同之处,但也有以下不同点:
(1)输出数据时不是流向外存文件,而是流向内存中的一个存储空间;输入数据时是从内存中的存储空间读取数据。
(2)字符串流关联的不是文件,而是内存中的一个字符数组,因此不需要打开和关闭文件。
(3)每个文件的最后都有一个文件结束符表示文件的结束,而字符串流所关联的字符数组没有相应的结束标志,用户自己要指定一个特殊字符作为结束符,在向字符数组写入全部数据后要写入此字符。