我的 getline 函数 [duplicate] 有问题

I am having an issue with the getline function [duplicate]

提问人:jack is carbon 提问时间:1/30/2023 最后编辑:jack is carbon 更新时间:1/30/2023 访问量:97

问:

#include <iostream>
using namespace std;
int main(){
    //set variables
    string name1;string name2;string name3;string n1;string n2;string n3;
    int age1; int age2; int age3;

    //get names and ages
    cout << "Who Is The First Student?"<< endl;
    getline(cin, name1); //name 1
    cout << "What is " << name1<< "'s Age?"<< endl;
    cin >> age1; // age 1
    cout << "Who Is The Second Student?"<< endl;
    getline(cin, name2); //name 2
    cout << "What is " << name2<< "'s Age?"<< endl;
    cin >> age2; //age 2
    cout << "Who Is The Third Student?"<< endl;
    getline(cin, name3); // name 3
    cout << "What is " << name3<< "'s Age?"<< endl;
    cin >> age3; //age 3

    // gets modified names
    n1 = name1.substr(2, name1.size() -3);
    n2 = name2.substr(2, name2.size() -3);
    n3 = name3.substr(2, name3.size()-3);
    // Output formatting
    cout << "Name             Age             Modified"<<endl;
    cout << name1<< "             "<<age1<<"             "<<n1<<endl;
    cout << name2<< "             "<<age2<<"             "<<n2<<endl;
    cout << name3<< "             "<<age3<<"             "<<n3<<endl;
    return 0;
}

输出询问第一个问题,即第一个学生的姓名,但输出如下:

谁是第一个学生? 无名氏- 约翰的年龄是多少? 19- 谁是第二个学生? 什么是年龄?

它跳过了第二个学生姓名的用户输入并立即询问年龄,但我不知道为什么会发生这种情况,我的代码有问题还是格式不正确?我相信我正确地使用了 getline 函数,但我可能不正确,并且没有意识到它被更重要的函数跳过了。

c++ 字符串 运行时错误 iostream 子str

评论

0赞 pm100 1/30/2023
这将是由于其中之一导致不正确的起始偏移量(<0 或>长度)或长度n1 = name1.substr(2, name1.size()-3);
0赞 JohnFilleau 1/30/2023
cinon 将输入到第一个空格或换行符。因此将设置为 ,您的程序将尝试读入为 。用于获取线条。但是,你不能轻易混合。我建议不要尝试在你的水平上尝试混合它们。我可以推荐的最佳修复操作是使用不带空格的名称。stringname1JohnDoeage1std::getlinestd::cin >>std::getline
0赞 pm100 1/30/2023
根据这里 en.cppreference.com/w/cpp/string/basic_string/substr
0赞 JohnFilleau 1/30/2023
顺便说一句,输入将设置为错误状态,这将阻止所有未来的输入,直到您清除错误状态。这里最简单的解决方法是使用不带空格的名称。Doeage1std::cin
0赞 Jesper Juhl 1/30/2023
什么是调试器,它如何帮助我诊断问题?

答:

0赞 Jeremy Friesner 1/30/2023 #1

std::string::substr() 手册页对您看到的异常是这样说明的:

Parameters
   pos   -  position of the first character to include
   count -  length of the substring

Exceptions
   [throws] std::out_of_range if pos > size()
0赞 Vlad from Moscow 1/30/2023 #2

该程序的主要问题是只读取一个单词。operator >>

例如,在这些陈述中

cout << "Who Is The First Student?"<< endl;
cin >> name1; //name 1

您输入了一个包含两个单词的字符串。但 只读取变量中的第一个单词。"John Doe"operator >>"Jphn"name1

所以在下一个输入语句中

cout << "What is " << name1<< "'s Age?"<< endl;
cin >> age1; // age 1

发生错误,因为输入缓冲区包含单词 ."Doe"

因此,变量 、 和 不包含您期望的内容。而这些陈述name1name2name3

n1 = name1.substr(2, name1.size()-3);
n2 = name2.substr(2, name2.size()-3);
n3 = name3.substr(2, name3.size()-3);

产生运行时错误。

而不是你应该使用标准函数。operator >>std::getline

这是一个基于程序代码的演示程序,显示了错误的原因

#include <iostream>
#include <string>

int main()
{
    std::string name1, name2;
    int age1;

    //get names and ages
    std::cout << "Input 3 Names Below:" << std::endl;
    std::cout << "Who Is The First Student?" << std::endl;
    std::cin >> name1; //name 1
    std::cout << "What is " << name1 << "'s Age?" << std::endl;
    std::cin >> age1; // age 1
    std::cout << "Who Is The Second Student?" << std::endl;
    std::cin >> name2; //name 2

    std::cout << "name1 = " << name1 << '\n';
    std::cout << "name2 = " << name2 << '\n';
}

程序输出为

Input 3 Names Below:
Who Is The First Student?
John Doe
What is John's Age?
Who Is The Second Student?
name1 = John
name2 =

正如你所看到的,由于读取变量 age1 中的数据(缓冲区包含字符串)中的数据时出错,对象是空的。因此,如果您将在此语句中使用它"Doe"name2

n2 = name2.substr(2, name2.size()-3);

然后将发生运行时错误。

这是另一个演示程序,展示了如何在程序中使用标准函数。std::getline

#include <iostream>
#include <string>
#include <limits>

int main()
{
    std::string name1, name2, name3;
    int age1, age2, age3;

    //get names and ages
    std::cout << "Input 3 Names Below:" << std::endl;

    std::cout << "Who Is The First Student?" << std::endl;
    std::getline( std::cin, name1 ); //name 1
    std::cout << "What is " << name1 << "'s Age?" << std::endl;
    std::cin >> age1; // age 1
    std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

    std::cout << "Who Is The Second Student?" << std::endl;
    std::getline( std::cin, name2 ); //name 2
    std::cout << "What is " << name2 << "'s Age?" << std::endl;
    std::cin >> age2; //age 2
    std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

    std::cout << "Who Is The Third Student?" << std::endl;
    std::getline( std::cin, name3 ); // name 3
    std::cout << "What is " << name3 << "'s Age?" << std::endl;
    std::cin >> age3;

    std::cout << "name1 = " << name1 << '\n';
    std::cout << "name2 = " << name2 << '\n';
    std::cout << "name3 = " << name3 << '\n';
}

程序输出为

Input 3 Names Below:
Who Is The First Student?
John Dow
What is John Dow's Age?
20
Who Is The Second Student?
Mary Poppins
What is Mary Poppins's Age?
21
Who Is The Third Student?
Bob Fisher
What is Bob Fisher's Age?
25
name1 = John Dow
name2 = Mary Poppins
name3 = Bob Fisher

评论

0赞 pm100 1/30/2023
这与抛出的异常无关,这是由于子 CA 上的范围之外
1赞 Vlad from Moscow 1/30/2023
@pm100 你错了。
0赞 pm100 1/30/2023
OK - 使用该特定输入,但如果用户输入“ed”作为名字,即使使用 getline,它仍然会失败。OP 必须检查长度
0赞 jack is carbon 1/30/2023
我使用了getline,它有点工作。第一个输出有效,我可以输入全名而不会出错,但是在输入第一个年龄后,它会同时询问第二个人的姓名和年龄,我不确定为什么会发生这种情况
0赞 Vlad from Moscow 1/30/2023
@jackiscarbon 使用运算符 >> 输入期限后,输入缓冲区包含换行符“\n”,getline 的下一次调用将读取一个空字符串。您需要删除字符行 std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );