的问题是,>>运营商的字符串 (std::string或C风格的字符串)实际上实现了一个单词的 语义,并具有特定的单词定义。 的决定是任意的(我会使它成为一条线),但由于 一个字符串可以表示很多不同的东西,他们不得不选择 的东西。
解决方案通常不会在字符串上使用>>。 定义你想要的类(在这里,可能类似于 Symbol),并为它定义一个运算符>>,它尊重它的 语义。你的代码会更清晰,并且你可以根据需要添加各种侵入式控件。如果你知道 该场总是恰好四个字符,你可以做 一些东西:
class DContactSymbol
{
char myName[ 4 ];
public:
// ...
friend std::istream&
operator>>(std::istream& source, DContactSymbol& dest);
// ...
};
std::istream&
operator>>(std::istream& source, DContactSymbol& dest)
{
std::sentry guard(source);
if (source) {
std::string tmp;
std::streambuf* sb = source.rdbuf();
int ch = sb->sgetc();
while (source && (isalnum(ch) || ch == '_')) {
tmp += static_cast(ch);
if (tmp.size() > sizeof(dest.myName)) {
source.setstate(std::ios_base::failbit);
}
}
if (ch == source::traits_type::eof()) {
source.setstate(std::ios_base::eofbit);
}
if (tmp.size() != sizeof(dest.myName)) {
source.setstate(std::ios_base::failbit);
}
if (source) {
tmp.copy(dest.myName, sizeof(dest.myName));
}
}
return source;
}
(请注意,不像一些其他建议,例如 使用std::istream::read,这一个维护所有的通常 约定,如跳绳导致依赖于 skipws标志空白。)
当然,如果你不能保证100%的符号将 永远是4个字符,你应该使用std::string它,和 相应地修改>>运营商。
而且顺便说一句,你似乎想读四个大字成 dcontact,虽然它只有足够大的三(因为 >>将插入一个终止'\0')。如果你再读了三个以上的 ,你就有未定义的行为。