良いニュースと悪いニュースがあります。良いニュースはあなたがこれを行うことができるということです。
悪い知らせは、それを行うことはかなりラウンドアバウトであり、一部の人々はそれがまったく醜くて厄介なことに気付いています。それを行うには
は、次の2つの事実を観察することによって開始:
- 通常の文字列の抽出は「言葉」を区切るために空白を使用しています。
- 空白を構成するものは、ストリームのロケールで定義されています。一緒にそれらを置く
が、答えは(遠回りの場合)かなり明白になっ:複数の区切り文字を定義するために、私たちは私たちが区切り文字として扱われるべきである何文字を指定することができますロケール(すなわち、ホワイトスペース)を定義します。
struct word_reader : std::ctype<char> {
word_reader(std::string const &delims) : std::ctype<char>(get_table(delims)) {}
static std::ctype_base::mask const* get_table(std::string const &delims) {
static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());
for (char ch : delims)
rc[ch] = std::ctype_base::space;
return &rc[0];
}
};
その後、我々は、我々は、区切り文字として使用する文字を渡し、(そのCTYPEファセットを持つだけでなく、ロケール)そのロケールを使用するようにストリームを伝える必要があり、その後、ストリームから単語を抽出します。
int main() {
std::istringstream in("word1, word2. word3,word4");
// create a ctype facet specifying delimiters, and tell stream to use it:
in.imbue(std::locale(std::locale(), new word_reader(" ,.\n")));
std::string word;
// read words from the stream. Note we just use `>>`, not `std::getline`:
while (in >> word)
std::cout << word << "\n";
}
結果はあなたが望むものです:私たちが言った句読点を使わずに各単語を抽出することは、 "空白"でした。
word1
word2
word3
word4
@GabeNonesええと、私たちはCとC++の両方にタグをつけて、このCの疑問を解決することはできません。私たちはC++を見つけなければなりません。 –
@BaummitAugen:C++のDupeを見つけることは大丈夫ですが、あなたがそれに対してクローズしたものは、特に優れたDupe(少なくともIMO)ではありません。 1つの答えでは、この問題はまったく解決されません(ストリングの分割のみを扱い、ここで必要なストリームからの読み込みは扱いません)。もう片方はうまく動作しますが、偶然によって並べ替えられます(これは '\ n'がデリミタでなければならないが、それを望んでいない他の人にとってはうまくいきません)。 –
@JerryCoffin質問は同じように思えます。他の質問にもっと良い回答が必要な場合は、まだ回答を追加することはできますが、それは閉じられません。 –