第3课 输入与输出

本文详细介绍了C++中cin、cout以及get()、getline()等输入输出函数的使用,包括无参数、带参数和带3个参数的get()方法,以及getline()方法的工作原理和示例。通过实例展示了如何处理文件结束符EOF和字符输入控制。
摘要由CSDN通过智能技术生成

一、学习目标

  • 掌握C/C++基本输入/输出语句的使用(针对标准输入/输出设备)

二、学习内容

提示:这里可以添加要学的内容

  1. cin——输入流对象
  2. cout——输出流对象
  3. scanf()——格式输入函数
  4. printf()——格式输出函数
  5. getchar()——输入一个字符
  6. putchar()——输出一个字符

三、扩展学习内容

  1. get()——输入流对象的成员方法,如 cin.get()
  2. put()——输出流对象的成员方法,如 cout.put()
  3. gets()——从标准设备读取字符直到遇到换行符(‘\n’)为止;
  4. puts()——将buffer中的字符输出到标准设备,直到遇到空字符(‘\0’)为止
  5. getline()——读取一行

1. C++的get()方法

get()是输入流对象的成员方法,它有3种形式:无参数的;有一个参数的;有3个参数的。
无参数的调用形式为
cin.get()
cin.get()用来从指定的输入流中提取一个字符(包括空白字符),其返回值就是读入的字符。 若遇到输入流中的文件结束符,则返回文件结束标志EOF(End Of File),一般以-1代表EOF,用-1而不用0或正值,是考虑到不与字符的ASCII代码混淆,但不同的C ++系统所用的EOF值有可能不同。

1. 无参数的get()

下面的代码示例使用get()方法读取字符

#include<iostream>
using namespace std;

int main() {
	char ch;
	cout << "enter a sentence:" << endl;
	while ((ch = cin.get()) != EOF)
		cout.put(ch);
		
	cout << "end" << endl;

	return 0;
}

运行代码,进行如图1所示的测试。
对(c = cin.get()) != EOF的测试
上面的代码示例演示的cin.get()和cout.put()与C语言中的getchar()函数和putchar()函数相比较。

#include <stdio.h>
int main() {
 int ch = 0;
 while ((ch = getchar()) != EOF)
       putchar(ch);
    return 0;
}

EOF是 “End of File” 的缩写,它表示文件的结束。在C和C++中,EOF是一个特殊的整数常量,用于表示文件末尾。使用EOF可以帮助我们判断何时停止读取文件,以避免无限循环或读取无效的字符。

在大多数操作系统中,按下CTRL+Z组合键会发送一个特殊的控制字符,称为"EOF"字符,它告诉正在运行的程序输入流已经结束。当你在终端或命令行窗口中输入CTRL+Z时,操作系统会将EOF字符发送给正在运行的程序。对于大多数交互式程序和循环,程序会检测到EOF字符,将其解释为输入结束的信号,并相应地终止循环或退出程序。

因此,按下CTRL+Z可以被视为一种快捷方式,用于退出循环或程序,而不必手动输入特定的退出条件。请注意,这种行为可能会因操作系统和编程语言而有所不同,因此并不能保证在所有情况下都能成功退出循环。

2. 带一个参数的get()

有一个参数的cin.get()的调用形式为
cin.get(ch)
其作用是从输入流中读取一个字符,赋给字符变量ch。如果读取成功则函数返回true,如失败(遇文件结束符) 则函数返回false(文件结束符 为 ctrl + z)。上面的例子可以改写如下:

#include <iostream>
using namespace std;
int main() {
	char ch;
	cout << "enter a sentence:" << endl;
	while (cin.get(ch)) { 
	    //读取一个字符赋给字符变量ch, 如果读取成功,cin.get(ch)为真
	    //读取字符为文件结束符(Ctrl + z)时,cin.get(ch)为假
		cout.put(ch);
	}
	cout << "end" << endl;
	return 0;
}

