是否有任何内置函数可用于在C ++中的两个分隔符字符串之间获取字符串?
输入字符串
(23567)=(58765)+(67888)+(65678)
预期产出
23567
58765
67888
65678
include <iostream>
#include <stdexcept>
#include <string>
#include <sstream>
#include <vector>
std::vector<std::string> tokenize(const std::string& input)
{
std::vector<std::string> result;
std::istringstream stream(input);
std::string thingie; // please choose a better name, my inspiration is absent today
while(std::getline(stream, thingie, '('))
{
if(std::getline(stream, thingie, ')'))
result.push_back(thingie);
else
throw std::runtime_error("expected \')\' to match \'(\'.");
}
return result;
}
void rtc()
{
ifstream myfile(test.txt);
if(myfile.is_open())
while (!myfile.eof())
{
getline(myfile,line);
auto tokens = tokenize(line);
for(auto&& item : tokens)
std::cout << item << '\n';
}
Error C4430 missing type specifier int assumed note:c++ does not support default int
ErrorC2440initializing cannot convertfrom std::vector<_ty>to int
Error C2059syntac error empty declaration
Error C2143syntax error missing;before&&
Error C2059syntax error:')'
答案 0 :(得分:1)
使用std::getline
:
#include <iostream>
#include <stdexcept>
#include <string>
#include <sstream>
#include <vector>
std::vector<std::string> tokenize(const std::string& input)
{
std::vector<std::string> result;
std::istringstream stream(input);
std::string thingie; // please choose a better name, my inspiration is absent today
while(std::getline(stream, thingie, '('))
{
if(std::getline(stream, thingie, ')'))
result.push_back(thingie);
else
throw std::runtime_error("expected \')\' to match \'(\'.");
}
return result;
}
int main()
{
std::string test = "(23567)=(58765)+(67888)+(65678)";
auto tokens = tokenize(test);
for(auto&& item : tokens)
std::cout << item << '\n';
}
对于那些不完全相信这个解决方案的强大稳健性的人,我将其专门用于括号之间的double
输入,并使用boost::lexical_cast
来验证输入:
#include <iostream>
#include <stdexcept>
#include <string>
#include <sstream>
#include <vector>
#include <boost/lexical_cast.hpp>
std::vector<double> tokenize(const std::string& input)
{
std::vector<double> result;
std::istringstream stream(input);
std::string thingie; // please choose a better name, my inspiration is absent today
while(std::getline(stream, thingie, '('))
{
if(std::getline(stream, thingie, ')'))
{
try
{
result.push_back(boost::lexical_cast<double>(thingie));
}
catch(...)
{
throw std::runtime_error("This wasn't just a number, was it?");
}
}
else
throw std::runtime_error("expected \')\' to match \'(\'.");
}
return result;
}
int main()
{
std::string test = "(23567)=(58765)+(67888)+(65678)";
auto tokens = tokenize(test);
for(auto&& item : tokens)
std::cout << item << '\n';
test = "(2h567)=(58765)+(67888)+(65678)";
tokens = tokenize(test);
}
Live example here。现在去了解strtok
实际上有多糟糕,或者当前的<regex>
实现有多糟糕/不可移植。此外,对于那些怀疑boost::lexical_cast
表现明智的人,please see the results for yourself。
答案 1 :(得分:0)
strpbrk
可用于查找每个令牌的开头
或strcspn
可用于计算字符直到下一个标记
然后strspn
可用于查找每个令牌的长度。
const char tokenChars[] = "0123456789";
char token = input; // say input is "(23567)=(58765)+(67888)+(65678)"
while( 0 != (token = strpbrk( token, tokenChars )) ) // find token
{
size_t tokenLen = strspn( token, token_chars ); // find length of token
// print out tokenLen characters of token here!
token+= tokenLen; // go to end of token
}
http://www.cplusplus.com/reference/cstring/strspn/
答案 2 :(得分:0)
如果你想使用指针,这就是答案:
char test[32] = "(23567)=(58765)+(67888)+(65678)";
char *output = NULL;
char *pos = (char *)test;
int length = 0;
while (*pos != '\0') {
if(*pos == '(' || *pos == ')' || *pos == '+' || *pos == '=') {
*pos = '\0';
if (length > 0) {
output = new char[length + 1];
strncpy_s(output, length + 1, pos - length, length + 1);
length = 0;
cout << output << endl;
delete [] output;
output = NULL;
}
} else {
length++;
}
pos++;
}
答案 3 :(得分:-1)
const char input[] = "(2av67q)=(ble ble)+(67888)+(qpa)";
int s = 0;
for(int i = 0; input[i]; i++)
{
if ( input[i] == ')' )
{
cout << endl;
s = 0;
}
else if ( input[i] == '(' )
{
s = 1;
continue;
}
else
{
if ( s == 1 )
{
cout << input[i];
}
}
}
结果:
2av67q
ble ble
67888
qpa
答案 4 :(得分:-1)
虽然有些评论员可能讨厌它但我喜欢这个:
for (p = std::strtok(input, "+"); p != NULL; p = std::strtok(NULL, "+"))
{
// do more stuff
}
这不会起作用 - 分隔符需要扩展 - 它展示了易用性。
答案 5 :(得分:-1)
以下是使用正则表达式的解决方案:
std::vector<std::string> get_numbers(std::string const& s)
{
static std::regex regex(R"(^\((\d+)\)=\((\d+)\)(?:\+\((\d+)\))+$)",
std::regex_constants::ECMAScript
| std::regex_constants::optimize);
std::vector<std::string> results;
std::sregex_iterator matches(s.cbegin(), s.cend(), regex);
for (auto first = matches->cbegin(), last = matches->cend();
last != first;
++first)
{
results.push_back(first->str());
}
return results;
}