c 语言通过分隔符截取字符串,C ++字符串基于分隔符的修改和提取

本问题已经有最佳答案,请猛点这里访问。

这是一个基本的问题,但我在思考解决方案时遇到了麻烦,所以我需要朝着正确的方向努力。

我有一个输入文件,我要把它放入一个字符串变量中。问题是我需要将这个字符串分成不同的东西。将有3个字符串和1个int。它们用":"分隔。

我知道我可以通过find()找到第一个":"的位置,但我真的不知道如何通过字符串进行处理,对于每个事物并将其放入它自己的字符串/ int中。

该文件的实际输入如下所示:

A:PEP:909:Inventory Item

A将成为命令我必须执行...所以这将是一个字符串。

PEP是一个关键,需要是一个字符串。

909是一个int。

最后一个是字符串。

所以我认为我想要做的是拥有3个字符串var和1个int并将所有这些内容放入各自的变量中。

所以我想我最终想要将这个C ++字符串转换为C字符串,所以我可以使用atoi将一个部分转换为int。

多次询问和回答:stackoverflow.com/questions/53849/

那不太一样。 在这种情况下,他需要转换一些东西。 简单的getline循环不会这样做

马丁的链接再次检查。 我在那边发布了我的代码。 它就像一个3行while循环来分割字符串。 然后他可以使用atol(stringVector [2] .c_str())来提取数字。 或atoi()如果他想要的话。 或者环礁()。 或者atoq()。

我经常使用这样的东西:

void split(const std::string &s, char delim, std::vector<:string> &elems) {

std::stringstream ss(s);

std::string item;

while(std::getline(ss, item, delim)) {

elems.push_back(item);

}

}

你可以像这样使用它:

std::vector<:string> tokens;

split("this:is:a:test", ':', tokens);

令牌现在将包含"this","is","a"和"test"

简单,不需要添加另一个库。适合我。

+1我的首选解决方案,没有搞乱find()和索引。

必须喜欢在一年之久的帖子上的downvote,工作得很好......

当您想要使用C ++标准库时,最好使用std::getline和std::istringstream完成此操作:

std::string command;

std::string key;

int         id;

std::string item;

std::string line ="A:PEP:909:Inventory Item";

// for each line:

std::istringstream stream(line);

std::getline(stream, command, ':');

std::getline(stream, key, ':');

stream >> id;

std::getline(stream, item);

// now, process them

考虑将它放入自己的结构中:

struct record {

std::string command;

std::string key;

int         id;

std::string item;

record(std::string const& line) {

std::istringstream stream(line);

stream >> *this;

}

friend std::istream& operator>>(std::istream& is, record & r){

std::getline(is, r.command, ':');

std::getline(is, r.key, ':');

stream        >> r.id;

std::getline(is, r.item);

return is;

}

};

当你击中一个> 3或<3冒号的格式错误的条目时,请注意你不会进入下一行。

是的,它假定线条是正确的。理论上,密钥也可以包含' n',然后它将跨越到下一行。

或者你只是首先提取整行,然后使用记录的ctor。这不会跨越下一行。

只是评论,运营商>>不需要被宣布为朋友。没有私人会员,所以它可以是外部免费功能。

dribeas,它已经是一个免费的功能。但它不能直接调用,只适用于koenig查找(ADT)(参见"朋友名称注入")。我喜欢在这里使用朋友定义,因为它会在您将成员设为私有时进行扩展。

看看boost :: tokenizer。

boost.org/doc/libs/1_37_0/libs/tokenizer/tokenizer.htm

我找到的一个舒适的解决方案并不罕见,是以下原型:

string SplitToken(string & body, char separator)

返回到第一次出现分隔符的所有内容,并删除包含分隔符的那部分。

"我的"MFC - 基于CString的实现如下:

CString SplitStringAt(CString & s, int idx)

{

CString ret;

if (idx < 0)

{

ret = s;

s.Empty();

}

else

{

ret = s.Left(idx);

s = s.Mid(idx+1);

}

return ret;

}

CString SplitToken(CString & s,TCHAR separator)

{

return SplitStringAt(s, s.Find(separator));

}

这绝对不是最有效的方法 - 主要的缺点是修改了主体并为每个令牌创建了一个新的(部分)副本,所以不要在性能关键位置使用它!

但是,对于简单的解析器,我发现这个(以及一些相关的函数)非常有用。

使用C风格的字符串,您可以使用strtok()来执行此操作。你也可以使用sscanf()

但是既然你正在处理C ++,你可能想要坚持使用内置的std :: string函数。因此,您可以使用find()。 Find有一个表单,它接受第二个参数,它是开始搜索的偏移量。所以你可以找到(':')找到第一个实例,然后使用find(':',firstIndex + 1)来查找下一个实例,其中firstIndex是第一次调用find()返回的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值