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<char>(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你尝试过一些简单的事情吗?
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)) >> number;
当然,这可能会导致可变大小字符串出错。
编辑:你不可能收到包含所有你想要的信息的字符串,因为问题必须在那里。这是因为您用于去除空格的代码是正确的,并且确实有效。修复您的子字符串问题(由 x 错误关闭),您就可以开始了
你可以看到my example
编辑 2: 将代码固定为 8 个字符,5 个空格,然后是一个数字。问题肯定仍然存在于未收到数字的子字符串中
编辑 3: 您的 istringstream 没有读取空白(根据下面的 cmets),因此请尝试一个简单的赋值操作。我仍然相信您需要为 14 个字符设置子字符串,这里是 another example。
所以你要找的线应该是
number = line.substr(i,14)
或者,您可以使用noskipws 标志拉入空白,因为您之后会删除。
istringstream(line.substr(i, 14)) >> std::noskipws >> 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 ++如何删除特定字符串中的空格的主要内容,如果未能解决你的问题,请参考以下文章