1

I am currently trying to count the number of words in a file. After this, I plan to make it count the words between two words in the file. For example. My file may contain. "Hello my name is James". I want to count the words, so 5. And then I would like to count the number of words between "Hello" and "James", so the answer would be 3. I am having trouble with accomplishing both tasks. Mainly due to not being exactly sure how to structure my code. Any help on here would be greatly appreciated. The code I am currently using is using spaces to count the words.

Here is my code:

readwords.cpp

string ReadWords::getNextWord()
{
    bool pWord = false;
    char c;
    while((c = wordfile.get()) !=EOF)
    {
        if (!(isspace(c)))
        {
            nextword.append(1, c);
        }

        return nextword;
    }
}

bool ReadWords::isNextWord()
{
    if(!wordfile.eof())
    {
        return true;
    }
    else
    {
        return false;
    }
}

main.cpp

main()
{
    int count = 0;
    ReadWords rw("hamlet.txt");
    while(rw.isNextWord()){
        rw.getNextWord();
                count++;
    }
    cout << count;
    rw.close();
}

What it does at the moment is counts the number of characters. I'm sure its just a simple fix and something silly that I'm missing. But I've been trying for long enough to go searching for some help.

Any help is greatly appreciated. :)

4

5 に答える 5

1

カウントする:

std::ifstream infile("hamlet.txt");
std::size_t count = 0;
for (std::string word; infile >> word; ++count) { }

start と stop の間だけをカウントするには:

std::ifstream infile("hamlet.txt");
std::size_t count = 0;
bool active = false;

for (std::string word; infile >> word; )
{
     if (!active && word == "Hello") { active = true; }
     if (!active) continue;
     if (word == "James") break;
     ++count;
}
于 2012-11-15T17:56:14.570 に答える
1

ファイルを文字ごとに解析するのではなく、単純istream::operator<<()に空白で区切られた単語を読み取ることができます。<<ストリームを返します。これは、ストリームがまだ読み取れる場合にtrueとして評価されます。bool

vector<string> words;
string word;
while (wordfile >> word)
    words.push_back(word);

<iterator>およびユーティリティを使用した一般的な定式化があり<algorithm>ます。これはより冗長ですが、他のイテレータ アルゴリズムで構成できます。

istream_iterator<string> input(wordfile), end;
copy(input, end, back_inserter(words));

次に、単語の数があり、好きなことを行うことができます。

words.size()

"Hello"とを見つけたい場合は、ヘッダーから"James"使用してイテレータをその位置に取得します。find()<algorithm>

// Find "Hello" anywhere in 'words'.
const auto hello = find(words.begin(), words.end(), "Hello");

// Find "James" anywhere after 'hello' in 'words'.
const auto james = find(hello, words.end(), "James");

それらがベクトルにない場合は、;find()が返されます。words.end()説明のためにエラーチェックを無視すると"Hello"、範囲内の包含を調整して、それらの違いを取得することにより、それらの間の単語の数をカウントできます。

const auto count = james - (hello + 1);

は「ランダム アクセス イテレータ」operator-()なので、ここで使用できます。より一般的には、 fromstd::vector::iteratorを使用できます。std::distance()<iterator>

const auto count = distance(hello, james) - 1;

これには、実際に行っていることをより説明できるという利点があります。また、今後の参考のために、この種のコード:

bool f() {
    if (x) {
        return true;
    } else {
        return false;
    }
}

次のように単純化できます。

bool f() {
    return x;
}

xはすでに 用に変換されているためboolif.

于 2012-11-15T18:00:38.740 に答える
0

すべての単語を数えるには:

std::ifstream f("hamlet.txt");
std::cout << std::distance (std::istream_iterator<std::string>(f),
                            std::istream_iterator<std::string>()) << '\n';

2つの単語の間で数えるには:

std::ifstream f("hamlet.txt");
std::istream_iterator<std::string> it(f), end;
int count = 0;
while (std::find(it, end, "Hello") != end)
  while (++it != end && *it != "James")
    ++count;
std::cout << count;
于 2012-11-15T18:03:40.747 に答える
0

これを試してください:行の下

nextword.append(1, c);

追加

continue;
于 2012-11-15T20:35:22.087 に答える
0

「次の単語に戻る」と思います。代わりに「else return nextword;」にする必要があります。そうしないと、char が何であっても、毎回関数 getNextWord から返されます。

string ReadWords::getNextWord()
{
    bool pWord = false;
    char c;
    while((c = wordfile.get()) !=EOF)
    {
        if (!(isspace(c)))
        {
            nextword.append(1, c);
        }

        else return nextword;//only returns on a space
    }
}
于 2012-11-15T17:59:34.620 に答える