1

私はこれを3か月しかやっておらず、現在は立ち止まっています。何が間違っているのかわかりません。正しい方向に私を向ける助けをいただければ幸いです。私は誰かに私の宿題をするように頼んでいるわけではありません。ユーザーから 1 行の入力を受け取り、小文字の数をカウントして出力するプログラムを作成することになっています。これは私がこれまでに持っているものですが、それがすべきことをしていません。

#include <fstream>
#include <iostream>
#include <cctype>
#include <string>

using namespace std;

int main(){
    char text;
    int count = 0;
    cout << " Enter one line of text: ";

    do 
    {
        cin.get(text);

        while(text!='\n')
        {
            if(islower(text))
            count++;
        }
    } while(text!='\n');

    cout << count << "\n";
}
4

2 に答える 2

3

問題は入力にありました: 個別の文字を入力しますが、空白はスキップされます。

std::getline一度に入力行を取得するために使用できます。

#include <algorithm>
#include <iostream>
#include <cctype>
#include <string>

using namespace std;

int main()
{
    cout << " Enter one line of text: ";
    string s;
    if(getline(cin, s))
    {
        size_t count = count_if(s.begin(), s.end(), 
               [](unsigned char ch) { return islower(ch); });
        cout << count << "\n";
    }
}
于 2012-11-25T01:50:42.193 に答える
2

無限ループを作成します。

while (text != '\n') {
    ...
}

text'\n' 以外の何かが発生した場合 (文字の誤称のように) は永遠に続きます。一般的なガイドラインとして、ループを作成するときはいつでも、ループの本体が何らかの形でループの終わりに向かって進行し、ループの終わりに到達したことを確認する必要があります (もちろん、無限ループを作成するつもりがない場合)。 lop) おそらく、これを取り除きwhile (...)、本体だけを保持したいだけでしょう。

外側のループには、終了する 2 つの条件が必要であることに注意してください。

  1. 行の終わりに到達すると、終了する必要があります。
  2. 入力の最後に到達すると終了する必要があります。これは必ずしも改行で終了するとは限りません。

ループを書くとしたら、次のようになります。

for (std::istreambuf_iterator<char> it(std::cin), end; it != end && *it != '\n'; ++it) {
    // do something with the `char` obtained from `*it`
}

islower()正の値が(または の他の関数のいずれか) に渡されることを確認する必要があることも注目に値し<cctype>ます。を呼び出したときの未定義の動作。この問題を回避する方法は、関数に渡す前に をに変換することです。 のビット パターンは のビット パターンと同じです(が 型であると仮定します)。charüislower('ü')charunsigned char<cctype>static_cast<unsigned char>(c)ccchar

whilea を読み取る -loopの元のアプローチに固執するとchar、基本的なループは次のようになります。

while (std::cin.get(text) && text != '\n') {
    if (std::islower(std::static_cast<unsigned char>(text))) {
        ++count;
    }
}

一般に、do ... while-loops が実稼働コードに残ることはめったになく、これも例外ではありませんchar。正常に読み取れる場合にのみ、ループに入ります。改行は小文字にならないので、条件に直接入れることもできます。ASCII 文字は機能しますが、コードを確実にするために、壊れないようにstd::islower(text)キャストを追加しました。unsigned char最後に、変数をインクリメントするための C++ のイディオムは、皮肉なことに、プリインクリメント++countですcount++。主な用途は、プリインクリメントが適用される型が完全に自明でない場合に、プリインクリメントがより効率的であることです。C++ はインクリメントされる多くの反復子を使用するため、プリインクリメントを使用するのが一般的です。

于 2012-11-25T01:49:07.833 に答える