【问题标题】:cin is not accepting input with space in them in C++?cin 在 C++ 中不接受带有空格的输入吗?
【发布时间】:2020-09-10 01:59:57
【问题描述】:
#include <iostream>
using namespace std;

int main(){
    string doi, name, address, phone;
    cout<<"Please provide these credentials:\n";
    cout<<"1.Date of issue\n";
    cin>>doi;
    cout<<"2.Name\n";
    cin>>name;
    cout<<"3.Address\n";
    cin>>address;
    cout<<"4.Phone Number\n\n";
    cin>>phone;
    return 0;
}

当我输入带有空格的名称时,例如(“John Doe”),而不是存储此值是名称,而是按空格拆分值并将“John”存储在名称中,“Doe”存储在地址中。

【问题讨论】:

  • 嗯?当然不是……std::cin 在遇到第一个空格时停止读取输入……
  • 离题:避免将doi命名为date of issue;相反,根据 camelCase 命名约定,您可以使用:dateOfIssue。
  • @DavidC.Rankin -- 这不是std::cin 这才是罪魁祸首。停止读取空白的是流提取器 (operator&gt;&gt;)。其他读者(`std::getline() 是最常见的)没有。

标签: c++ iostream cin


【解决方案1】:

如果你想读取的字符串中有空格,你可以像这样使用std::getline

std::getline(std::cin, name);

而不是行:

std::cin >> name;

请注意,getline 将读取所有字符,直到换行符为止。

另外,请避免using namespace std;

【讨论】:

  • name 中存储的值对应于我输入的最后一个单词。例如,如果我的输入 =“John Doe”,那么只有 Doe 存储在我的 name 变量中。
  • 输入中的每个字段是否位于不同的行中?
  • 字符串doi,姓名,地址,电话; cout>doi; cout>名称; std::getline(std::cin, 名称); cout>地址; cout>电话; cout
  • 编辑了答案。将cin 替换为getline
【解决方案2】:

当您需要输入带空格的字符串时,您应该使用 getline() 代替 cin。 在您的情况下,语法将是

string name;
getline(cin,name);

有关 getline 的更多信息https://www.geeksforgeeks.org/getline-string-c/

【讨论】:

    【解决方案3】:

    cmets 和答案中有很多混乱的术语。 std::cin 是一个对象;它不会做任何事情自己。

    从输入流中读取的

    函数属于以下两类之一:它们执行格式化输入未格式化输入。格式化输入函数将从输入流(此处为std::cin)获得的 文本 转换为他们尝试读取的数据类型:

    int i;
    std::cin >> i; // operator>> reads text and translates it into an integer value
    

    格式化输入函数从跳过空格开始,然后读取字符并翻译它们;当函数遇到对他们正在读取的类型无效的字符时,或者当他们看到空格时,他们会停止。所以在上面的例子中,如果你输入“32”,流提取器会跳过前导空格,读取32,看到下面的空格,然后停止读取。存储在i 中的值将是 32。

    std::string data;
    std::cin >> data;
    

    在这里,如果您输入“Hello, world”,流提取器 (operator&gt;&gt;) 将读取到空格,并将 "Hello," 存储在 data 中。

    如果您想读取空白和非空白,您需要一个未格式化的输入函数:

    std::string data;
    std::getline(std::cin, data);
    

    这里,对getline 的调用从std::cin 读取文本,直到第一个换行符或输入流的末尾。因此,如果您为此代码键入“32”,data 将保存文本 " 32 "。如果您输入“Hello, world”,data 将保留文本 "Hello, world"

    请注意,如果您将格式化的输入函数与未格式化的输入函数混合使用,则必须小心剩余的空格:

    int i;
    std::string data;
    std::cin >> i;
    std::getline(std::cin, data);
    

    如果您在一行中输入“32 Hello, world”,i 会得到 32,data 会得到“Hello, world”。

    另一方面,如果您键入两行输入,第一行输入“32”,第二行输入“Hello, world”,您将在i 中得到 32,但data 将为空。这是因为流提取器读取了32,然后看到一个换行符,然后停止,将换行符留在输入缓冲区中。 std::getline 然后读取换行符,它也停止了。但它读取了整行:它吞下了换行符。

    因此,当您的代码从格式化输入切换到未格式化输入时,您必须处理输入缓冲区中剩余的空白字符。如果您想阅读它们,很好;但如果不这样做,则需要删除它们:

    int i;
    std::string data;
    std::cin >> i;
    std::getline(std::cin, data); // read the rest of the line
    std::getline(std::cin, data); // read the next line of text
    

    更好的方法是使用std::cin.ignore(42, '\n'); 之类的东西进行清理。 std::ignore 是无格式输入函数;在这个调用中,它最多读取 42 个字符,寻找换行符。它在读取 42 个字符、看到换行符或到达输入结尾时停止读取。这比使用std::getline(std::cin, data) 更好,因为它不会将文本存储到data,如果行的其余部分有很多文本,这可能需要大量调整大小。该调用更常用的形式是将std::numeric_limits&lt;int&gt;::max() 作为大小参数传递;这是一种特殊情况,它对要读取的字符数没有限制。所以std::cin.ignore(std::numeric_limits&lt;int&gt;::max(), '\n'); 会读取字符,直到找到换行符或到达输入的末尾。

    int i;
    std::string data;
    std::cin >> i;
    std::cin.ignore(std::numeric_limits<int>::max(), '\n'); // flush the rest of the line
    std::getline(std::cin, data); // read the next line of text
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-26
      相关资源
      最近更新 更多