使用getline函数获取分段错误?

时间:2019-01-10 12:29:13

标签: c++ string

我的代码出现分段错误。我已经使用调试器并将错误定位到第14行。它没有将输入存储在第13行,这就是为什么第14行抛出界外错误的原因。谁能告诉我为什么13号线不起作用?

using namespace std;
#include<iostream>
#include<cstring>
#include<deque>
int main()
{
    int n;
    cout<<"How many messages to read: ";
    cin>>n;
    string s;
    for(int i=1;i<=n;i++)
    {
        getline(cin,s);       //<-----LINE13
        auto it=s.begin();    //<-----LINE14
        deque<char> kingdom;
        while(s[0]!=',')
        {
            kingdom.push_back(s[0]);
            s.erase(it);
        }
        s.erase(it);
        s.erase(it);
        s.erase(it);
        while(kingdom.size()!=0)
        {
            it=s.begin();
            for(int j=0;j<s.length();j++,it++)
            {
                if(kingdom.at(0)==s.at(j))
                {
                    kingdom.pop_front();
                    s.erase(it);
                    break;
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:4)

您的问题的可能根本原因是:

cin>>n;

在这里,您从用户那里读取了一个整数值。但是用户使用 Enter 键结束输入,该键也作为换行符'\n'添加到输入缓冲区中。

当您呼叫getline时,除了换行符,它什么也看不到,认为它是空行,因此有效清除了字符串s,使其为空。

一个空字符串的begin迭代器将等于其end迭代器。 end迭代器除与其他迭代器进行比较外,不能用于其他任何用途。

这还意味着任何索引(甚至索引0)都将超出范围。

要解决此问题,您需要在读取n之后ignore行的其余部分:

cin >> n;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // Skip just past the end of the line

答案 1 :(得分:1)

s.erase(it) invalidates迭代器it。该运算符的后续用法是undefined behavior

您应该写it = s.erase(it);