在线路中的字符之前卸下所有空间

Remove all spaces before a character in a line

本文关键字:空间 字符 在线路      更新时间:2023-10-16

我有这个特殊的要求,在我需要在特定字符的特定字符(即管道'|'的特定字符)之前删除所有空间字符。我为其编写了一个测试代码,该代码实际上是在打印正确的输出,但还向我赠送了一个核心文件:(

我的代码如下:

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|

正如Krzysztof的答案所述,核心转储的原因是erase()无效迭代器。要解决此问题,您需要正确重置迭代器,使用erase()的范围版本,您将获得一个迭代器,引用现在占用第一个字符位置的字符,并将其分配给ITE。将第一个if语句更改为下面的代码,它应该可以正常工作。

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

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

具体来说,当line.erase(start,counter);执行时,ite无效 - 不再保证它参考字符串中的有效位置。如果它不等于 line.end(),则可以在条件isalnum(*ite)中删除。由于ite在此时无效,因此可以参考已释放的内存(例如,如果将字符串重新分配在被删除后)。因此,这条线导致segfault。

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

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;
    }
}
#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;
}

Ouput是:

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