11

文字列内のすべてのスペースをアンダースコアに置き換えるものを書き込もうとしています。

私がこれまでに持っているもの。

string space2underscore(string text)
{
    for(int i = 0; i < text.length(); i++)
    {
        if(text[i] == ' ')
            text[i] = '_';
    }
    return text;
}

私が何かをしていれば、ほとんどの場合、これはうまくいくでしょう。

string word = "hello stackoverflow";
word = space2underscore(word);
cout << word;

それは「hello_stackoverflow」を出力します。これはまさに私が望むものです。

ただし、次のようなことをする場合

string word;
cin >> word;
word = space2underscore(word);
cout << word;

「こんにちは」という最初の単語を取得します。

誰かがこれの修正を知っていますか?

4

5 に答える 5

25

問題は解決しましたがgetline、標準ライブラリには多くの便利な機能が含まれていると言いたかっただけです。手巻きループの代わりに、次のことができます。

std::string space2underscore(std::string text)
{
    std::replace(text.begin(), text.end(), ' ', '_');
    return text;
}

これは機能し、高速であり、実際にあなたがしていることを表現しています。

于 2011-03-09T22:47:29.397 に答える
15

問題はcin >> word、最初の単語だけを読むことです。一度に全体を操作したい場合は、を使用する必要がありますstd::getline

例えば:

std::string s;
std::getline(std::cin, s);
s = space2underscore(s);
std::cout << s << std::endl;

また、実際に行を読み取ることができたことを確認することもできます。あなたはこのようにそれを行うことができます:

std::string s;
if(std::getline(std::cin, s)) {
    s = space2underscore(s);
    std::cout << s << std::endl;
}

最後に、補足として、関数をよりクリーンな方法で記述できる可能性があります。個人的に私はそれをこのように書くでしょう:

std::string space2underscore(std::string text) {
    for(std::string::iterator it = text.begin(); it != text.end(); ++it) {
        if(*it == ' ') {
            *it = '_';
        }
    }
    return text;
}

またはボーナスポイントには、std::transform!を使用してください。

編集: 幸運にもc ++ 0x機能を使用できる場合(そしてそれが大きい場合はそれが大きいことを私は知っています)、ラムダとを使用できますstd::transform。これにより、非常に単純なコードが作成されます。

std::string s = "hello stackoverflow";
std::transform(s.begin(), s.end(), s.begin(), [](char ch) {
    return ch == ' ' ? '_' : ch;
});
std::cout << s << std::endl;
于 2011-03-09T21:53:13.427 に答える
5

問題は、ライブラリstd::cinからの理解にあります。右側の引数としてを使用してストリームで演算子を使用すると、一度に1つの単語しか使用できません(空白を使用して区切ります)。iostream>>std::string

代わりに必要なのはstd::getline()、文字列を取得するために使用することです。

于 2011-03-09T21:53:07.733 に答える
-1

交換

cin >> word;

getline(cin, word);
于 2011-03-09T21:53:36.143 に答える