@Steve Townsend はすでに 1 つの可能性を指摘しています。operator>>
の代わりに使用したい場合はstd::getline
、それも可能です。Anistream
は常に空白をセパレータとして扱います。各ストリームには関連付けられたロケールがあり、各ロケールにはctype
ファセットが含まれています。そのctype
ファセットは、 がistream
どの入力文字が空白であるかを判断するために使用するものです。
あなたの場合、ストリームが改行とコロンのみを「空白」(つまり、セパレータ) として扱うようにしたいようですが、実際のスペース文字はセパレータではなく「通常の」文字として扱われます。
これを行うには、次のように ctype ファセットを作成できます。
struct field_reader: std::ctype<char> {
field_reader(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<std::ctype_base::mask>
rc(table_size, std::ctype_base::mask());
rc['\n'] = std::ctype_base::space;
rc[':'] = std::ctype_base::space;
return &rc[0];
}
};
これを使用するには、このファセットを使用してストリームにロケールを「吹き込む」必要があります。
int main() {
std::stringstream input("A:KT5:14:executive desk:");
// have the stream use our ctype facet:
input.imbue(std::locale(std::locale(), new field_reader()));
// copy fields from the stream to standard output, one per line:
std::copy(std::istream_iterator<std::string>(input),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
ただし、これにはいくつかの欠点があることを最初に認めます。まず第一に、ロケールとファセットは一般的に文書化されていないため、ほとんどのC++ プログラマーはこれを理解するのがかなり難しいと感じる可能性があります (特に、すべての実際の作業が「隠れて」行われる場合)。
もう 1 つの可能性は、Boost Tokenizerを使用することです。正直なところ、これを使用するにはもう少し手間がかかります。文字列を読み取り、それを個別に分割するなどの作業が必要になります。同時に、それは十分に文書化されており、かなり広く知られており、そのようなことを行う方法についての人々の先入観に十分に適合しているため、かなりの数の人々は、余分な複雑さにもかかわらず、おそらく従うのが簡単になるでしょう.