运行程序,类似的输入与输出如下:
测试cin.get(ch)
现在,我们知道可以使用cin.get(ch)和ch = cin.get()两种形式来输入一个字符。
上面不带参数和带一个参数的cin.get()方法都是完成单个字符的输入。此时,get()方法读取下一个输入字符,即使该字符是空格,制表符或换行符。还是通过键盘仿真的文件尾,对于DOS和Windows命令提示符模式,位按下Ctrl+Z;对于UNIX,是在行首按下Ctrl+D。
但是,cin.get(ch)和ch = cin.get()还是有区别的。如下表所示。

特征cin.get(ch)ch = cin.get()
传输输入字符的方式赋给参数ch将函数返回值赋给ch
字符输入时方法的返回值指向istream对象的引用字符编码(int值 )
达到文件末尾时方法的返回值转换为falseEOF

其实get()方法也可以接收多个字符,此时,其函数原型如下:
istream& get(char*, int, char);
istream& get(char*, int);
第一个参数用于放置输入字符串的内存单元的地址。第二个参数通常指定为要读取的最大字符数+1(额外的一个字符用于存储结尾的空字符 ‘\0’,以便将输入存储为一个字符串)。第三个参数(如果提供了的话)指定用作分节符的字符,如果没有提供第三个参数则将换行符作为分界符。
注意: get()方法在读取字符时会将换行符(分界符号)留在输入流中,getline()方法则会丢弃换行符(分界符号)。
运行下面的代码

#include<iostream>
using namespace std;

int main() {
	char ch1[20], ch2[20];
	cin.get(ch1, 20);
	cout << ch1 << endl;
	cin.get(ch2, 20);
	cout << ch2 << endl;''
	return 0;
}

测试效果如下
使用cin.get()输入多个字符
留意输出的空行,应该不难得知——这里第二个cin,我们还没输入,系统就自动把上一次遗留的回车符读取,然后打印(第二次啥也没读取到),输出的就是一个空白行。针对这种情况,可以单纯使用cin.get()来读取一个字符,这里的cin.get()属于一种特殊变体,它会读取输入流中的下一个字符。

#include<iostream>
using namespace std;

int main() {
	char ch1[20], ch2[20];
	cin.get(ch1, 20);
	cout << ch1 << endl;
	cin.get();	// 读取一个字符,即'\n'
	cin.get(ch2, 20);
	cout << ch2 << endl;
	return 0;
}

这样第二个cin,即cin.get(ch2, 20);就可以正常的读取下一行中的字符了。
get()方法与输入流测试
上面的代码还可以写成如下形式

#include<iostream>
using namespace std;

int main() {
	char ch1[20], ch2[20];
	cin.get(ch1, 20).get();
	cout << ch1 << endl;
	//cin.get();	// 读取一个字符,即'\n'
	cin.get(ch2, 20);
	cout << ch2 << endl;
	return 0;
}

之所以能够直接写成cin.get(ch,20).get();这样的形式,是因为cin.get(ch, 20);使用完后会返回一个cin对象,于是就变为cin.get()了。
get没有读取完的字符还会保留在输入缓冲区中,不会删除。所以下一次可以继续读取。
下面再来看看带3个参数的get()方法输入多个字符的情况。

3. 带3个参数的get()

有3个参数的get()的方法原型为
istream& get(char *, int, char);
调用形式为
cin.get(字符数组, 字符个数n, 终止字符)

cin.get(字符指针, 字符个数n, 终止字符)

其作用是从输入流中读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组),如果在读取n-1个字符之前遇到指定的终止字符,则提前结束读取。如果读取成功则函数返回true(真),如失败(遇文件结束符) 则函数返回false(假)。再将前面的示例改写如下:

#include<iostream>
using namespace std;

int main() {
	char ch[40];
	cout << "enter a sentence:" << endl;
	cin.get(ch, 20, '\n');	//指定换行符为终止字符
	cout << ch << endl;
	//system("pause");

	return 0;
}

运行程序,输入与输出如下:
测试cin.get(ch, 20, '\n')
输出为"This is a demo of c",为什么只有19个字符呢?因为存放的是一个字符串,因此在19个字符之后要加入一个字符串结束标志,实际上存放到数组中的是20个字符。
get()方法中第3个参数可以省写,此时默认为’\n’。下面两行等价:

cin.get(ch, 10, '\n');
cin.get(ch, 10);

终止字符也可以用其他字符。如

cin.get(ch,10,'0');  //在遇到字符'0'时停止读取操作。

