Background Info
- EOF是C语言中为了区分有效数据和输入结束符的。 EOF的输入由系统锁定,windows下是
ctrl+z
,linux/unix下是ctrl+d
. - 在 C++ 中,输入输出流被定义为类。C++ 的I/O库中的类称为流类(stream class)。 用流类定义的对象称为流对象。
输入和输出是数据传送的过程,数据如流水一样从一处流向另一处。C++ 形象地将此过程称为流(Stream)。C++的输入输出流是指由若干字节组成的宇节序列,这些宇节中的数据按顺序从一个对象传送到另一对象。流表示了信息从源到目的端的流动。在输入操作时,字节流从输入设备(如键盘、磁盘)流向内存,在输出操作时,字节流从内存流向输出设备(如屏幕、打印机、磁盘等)。流中的内容可以是ASCII字符、二进制形式的数据、图形图像、数字音频视频或其他形式的信息。
实际上,在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据。当用cout和插入运算符“<<”向显示器输出数据时,先将这些数据送到程序中的输出缓冲区保存,直到缓冲区满了或遇到endl,就将缓冲区中的全部数据送到显示器显示出来。在输入时,从键盘输入的数据先放在键盘的缓冲区中,当按回车键时,键盘缓冲区中的数据输入到程序中的输入缓冲区,形成cin流,然后用提取运算符“ >>”从输入缓冲区中提取数据送给程序中的有关变量。总之,流是与内存缓冲区相对应的,或者说,缓冲区中的数据就是流。
从键盘读入
1. cin
- cin 继承了 istream 类,是 istream 的一个对象。
- cin无法读入空格和换行。
来看一段代码:
#include<iostream>
using namespace std;
char a[10], b;
cin >> b;
cout << b << endl;
cin.getline(a, 10);
cout << a << endl;
运行程序,输入a,程序运行的结果是:
/media/sf_code> ./a.out
a
a
// 此处为一个空格
/media/sf_code>
这里涉及到的是:cin在读入的时候,输入内容暂时被保存在缓存中,遇到回车时内容被传递给输入流 cin。但是换行符仍然滞留在输入流了,如果在 cin 后面有getline语句,这个换行符就被这个 getline 读取了,于是得到 getline 的结果为空。
可以用cin.ignore()
来清空缓存区。
cin.getline()不会把’\0’, ‘ ‘, ‘\n’等默认的分隔符写入到字符数组,因此如果在std::cin>>w后面紧接着的cin.getline语句(可以尝试把ignore()语句注释掉),会变为空读入,再后面的cin.getline()就正常读入每一行内容,并且把读入的分隔符舍弃。
2. getline
在C++中本质上有两种getline函数:
第一种:在头文件中,是iostream类的成员函数。
第二种:在头文件中,是普通函数。
第二种其实是在string类定义中对getline进行了重载。
cin.getline()
- istream& getline (char* s, streamsize n );
- istream& getline (char* s, streamsize n, char delim );
getline()
- istream& getline (istream& is, string& str, char delim);
- istream& getline (istream&& is, string& str, char delim);
- istream& getline (istream& is, string& str);
- istream& getline (istream&& is, string& str);
3. cin.get
- int get();
- istream& get (char& c);
- istream& get (char* s, streamsize n);
- istream& get (char* s, streamsize n, char delim);
- istream& get (streambuf& sb);
- istream& get (streambuf& sb, char delim);
cin.get() 遇到delimiting character 时候是不读取的,将其留在流中;而 getline() 读取限定符但不显示。
假定输入一串字符,以Enter结束输入。cin.get遇到 \n
后便返回,此时\n
还留在缓冲区中,所以下次读出来的将是\n
,而getline遇到\n
时会将其从缓存区中移除之后在返回。所以很多时候用getline方便些。
利用 while 连续读入
- while (bool) 语句的判定条件是一个bool类型,而 getline 返回地类型是 istream. 这里实际上还隐式的调用了转换函数,将 istream 转换成 bool.
operator void *() const { if(state&(badbit|failbit) ) return 0; return (void *)this; }
operator bool() const { if(state&(badbit|failbit) ) return 0; return (void *)this; }
string s;
while(getline(cin,s)) {
cout << s << endl;
}
从文件读入
从文件读入和从键盘读入类似,只是需要先将文件以文件流的形式打开。
// 输入文件流
#include<iostream>
#include<fstream>
#include <string>
using namespace std;
int main() {
char line[50];
ifstream ifile("./text.txt");
while (ifile.getline(line, sizeof(line))) {
cout << line << endl;
}
ifile.close();
return 0;
}
// 输出文件流
#include<iostream>
#include<fstream>
#include <string>
using namespace std;
int main() {
ofstream ofile("./text2.txt");
ofile << "hello world!" << endl;
ofile.close();
return 0;
}
References:
getline函数介绍:
https://www.cnblogs.com/xiaofeiIDO/p/8574042.html
getline实际使用中常见问题分析:
https://blog.csdn.net/iamiman/article/details/53468250
https://blog.csdn.net/JiuHuangShan/article/details/53150766
文件流:
https://www.cnblogs.com/zhengfa-af/p/8157199.html
来源:CSDN
作者:doge C
链接:https://blog.csdn.net/m0_37891226/article/details/103951929