C ++如何删除特定字符串中的空格

时间:2019-07-16 13:18:09

标签: c++ algorithm c++11

我的工作中需要读取一个.txt文件。每个字符串的长度为13个字符,例如“ PM 1”,其中“ PM 1”是8个字符,在“ PM”和“ 1”之间有5个空格,在“ 1”后面有5个空格,例如“ DPSI 26”的长度也为13个字符,其中“ DPSI 26”为8个字符,在“ DPSI”和“ 26”之间有2个空格,在“ 26”之后有5个空格。 最后,我想读取此文件,并删除它们之间的这些空白,例如,删除“ PM 1”的所有空白,然后获取“ PM1”,并且通过删除这些空白将“ DPSI 26”变为“ DPSI26” 。 我的目的是: 我想每隔13个字符读取此文件以形成一个字符串,这意味着我想用c ++将数据拆分成13个字符,然后删除此字符串中的这些空格,然后生成1D向量的字符串。

这是我需要阅读的字符串名称列表:

import subprocess

# cmd =['','',...]
def run(cmd):
    p = subprocess.Popen(cmd, shell=True)
    return p.wait()

我的原始密码:

PM     1     PM     2     PM     3     PM     4     PM     5     PM     6
PM     7     PM     8     PM     9     PM    10     PM    11     PM    12
PM    13     PM    14     PM    15     PM    16     PM    17     PM    18
PM    19     PM    20     PM    21     PM    22     PM    23     PM    24
PM    25     PM    26     PM    27     PM    28     PM    29     PM    30
PM    31     PM    32     PM    33     PM    34     PM    35     PM    36
PM    37     PM    38     PM    39     PM    40     PM    41     PM    42
PM    43     PM    44     PM    45     PM    46     PM    47     PM    48
PM    49     PM    50     PM    51     PM    52     PM    53     PM    54
PM    55     DPSI   1     DPSI   2     DPSI   3     DPSI   4     DPSI   5
DPSI   6     DPSI   7     DPSI   8     DPSI   9     DPSI  10     DPSI  11
DPSI  12     DPSI  13     DPSI  14     DPSI  15     DPSI  16     DPSI  17
DPSI  18     DPSI  19     DPSI  20     DPSI  21     DPSI  22     DPSI  23
DPSI  24     DPSI  25     DPSI  26     DPSI  27     DPSI  28     DPSI  29
DPSI  30     DPSI  31     DPSI  32     DPSI  33     DPSI  34     DPSI  35
DPSI  36     DPSI  37     DPSI  38     DPSI  39     DPSI  40     DPSI  41
DPSI  42     DPSI  43     DPSI  44     DPSI  45     DPSI  46     DPSI  47
DPSI  48     DPSI  49     DPSI  50     DPSI  51     DPSI  52     DPSI  53

我的预期结果:

using namespace std;

int main()
{

    std::vector<string> names;

    ifstream infile;    
    infile.open("species_name");
    string line;

    while (getline(infile, line))
    {
        for (int i = 0; i < line.size(); i += 13) 
        {
        std::string number;
        istringstream(line.substr(i, 13)) >> number;
        number.erase(std::remove(number.begin(), number.end(), " "), number.end());
        names.push_back(number);
        cout << "number: " << number <<endl;
        }

    }
    infile.close();
}  

4 个答案:

答案 0 :(得分:1)

我修改了密码,然后问题解决了。

使用命名空间标准;

int main() {

std::vector<string> names;

ifstream infile;    
infile.open("species_name");
string line;

while (getline(infile, line))
{
    for (int i = 0; i < line.size(); i += 13) 
    {
    std::string number;
    **number = line.substr(i, 13);**
    **number.erase(std::remove(number.begin(), number.end(), ' '), number.end());**
    names.push_back(number);
    cout << "number: " << number <<endl;
    }

}
infile.close();

}

答案 1 :(得分:0)

不知道您的实际结果是什么,我可以根据您的代码推测您没有收到数字(13个字符串的最后一个字符)。

