我想从SP
跳过所有HT
和std::istream
,然后从中读取一个字符串直到第一个SP
或HT
,然后跳过所有SP
和HT
,然后阅读所有内容直到新行\n
。
我试过
stream >> str >> std::ws;
std::getline(stream, rest);
但不太有用,因为std::ws
会占用换行符以及空格和水平制表。我想我可以做到
stream >> str;
std::getline(stream, rest);
trim_leading_whitespace(rest);
甚至是std::getline(stream, temp); do_regex_match("/* some complex regex */", temp, str, rest);
。
是否有可能以某种方式仅使用iostream
相关内容修复第一次尝试?它个人看起来最简洁,但当然任何建议如何写它很快,显然是受欢迎的。
答案 0 :(得分:1)
在读取行上声明一个额外的流:
std::string data; // <<-- trimmed data
std::string line;
std::getline(stream, line);
std::istringstream line_buffer(line);
line_buffer >> std::ws >> data;
答案 1 :(得分:0)
您可以创建自己的方面,将用户提供的空白字符注册到基础表。创建用于启用/禁用此功能的操纵器是我将留给您的练习:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
class ctype : public std::ctype<char>
{
template<class... Args>
static mask* make_table(Args... args)
{
static std::vector<mask> table(classic_table(),
classic_table() + table_size);
typedef int pack[];
(void)pack{ ((table[args] |= space), void(), 0) ... };
table['\n'] &= ~space;
return &v[0];
}
public:
template<class... Args>
ctype(Args... args)
: std::ctype<char>(make_table(args...)) { }
};
int main()
{
std::istringstream iss("!@#abc");
iss.imbue(std::locale(iss.getloc(), new ctype('!', '@', '#')));
std::string str;
std::getline(iss >> std::ws, str);
std::cout << str; // "abc"
}