C++ 从std::string提取信息
与字符串相关的查询太多了,但仍然存在一些疑问,因为每个字符串都不同,每个需求也不同 我在此表单中有一个字符串:C++ 从std::string提取信息,c++,stdstring,C++,Stdstring,与字符串相关的查询太多了,但仍然存在一些疑问,因为每个字符串都不同,每个需求也不同 我在此表单中有一个字符串: Random1A:Random1B::String1 Random2A:Random2B::String2。。。RandomNA:RandomNB::StringN 我想以这种形式返回一个字符串: String1-String2。。。字符串n 简而言之,输入字符串看起来像A:B::Val1 p:Q::Val2,而o/p结果字符串看起来像“Val1Val2” PS:随机数和字符串是长度较
Random1A:Random1B::String1 Random2A:Random2B::String2。。。RandomNA:RandomNB::StringN
我想以这种形式返回一个字符串:
String1-String2。。。字符串n
简而言之,输入字符串看起来像A:B::Val1 p:Q::Val2
,而o/p结果字符串看起来像“Val1
Val2
”
PS:随机数
和字符串
是长度较小(可变)的字母数字字符串
std::string GetCoreStr ( std::string inputStr, int & vSeqLen )
{
std::string seqStr;
std::string strNew;
seqStr = inputStr;
size_t firstFind = 0;
while ( !seqStr.empty() )
{
firstFind = inputStr.find("::");
size_t lastFind = (inputStr.find(" ") < inputStr.length())? inputStr.find(" ") : inputStr.length();
strNew += inputStr.substr(firstFind+2, lastFind-firstFind-1);
vSeqStr = inputStr.erase( 0, lastFind+1 );
}
vSeqLen = strNew.length();
return strNew;
}
我很难决定如何调整偏移量。[……]
std::string getCoreString(std::string常量和输入)
{
std::字符串结果;
//可选:避免重新分配:
result.reserve(input.length());
//(如果您有可靠的提示,我们可能预留了太多的空间
//输入我们拥有的部分,您可以减去适当的数字)
尺寸=0;
做
{
size\u t begin=input.find(“:”,end);
//添加检查:根本找不到双冒号。。。
if(begin==std::string::npos)
打破
//如果您需要找到这样一种变体,则单字符变体更有效:
end=std::min(input.find(“”,begin)+1,input.length());
result.append(input.begin()+begin+2,input.begin()+end);
}
while(end
旁注:您不需要额外的“长度”输出参数;它是多余的,因为返回的字符串包含相同的值…“我的代码正常工作,我得到了我选择的结果,但它不是一种最佳形式。我希望在提高代码质量方面得到帮助。”–那么这段代码更适合于……您仍然可以改进的内容:删除inputStr的副本(
seqStr
),我看不出您在哪里需要它。然后,std::find重载提供了一个offset参数。您可以使用调整后的偏移量重新开始下一次搜索,并保持字符串不变(您也可以接受它作为常量引用),而不是越来越多地擦除字符串直到其为空。您将在字符串上迭代,直到偏移量大于或等于字符串的长度。您将在分配给lastFind时调用find
两次。我不确定编译器是否可以优化第二次调用,尤其是当输入字符串不是常量时。更好:lastFind=find();如果(lf>长度)lf=长度代码>甚至:lastFind=std::max(find(),length())代码>。另外:如果空格出现在双冒号之前,会发生什么?只有在firstFind
(前面提到的第二个重载)之后,我才会重新开始搜索它。我无法决定如何调整偏移量。我正在擦除已经解析的字符串,只是为了解决这个问题。此外,在双冒号之前不会有任何空格。
std::string GetCoreStr ( const std::string & inputStr )
{
std::string strNew;
for ( int i = 0; i < inputStr.length(); ++i )
{
if ( inputStr[i] == ':' && inputStr[i + 1] == ':' )
{
i += 2;
while ( ( inputStr[i] != ' ' && inputStr[i] != '\0' ) )
{
strNew += inputStr[i++];
}
if ( inputStr[i] == ' ' )
{
strNew += ' ';
}
}
}
return strNew;
}
std::string getCoreString(std::string const& input)
{
std::string result;
// optional: avoid reallocations:
result.reserve(input.length());
// (we likely reserved too much – if you have some reliable hint how many
// input parts we have, you might subtract appropriate number)
size_t end = 0;
do
{
size_t begin = input.find("::", end);
// added check: double colon not found at all...
if(begin == std::string::npos)
break;
// single character variant is more efficient, if you need to find just such one:
end = std::min(input.find(' ', begin) + 1, input.length());
result.append(input.begin() + begin + 2, input.begin() + end);
}
while(end < input.length());
return result;
}