myString = \已经被执行
第三个例子中,指定长度为0产生空串作为结果。第四个例子显示了在开始位置后如果第二个自变量指定的字符数比存在的字符多所发生的情况:substr 返回从开始位置到串的结尾的字符。最后例子说明了第一个自变量(即开始位置)不能超出串的末尾外面。
由于substr 返回一个串类型值,你能够使用这个值用连接运算符(+)连接到串块并把它们连接在一起形成新串。
这里是一个使用几个串操作的代码段: string fullName ; string name;
string:: size_type startPos ;
fullName = \startPos = fullName .find(\
name = \cout << name << endl;
当这个代码段被执行时,输出Mr .Peterson。首先它存储一个串到变量fullName中, 然后它使用find 在串内找出名为Peterson的开始位置,接下来连接字面串\与字符Peterson(Peterson由原串拷贝而来)建立一个新串,最后打印出新串。
下列表总结了我们在本章已经看到了的串操作。
第四章 程序输入和软件设计过程
目标:
? 能够构造一个输入语句来读一个值到程序中。 ? 能够确定输入语句赋值给变量的内容。 ? 能够为人机对话写适当的提示信息。
? 知道什么时候非交互输入/输出是合适的,如何不同于人机对话式输入/输出。 ? 能够写出使用数据文件进行输入和输出的程序。 ? 理解面向对象设计的基本原理。
? 能够应用函数功能分解方法解决一个简单问题。
? 够使用文件自身代码,取得一个函数功能分解并在C++中用代码表示它。 4.1 将数据取到程序中
从外面将数据值安置到程序变量中的过程被称为输入,用于程序的数据可以是来自一个输入设置或一个辅助存储设备的文件。这里我们考虑标准输入设备——键盘。 输入流和抽出运算符(>>)
像第3章开始那样,你可以认为输出流像无尽止的字符序列从你的程序流到输出设备上,同样,可以认为输入流像无尽止的字符序列从输入设备流到你的程序中。
头文件iostream包含了两个数据类型的定义:istream和ostream,这些数据类型分别描述了输入流和输出流。头文件中也包含了像这样的声明: istream cin: ostream cout:
第一个声明是说cin是一个istream类型的变量。第二个声明是说cout一个ostream类型的变量。此外。cin与标准输入设备(键盘)联系在一起,并且cout与标准输出设备(通常是显示屏)联系在一起。
正你已经看到一样,你可以使用插入运算符(<<)输出值到cout,(<<)有时发音”put to” cout << 3*price;
用类似的方式,你可以使用抽取运算符(>>)从cin输入数据,(>>)有时发音”get from”: cin>>cost ;
当计算机执行这条语句时,它输入接下来你从键盘上打入的数(例如,425),并将它存储到变量cost中。 抽取运算符>>取两个操作数,它的左边操作数是一个流表达式(cin),它的右边操作数是一个变量,我们将输入的数据存储到这个变量中。
你可以在一个输入语句中使用几次>>操作符,每次出现>>,从输入流抽取(输入)接下来的数据项, 例如:下列语句 cin>>length>>width; 和两条语句 cin>>length; cin>>width; 之间没有差别。
指定在一条输入语句中的项目只能是变量名。
当你从键盘输入数据时,你必须肯定在输入语句中,每个数据值与变量的数据类型是一致的。
当在流中寻找下一个输入值时,>>操作符跳过任何引导的空白字符,空白字符是空格和某些不能打印的字符。在跳过了这些字符后,>>操作符继续从输入流中抽取所要的数据值。如果这个数据值是一个char值,那么当输入一个字符时,输入就停止。如果数据值是int或float,在输入第一个与数据类型不一致的字符(如空白字符)时,数据输入停止。
这里是一些例子,此处,i,j和k是整型int变量,ch是字符char变量,并且x是一个实型变量。 例(1)和例(2)是直接输入整型值的例子;例(3)表明当输入字符时,你不能使用引号将字符数据值括起来;例(4)显示了如何跳过空白字符的过程,如果需要的话,包括继续输入下一行;例(5)表明遇到第一个与数字类型不符合的字符时,结束数字。在输入字符A时,对变量i的输入停止,之后A被存储到ch,然后在输入行结束时,对x的输入停止;例(6)表明如果你在键盘上没有输入足够的值来满足输入语句,那么计算机会等待下一个数据;例(7)表明如果输入的值多于输入语句中变量,多余的值会留在输入流中直到他们下一个输入流语句读入。如果有多余的值留下,当程序结束时,计算机忽略它们。 新行字符
每个输入行有一个看不见的行结束字符(新行字符),它告诉计算机一行的结束和下一行的开始,为了找出下一个输入值有必要的话,>>操作符会越过行边界(新行字符)。
当你用键盘操作时,每次你击Return或Enter键就产生一个新行字符,当在输出语句中使用endl控制符,你的程序也产生一个新行字符。Endl控制符产生一个新行,告诉屏幕光标到下一行。
在C++程序中,使用两个符号\\n,反斜杠和n,中间没有空格,来直接涉及新行字符。虽然\\n由两个字符组成,但它只是一个涉及空行字符的字符。正如你可以存储字母A到一个char变量ch这样: ch=’A’;
你也能存储新行字符到一个变量中 ch=’\\n’;
用get函数读字符数据
像我们讨论的一样,>>操作符跳过在输入流中前导空白字符,假如ch1和ch2是char变量,程序执行语句
cin>>ch1>>ch2; 如果输入流由 R 1
组成,那么抽取操作符存储‘R’到ch1中,跳过空格,再存储1到ch2中,(注意char变量’1’不同于int变量1,在计算机的内存中,这两个数存储完全不同。抽取操作符以不同的方法解释相同的数据,取决于要填入数据的变量的类型)。
如果我们想从输入行输入3个字符:R.空格和1,如何做?用抽取操作符是不可能的,像空格这样的空白字符会被逃过。
istream数据类型提供了除>>操作符外的第2种读字符数据的方法。你可以使用get函数,get函数在输入流中输入紧接着的下一个字符,没有跳过任何空白字符,它的调用像这样: cin.get(somechar);
get函数与istream数据类型相联系,你必须使用点标记来调用函数,为了使用get函数,你给出一个istream变量的名字(这里是cin),然后是一个点(句号)。再是函数名和自变量表列。注意调用get使用的是调用void函数的语法,不带回返回值的函数。。
get函数的参数必须是一个变量,不是一个常量或任意表达式。 使用get函数,我们现在可以输入行中所有三个字符。 R 1
我们可以使用三条连续对get函数的调用: cin.get(ch1); cin.get(ch2); cin.get(ch3);
或我们可以采用这种方法: cin>>ch1; cin.get(ch2); cin>>ch3;
用ignore函数跳过字符
与iostream相关联的ignore函数像一个特殊的工具,ignore函数用来在输入流中跳过字符,它是一个有两个参数的函数,调用像这样: cin.ignore (200,’\\n’)
第一个自变量是一个int表达式,第二个是一个char值,这个专用函数的调用告诉计算机跳过接下来的200个字符或跳过到一个新行字符为止的字符,不管新行字符在哪里第一次出现。 这里是一些例子,使用了一个char变量ch,三个int变量i,j和k。
例(1)显示了最通常使用的ignore函数,在当前输入行中,跳过数据的其余部分,例(2)演示除‘\\n’外的一个作为第二个参数的字符的使用,我们跳过所有输入字符直到找到B为止,然后读下一个输入数字到i 中,在例3中,我们改变我们的注意力并集中到第一参数上,我们要注意的是在当前行跳过下两个输入字符。 读字符串数据
为了输入一个字符串到一个string变量中,我们有两个选择,第一是使用抽取操作符(>>),当读输入字符到string变量时,>>操作符跳过任何像空格和新行这样的前导空白符,然后连续读字符到变量中,在第一个尾随的空白字符的地方停止读入,例如,设我们有下列代码: string firstName; string lastName;
cin>>firstName>>lastName;
如果输入流初始像这样(这里口表示空格) 口口Mary口smith口口口18
那么我们的输入语句存储4个字符Mary到firstName,存储5个字符Smith到lastName,并剩下的输入流为
口口口18
记住>>操作符一遇到空白字符就停止读,这个事实,使我们引入第二种选择用getline函数来完成字符串的输入,一个对getline 函数的调用像这样: getline (cin .myString);
函数调用,不使用点标记,需要两个自变量,第一个是一个输入流变量(这里是cin),第二个是一个string变量,getline函数不跳过前导空白字符,一直继续到它遇到新行字符‘\\n’为止,注意用getline函数,新行字符被用过了(但不存储到字符变量中)。给出代码段: string inputstr ; getline(cin,inputstr) ; 并且输入行
口口Mary口Smith口口口18
调用getline的结果是,在输入行上的所有17个字符(包含空格)被存储到inputstr中,读标记器被放置在下一行输入的开始。
下面表格总结了当读字符串数据到string变量时,>>操作符和 getline函数之间的不同。
4.2 交互式输入/输出
一个交互程序式用户直接于计算机通信的程序,我们写的许多程序是交互式的程序。
为了使得数据到交互式程序中,我们开始用输入提示,打印出信息,解释用户应该输入什么值,没有这些信息,用户不知要打入什么样的数据值。这里是一个程序段,显示了提示的恰当使用。 cout << \; // Prompt cin >> partNumber;
cout << \ << endl; // Prompt cin >> quantity;
cout << \ << endl; cin >> unitPrice;
totalPrice = quantity * unitPrice;
cout << \ << \, quantity \
<< \, at $ \ << \;
cout << \; 这里是输出,用户的输入以彩色显示: Enter the part number: 4671
Enter the quantity of this part ordered: 1O
Enter the unit price for this part: 27.25
Part 4671, quantity 1O. at $ 27.25 each totals $ 272.50
4.3 非交互式输入/输出
虽然在本文中我们倾向使用交互式I/O例子。但还有许多程序使用非交互式I/O来写。
设计为非交互式I/O程序不为输入打印出提示信息,可是,回馈打印每个读入的数据值是一个好的设计方法。回馈打印允许人们读输出值来与输入值比较从而证实数据的正确性。由于非交互式程序有助于打印大量数据, 它们的输出常是具有标题栏描述的表格形式。 4.4 文件的输入和输出
文件
文件中的信息通常被存储在一个辅助存储设备中,如磁盘。我们的程序从一个文件中读数据的方法与从键盘读数的方法是一样的。并且程序将输出写到一个磁盘文件中的方法与输出写到屏幕的方法是一样的。 使用文件
如果我们希望一个程序使用文件进行输入/输出,我们必须做4件事: 1. 要求预处理器包含头文件fstream. 2. 用声明语句声明我们要用的文件流。
3. 准备为每个要进行读或写的文件使用名为open的函数。 4. 在每个输入或输出语句中,指定文件流的名字。 包含头文件fstream #include
在头文件fstream中,c++标准库定义了两个数据类型,ifsream和oftream(标准输入文件流和输出文件流),与通常c++流概念一致,ifstream数据类型描述了来自一个输入文件的字符流,而ofstream描述了送到输出文件的字符流。
已学的所有istream操作——抽取操作符(>>)、get函数、ignore函数——对于ifstream类型也都是有效的,所有的ostream操作,如插入(<<)操作符、endl、setw和setprecision控制符,也都可以应用到ofstream类型。 声明文件流
在程序中,你声明流变量的方法与你声明任何变量的方法一样——你指定数据类型,然后是变量名: int someInt ; float someFloat ; ifstream inFile ; ofstream outFile ;
(你不必声明流变量cin和cout,头文件iostream已经为你声明了)。
对于我们的Walk程序,让我们命名输入和输出文件流为inDate和outDate ,我们声明它们像这样: ifstream inDate ; //保存用英寸表示的地图距离 ofstream outdate ; //保存用英里表示的行走距离
注意ifstream类型是仅用于输入文件,ofstream类型仅用于输出文件。用这些数据类型,你不能对同一个文件进行读和写。 打开文件
我们要做的第三件事是准备为每个要读或写的文件调用“打开”文件。打开文件引起计算机的操作系统完成某项允许我们进行文件的输入/输出活动。
在我们的例子中,我们想对文件流inData进行读,对文件流outData进行写。我们打开有关文件所要使用语句
inData.open (“Walk.dat”) ;