在输入输出流,字符串(意思是两个C字符串和C++字符串)几乎没有任何的格式要求。任何和所有字符被提取为一个字符串仅直到一个空白字符被发现,或直至流的末尾被捕获。在你的榜样,你使用意在吃起来的重要数据之间的逗号的字符串,但您所遇到的输出是我刚才解释的行为的结果是:dummy
字符串不只是吃了逗号,但也字符序列的其余部分直到下一个空白字符。
为了避免出现这种情况,您可以使用char
作为虚拟变量,其中只有一个字符的空间。如果你正在寻找把Apple 1
成一个字符串,你需要一个格式化提取,因为格式化提取operator>>()
只读取,直到空白。在这里使用相应的功能是std::getline()
:
string c;
char dummy;
if ((stream >> a >> dummy >> b >> dummy) &&
std::getline(stream >> std::ws, s))
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
}
清除换行后的格式化的提取也是必要的,这就是为什么我用std::ws
清除前导空格。我还使用了if
语句包含以判断它成功与否的提取。
任何平滑的方式做到这一点会帮助我极大。
您可以使用std::ctype<char>
面流中充满语言环境的逗号字符的类型设置为空白字符。这将使得不需要使用虚拟变量。这里有一个例子:
namespace detail
{
enum options { add, remove };
class ctype : public std::ctype<char>
{
private:
static mask* get_table(const std::string& ws, options opt)
{
static std::vector<mask> table(classic_table(),
classic_table() + table_size);
for (char c : ws)
{
if (opt == add)
table[c] |= space;
else if (opt == remove)
table[c] &= ~space;
}
return &table[0];
}
public:
ctype(const std::string& ws, options opt)
: std::ctype<char>(get_table(ws, opt)) { }
};
}
class adjustws_impl
{
public:
adjustws_impl(const std::string& ws, detail::options opt) :
m_ws(ws),
m_opt(opt)
{ }
friend std::istream& operator>>(std::istream& is,
const adjustws_impl& manip)
{
const detail::ctype* facet(new detail::ctype(manip.m_ws, manip.m_opt));
if (!std::has_facet<detail::ctype>(is.getloc())
{
is.imbue(std::locale(is.getloc(), facet));
} else
delete facet;
return is;
}
private:
std::string m_ws;
detail::options m_opt;
};
adjustws_impl setws(const std::string& ws)
{
return adjustws_impl(ws, detail::add);
}
adjustws_impl unsetws(const std::string& ws)
{
return adjustws_impl(ws, detail::remove);
}
int main()
{
std::istringstream iss("10,1.546,Apple 1");
int a; double b; std::string c;
iss >> setws(","); // set comma to a whitespace character
if ((iss >> a >> b) && std::getline(iss >> std::ws, c))
{
// ...
}
iss >> unsetws(","); // remove the whitespace classification
}
字符哑将修复它(第二个是吃了输入) –
@DieterLücking'字符串假人;'德哦。我盯着像白痴一样的代码,并没有看到它:) – jrok
@DieterLücking是的,它已经改进为输出10和1.546,但我需要'苹果1',并没有得到任何东西,我现在正在'Apple'但仍然不是“Apple 1”。有任何想法吗? –