2. C++的getline()方法

getline()方法的作用是从输入流中读取一行字符,其用法与带3个参数的get()方法类似,只是getlien则会丢弃分界符号(默认换行符)。其方法原型为
istream& getline(char *, int , char);
其调用形式为
cin.getline(字符数组(或字符指针), 字符个数n, 终止标志字符)
getline属于cin类的成员函数,他可以一直读取输入知道遇到换行符,同时它会丢弃换行符换成’\0’。
下面是一个cin.getline()的用法示例。

#include<iostream>
using namespace std;

int main() {
	char ch1[32], ch2[32];
	cout << "enter a sentence:" << endl;
	cin.getline(ch1, 32, '/');	//读20个字符或遇'/'结束
	cout << ch1 << endl;
	cin.getline(ch2, 32);	//读20个字符或遇'/n'结束
	cout << ch2 << endl;
	cout << ch2 << endl;
	for(int i=0; ch2[i]!='\0'; i++)
		cout << ch2[i];
	return 0;
}

运行程序,输入与输出如下:
测试cin.getline()
代码首先使用语句cin.getline(ch1, 32, ‘/’)从输入流读取32个字符 (或遇 ‘/’ 结束),即读取"When you are old"并输出;接下来使用语句cin.getline(ch2, 32);从输入流中接续读取32个字符(或遇 ‘\n’ 结束),显然这里是遇到 ‘\n’ 结束输入,即读取"and grey and full of sleep"并输出。
注意
(1)在输入流中有一个字符指针,指向当前应访问的字符。在开始时,指针指向第一个字符,在读入一个字符后,指针会自动向后面移动到下一个字符。
(2)cin.getline()方法遇终止标志字符"/“时停止读取,终止标志字符”/"并不会放到字符数组中。
(3)用getline()方法从输入流读字符时,遇到终止标志字符时结束,指针移到该终止标志字符之后,下一个getline()方法将从该终止标志的下一个字符开始接着读入,如上面程序运行结果所示那样。如果用cin.get()函数从输入流读字符时,遇终止标志字符时停止读取,指针不向后移动,仍然停留在原位置。下一次读取时仍从该终止标志字符开始。这是getline函数和get函数不同之处。


四、练习

  1. 输入两个整数,按每个整数占7个字符宽度并且右对齐输出。
  2. 输入一个单精度浮点数,按保留4位小数输出。
  3. 输入一个双精度浮点数,按保留10位小数输出。
  4. 输入3个字符数据,按每个字符占3位且左对齐输出。
  5. 输出由星号 '*'组成的菱形图案。
  6. 输入一个字符,输出有该字符组成的金字塔图案。

其中,1、2、3题合并到一个程序中,代码如下:

#include<iostream>
#include<iomanip>
using namespace std;

int main() {
	int a, b;
	cout <<"输入两个整数:" << endl;
	cin >> a >> b;
	cout << setw(7) << a << setw(7) << b << endl;
	float f;
	cout <<"输入一个单精度浮点数:" << endl;
	cin >> f;
	cout << fixed << setprecision(4) << f << endl;
	double d;
	cout <<"输入一个双精度浮点数:" << endl;
	cin >> d;
	cout << fixed << setprecision(10) << d << endl;
	
	return 0;
}

第4题的参考代码如下:

#include<iostream>
using namespace std;

int main() {
	char ch;
	cout << "enter 3 characters such as abc or xyz etc.:" << endl;
	while ((ch = cin.get()) != '\n') {
		cout.put(ch);
		cout << "  ";	//	2个空格
	}
	return 0;
}

第6题的参考代码如下(按学习进度,给出的代码涉及到了两重循环结构,代码所涉及内容显然超前了):

#include<iostream>
using namespace std;

int main() {
	char ch;
	int lines;
	cin >> ch >> lines;
	for(int i=1; i<=lines; i++) {
		for(int k=lines-i; k>0; k--)
			cout << ' ';
		for(int j=1; j<=2*i-1; j++) {
			cout << ch;
		}
		cout << endl;
	}
	return 0;
}

运行该程序,输入一行:* 20 回车,输出如下图所示。
输出指定字符和指定行数的金字塔图案

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值