C++中字符串分为C风格字符串(就是char数组)和string字符串类型(需要包含string头文件),针对这两种类型,C++提供了很多方法可供输入:cin, cin.get(), cin.getline(), getline()

cin

这是最常用的方法,cin可以接收一个字符串,无论是string对象还是char []数组都可用cin输入。用cin输入时,会跳过开头的空白字符(“空格”, “TAB”, “回车”),并且结尾遇到空白字符就会认为输入结束。

下面的代码分别创建了字符数组a和string对象b,接收输入并打印出来。

#include <iostream>
#include <string>

using namespace std;

int main()
{
    char a[10];
    string b;
    cout << "Enter char[]: ";
    cin >> a;
    cout << "Enter string: ";
    cin >> b;
    cout << endl
         << "char[]:" << a << " string: " << b << endl;
    return 0;
}

不输入空白字符的情况下,一切正常,分两次输入的abc和def,都正常打印出来:
QQ_1720575276634.png

输入空白字符的情况下,此时只进行了一次输入”abc<空格>def“。cin遇到空格认为输入结束,于是将abc保存在字符数组a中,剩下的”<空格>def“仍然保存在缓冲区中。在第二个cin执行时,由于缓冲区中仍有字符,所以没有让用户进行输入。第二个cin跳过了开头的空白字符,遇到认为输入结束,所以读取了”def“并保存在string对象b中:
QQ_1720575911285.png

cin.get()

cin.get()主要用于读取单个字符或字符数组,可以接收空白字符。它有很多重载的版本,无论哪个版本都不能输入string对象。

无参数

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

#include <iostream>

using namespace std;

int main()
{
    char c;
    while ((c = cin.get()) != EOF)
        cout << c;
    cout << "ctrl+z ,Done" << endl;
    return 0;
}

执行效果如下:
QQ_1720576832527.png
注意:cin.get()不会消耗缓冲区中的回车。其另一种常见用法为通过cin.get()(不赋给任何变量)来消耗缓冲区中的回车。

一参数

其调用形式为cin.get(ch),其作用是从输入流中读取一个字符,赋给字符变量ch。如果读取成功则函数返回true(真),如失败(遇文件结束符) 则函数返回false(假)。

#include <iostream>

using namespace std;

int main()
{
    char c;
    while (cin.get(c))
        cout << c;
    cout << "ctrl+z ,Done" << endl;
    return 0;
}

执行效果如下:
QQ_1720577136474.png

二参数

其调用形式为cin.get(字符数组名, 接收字符数n)。主要用来接收一行字符串(可以接收空格),这个最大的用途是可以定量的接收字符的个数。但是要注意,如果定义的数组的个数是n,则实际上只能接收n-1个字符,还要加上’\0’。

#include <iostream>

using namespace std;

int main()
{
    char a[5], b[5];
    cin.get(a, 5);
    cin.get(); // 用于消耗缓冲区中的回车
    cout << a << endl;
    cin.get(b, 5);
    cout << b << endl;
    cout << "done" << endl;
    return 0;
}

执行效果如下:
QQ_1720578115406.png

前面说过,cin.get()不会消耗缓冲区中的回车,所以在上述代码中,用了一次无参数版本的cin.get()来消耗回车,从而保证输入的正确。
如果没有第9行的代码,第二次的输入遇到缓冲区中的回车就结束了,从而认为用户输入了空字符串,执行效果如下。
QQ_1720578249636.png

三参数

其调用形式为cin.get(字符数组名, 接收字符数n, 终止字符)。其作用是从输入流中读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组),如果在读取n-1个字符之前遇到指定的终止字符,则提前结束读取。如果读取成功则函数返回true(真),如失败(遇文件结束符) 则函数返回false(假)。

#include <iostream>

using namespace std;

int main()
{
    char a[5];
    cin.get(a, 5, '#');
    cout << a << endl;
    return 0;
}

执行效果如下:
QQ_1720578716385.png

第一次输入了很多字符,只读取了4个;第二次由于遇到了’#',提前结束输入。

cin.getline()

cin.getline()cin.get()的作用差不多,都能接收空白字符的输入,都不能输入string对象。其用法也大致相同,但是cin.getline()只有二参数和三参数版本,没有无参数和一参数版本。

cin.getline()cin.get()的一个重要区别是:cin.getline()会消耗缓冲区中的回车,而cin.get()不会。

二参数

其调用形式为cin.getline(字符数组名, 接收字符数n)

#include <iostream>

using namespace std;

int main()
{
    char a[5], b[5];
    cin.getline(a, 5);
    cout << a << endl;
    cin.getline(b, 5);
    cout << b << endl;
    cout << "done" << endl;
    return 0;
}

这段代码和cin.get()二参数版本中的代码类似,除了将cin.get()换成cin.getline(),还去掉了用于消耗回车的cin.get()。执行效果如下:
QQ_1720579933420.png
由于cin.getline()会消耗回车,所以不需要cin.get()

三参数

其调用形式为cin.getline(字符数组名, 接收字符数n, 终止字符)。代码类似cin.get()三参数版本,就不放了。

getline()

getline()可以接受一个字符串输入,包括空格,但需要引入头文件string。因为cin.getline()属于istream流,而getline()属于string流。getline()函数不能输入char数组,只能输入string对象。

getline()返回输入流对象的引用。通过检查这个返回值,可以判断读取操作是否成功。

二参数

定义:std::getline(std::istream& is, std::string& str);

  • is:输入流对象,通常是std::cin
  • str:存储读取内容的字符串对象。
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string str;
    while (getline(cin, str))
        cout << "You entered: " << str << endl;
    cout << "done" << endl;
    return 0;
}

执行效果如下:
QQ_1720581161467.png

三参数

定义:std::getline(std::istream& is, std::string& str, char delim);

  • is:输入流对象,通常是std::cin
  • str:存储读取内容的字符串对象。
  • delim(可选):指定的分隔符,默认是换行符 \n。
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string str;
    getline(cin, str, '#');
    cout << str << endl;
    return 0;
}

执行效果如下:
QQ_1720581407256.png

总结

下表总结了上述方法的区别

输入char数组输入string字符串输入空白字符其他
cin×
cin.get()×不消耗回车
cin.getline()×消耗回车
getline()×
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