如果是这种情况,并且您只想从整个行中删除空格,请读取整个14个字符串,然后去除空格。如果您采用现有的方式进行这项工作(number.erase(std::remove(number.begin(), number.end(), " "), number.end())),则建议更改您的substr行。

istringstream(line.substr(i, 13)) >> number;

当然,这可能导致可变大小的字符串出错。

编辑:由于问题必定存在于此,因此无法通过任何方式接收包含所有所需信息的字符串。这是因为您用于剥离空格的代码是正确的,并且可以正常工作。解决您的子字符串问题(减少x错误),您很高兴

您可以看到my example

编辑2::将代码固定为8个字符,5个空格和一个数字。问题肯定仍然存在于子字符串中而不接收数字

编辑3:(根据下面的注释),您的istringstream不在空白中读取,因此请尝试简单的赋值操作。我仍然相信您需要为14个字符的子字符串,这是another example

因此您要查找的行应该是 number = line.substr(i,14) 另外,您可以使用noskipws标志来插入空格,因为之后您将其删除。 istringstream(line.substr(i, 14)) >> std::noskipws >> number;

另外,您可能需要更新for循环的增量,因为您正在读取14个字符而不是13个字符。这当然是假设1后面紧跟着您要拉出的下一个序列的开始。例如,line必须与此类似: abcdefgh 1ijklmnop 2...

答案 2 :(得分:0)

您可以为此使用正则表达式:

#include <fstream>
#include <iostream>
#include <regex>
#include <string>

int main() {
    std::ifstream infile("species_name");
    std::string line;

    while (std::getline(infile, line)) {
        std::cout << std::regex_replace(
            line,
            std::regex("(\\w)\\s*(\\d)"),
            "$1$2") << '\n';
    }
    return 0;
}

此正则表达式搜索字符,一些空格和数字,然后将其替换为字符和无空格的数字。输出是

PM1     PM2     PM3     PM4     PM5     PM6
PM7     PM8     PM9     PM10     PM11     PM12
PM13     PM14     PM15     PM16     PM17     PM18
PM19     PM20     PM21     PM22     PM23     PM24
PM25     PM26     PM27     PM28     PM29     PM30
PM31     PM32     PM33     PM34     PM35     PM36
PM37     PM38     PM39     PM40     PM41     PM42
PM43     PM44     PM45     PM46     PM47     PM48
PM49     PM50     PM51     PM52     PM53     PM54
PM55     DPSI1     DPSI2     DPSI3     DPSI4     DPSI5
DPSI6     DPSI7     DPSI8     DPSI9     DPSI10     DPSI11
DPSI12     DPSI13     DPSI14     DPSI15     DPSI16     DPSI17
DPSI18     DPSI19     DPSI20     DPSI21     DPSI22     DPSI23
DPSI24     DPSI25     DPSI26     DPSI27     DPSI28     DPSI29
DPSI30     DPSI31     DPSI32     DPSI33     DPSI34     DPSI35
DPSI36     DPSI37     DPSI38     DPSI39     DPSI40     DPSI41
DPSI42     DPSI43     DPSI44     DPSI45     DPSI46     DPSI47
DPSI48     DPSI49     DPSI50     DPSI51     DPSI52     DPSI53

答案 3 :(得分:0)

您尝试过一些简单的事情吗?

std::string name;
int value;
while (infile >> name >> value)
{
   // Process name & value
}

输入设备将跳过空格,直到找到一个数字(或直到找到一个字符串)为止。换行符被认为是空格,因此将被忽略。

更正式的设计:

struct Name_Value
{
    std::string name;
    int         value;
    friend std::istream& operator>>(std::istream& infile, Name_Value& nv);
};

std::istream& operator>>(std::istream& infile, Name_Value& nv)
{
    infile >> nv.name;
    infile >> nv.value;
    return infile;
}

您输入的循环变为:

std::vector<Name_Value> database;
Name_Value nv;
while (infile >> nv)
{
    database.push_back(nv);
}

我建议尽可能简化。