删除行中字符前的所有空格

时间:2014-01-24 14:51:10

标签: c++

我有这个特殊的要求,我需要删除特定字符(管道'|')之前的所有空格字符。 我已经为它编写了一个测试代码,它实际上是打印正确的输出,但另外给了我一个核心文件:(

我的代码如下:

int main()
{

    string line="1  2  |3 4| hbvhwf     wjff wenf|hjbcwbfw     ejwef   efwk    dfkwe|jsv                       |";
    cout <<line<<endl;
    string::iterator ite =(line.begin());

    int counter=0;
    int index=0;
    int start=0;
    while(ite != (line.end()))
    {
        if(*ite == '|' && counter > 0)
        {
            line.erase(start,counter);
            counter=0;
            cout<<line<<endl;
        }
        if(ite!=line.end())
        {
            if(isalnum(*ite))
            {
                counter=0;
            }
            if(*ite==' ')
            {
                if(!counter)
                {
                    start=index;
                }
                counter++;
            }
            ite++;
            index++;        
        }
    }

    cout<<line<<endl;
}

我正在努力寻找核心转储的根本原因。 有人可以帮忙吗? 预期产出是:

1  2|3 4| hbvhwf     wjff wenf|hjbcwbfw     ejwef   efwk    dfkwe|jsv|

3 个答案:

答案 0 :(得分:1)

在字符串上调用erase()会使字符串中的所有迭代器无效,包括ite

具体来说,当line.erase(start,counter);执行时,ite无效 - 不再保证引用字符串中的有效位置。如果它不等于line.end(),则可以在条件isalnum(*ite)中取消引用它。因为ite在该点无效,所以它可以引用已经释放的内存(例如,如果字符串在被擦除后被重新分配)。因此,这一行会导致段错误。

这是一个更简单的代码版本,没有问题。

std::string line = ...;
unsigned space_run = 0;

for (unsigned i = 0; i < line.size(); ++i) {
    if (line[i] == ' ') {
        ++space_run;
    } else if (line[i] == '|') {
        line.erase(i - space_run, space_run);
        i -= space_run;
        space_run = 0;
    } else {
        space_run = 0;
    }
}

答案 1 :(得分:1)

正如Krzysztof的回答所说,核心转储的原因是erase()使迭代器失效。要解决这个问题,你需要正确地重置迭代器,使用erase()的{​​{3}},你将得到一个迭代器,指的是现在占据第一个字符擦除位置的字符,并将其分配给伊特。将第一个if语句更改为下面的代码,它应该可以正常工作。

    if(*ite == '|' && counter > 0)
    {
        ite = line.erase(ite - counter, ite);

        counter=0;
        cout<<line<<endl;
    }

答案 2 :(得分:0)

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;

int main()
{
    string line="1  2  |3 4| hbvhwf     wjff wenf|hjbcwbfw     ejwef   efwk    dfkwe|jsv                       |";
    cout <<line<<endl;

    string res;
    size_t length =  line.size();
    bool flag = false;
    for (int i = length - 1; i >= 0 ; --i)
    {
        if (line[i] == '|')
        {
            res.push_back(line[i]);
            flag = true;
        }
        else if (flag && line[i] == ' ')
        {

        }
        else
        {
            res.push_back(line[i]);
            flag = false;
        }
    }

    copy(res.rbegin(), res.rend(), ostream_iterator<char>(cout, ""));
    cout<<endl;
}

输出结果为:

1  2  |3 4| hbvhwf     wjff wenf|hjbcwbfw     ejwef   efwk    dfkwe|jsv                       |
1  2|3 4| hbvhwf     wjff wenf|hjbcwbfw     ejwef   efwk    dfkwe|jsv|