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

Posted

技术标签:

【中文标题】c ++如何删除特定字符串中的空格【英文标题】:How c++ removes the whitespaces in specific characters string 【发布时间】:2019-07-16 13:18:09 【问题描述】:

我有一个 .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 个字符,然后删除这个字符串中的这些空格,然后生成字符串的一维向量。 p>

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

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();
  

我的预期结果:

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    DPS10   DPSI11
DPSI12   DPSI13   DPSI14   DPSI15   DPS16   DPSI17
DPSI18   DPSI19   DPSI20   DPSI21   DPS22   DPSI23
DPSI24   DPSI25   DPSI26   DPSI27   DPS28   DPSI29
DPSI30   DPSI31   DPSI32   DPSI33   DPS34   DPSI35
DPSI36   DPSI37   DPSI38   DPSI39   DPS40   DPSI41
DPSI42   DPSI43   DPSI44   DPSI45   DPS46   DPSI47
DPSI48   DPSI49   DPSI50   DPSI51   DPS52   DPSI53

【问题讨论】:

这段代码的实际结果是什么? 如果您的结果与您的预期不同,您是否尝试过调试? regex_replace(std::ostreambuf_iterator&lt;char&gt;(std::cout), infile.begin(), infile.end(), "(\w)\s*(\d)", "$1$2") 没有。实际上,在我的代码中,它只读取“PM”或“DPSI”部分,后面没有数字1或26。 【参考方案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();

【讨论】:

【参考方案2】:

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

#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

【讨论】:

首先,谢谢。当我编译你的代码时,有一个错误: test-names.C:15:16: error: 'std::ifstream' aka 'class std::basic_ifstream' has no member named 'begin';你的意思是“乞求”吗? infile.begin(), ^~~~~ beg test-names.C:16:20: error: 'std::ios_base::end' 不能用作函数 infile.end(), @NingyiLi 好的,修好了 太棒了。太感谢了。但在我的目的中,我需要读取文件并创建一个 std::vector 名称变量来包含所有这些名称。 names.push_back(number); @NingyiLi 这不是你的问题。 好的。如果我想实现这个目的,这些代码可以吗: std::vector names; std::cout >数字; names.push_back(number);【参考方案3】:

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

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);

我建议尽可能简单。

【讨论】:

首先谢谢您。但我的目的是:我想每 13 个字符读取一次这个文件以形成一个字符串,这意味着我想用 c++ 将数据拆分为 13 个字符,然后删除这个字符串中的这些空格,然后生成字符串的一维向量。 试试我的解决方案。我相信它会起作用。您的数据主要是空格分隔的,您无需担心列。【参考方案4】:

在不知道你的实际结果的情况下,我可以根据你的代码推测你没有收到数字(13 个字符串的最后一个字符)。

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

istringstream(line.substr(i, 13)) &gt;&gt; number;

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

编辑:你不可能收到包含所有你想要的信息的字符串,因为问题必须在那里。这是因为您用于去除空格的代码是正确的,并且确实有效。修复您的子字符串问题(由 x 错误关闭),您就可以开始了

你可以看到my example

编辑 2: 将代码固定为 8 个字符,5 个空格,然后是一个数字。问题肯定仍然存在于未收到数字的子字符串中

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

所以你要找的线应该是 number = line.substr(i,14) 或者,您可以使用noskipws 标志拉入空白,因为您之后会删除。 istringstream(line.substr(i, 14)) &gt;&gt; std::noskipws &gt;&gt; number;

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

【讨论】:

我通过改变 istringstream(line.substr(i, 13)) >> number;按照你的建议,但我仍然只得到了没有数字的 PM。 为什么不打印出number,然后再去掉空格,看看它包含什么。如果它不包含数字,则更改 substr 长度(13)直到它也包含数字。这可能是一个错误或计数错误(整个字符串长度超过 13 个字符)。 感谢您的回答。但我认为这不是这种错误,因为我按照你的建议做了。还是不行。 @NingyiLi 8 个字符串,5 个字符空格 = 13 个字符。该数字的另外 1 个字符是 14 个字符的字符串。 number 在 substr 之后和空白剥离之前的长度和输出是多少?线的长度和线的输出是多少?在不提供任何有关发生情况的信息的情况下说“它不起作用”并不是很有帮助。这是调试,在测试和收集信息时尽量健壮 好吧,我在我的编程中使用代码:istringstream(line.substr(i, 14)) >> number,然后通过cout输出数字,但它只输出PM,PM,PM ...没有数字,实际上,我需要的是 PM1、PM2、PM3...

以上是关于c ++如何删除特定字符串中的空格的主要内容,如果未能解决你的问题,请参考以下文章

JS中怎么删除字符串中的特定的字符?

JS中怎么删除字符串中的特定的字符?

JS中怎么删除字符串中的特定的字符?

c语言编写一个程序,实现查找一个字符串中的特定字符,并将其删除.

在javascript中如何去除字符串两头的空格

编程去掉字符串中的多余空格