8

私は、ファイルを読み取って行数を数え、同時にその中の単語を数えることになっている課題に取り組んでいます。while ループ内で getline と strtok の組み合わせを試しましたが、うまくいきませんでした。

file:example.txt (読み取るファイル)。

こんにちは、うれしい驚きです。
この場所へようこそ。
ここでの滞在が快適でありますように。
(3 行といくつかの単語)。

Readfile.cpp

#include <iostream>
#include <fstream>
#include<string>
using namespace std;
int main()
{
  ifstream in("example.txt");
  int count = 0;

  if(!in)
  {
    cout << "Cannot open input file.\n";
    return 1;
  }

  char str[255];
  string tok;
  char * t2;

  while(in)
  {
    in.getline(str, 255);
    in>>tok;
    char *dup = strdup(tok.c_str());
    do 
    {
        t2 = strtok(dup," ");
    }while(t2 != NULL);
    cout<<t2<<endl;
    free (dup);
    count++;
  }
  in.close();
  cout<<count;
  return 0;
}
4

6 に答える 6

5

ちょうどこれを得た!! 不要なコードをすべて削除しました。

int main()
{    
    ifstream in("example.txt");
    int LineCount = 0;
    char* str = new char[500];

    while(in)
    {
        LineCount++;
        in.getline(str, 255);
        char * tempPtr = strtok(str," ");
        while(tempPtr)
        {
            AddWord(tempPtr, LineCount);
            tempPtr = strtok(NULL," ,.");
        }
    }
    in.close();
    delete [] str;
    cout<<"Total No of lines:"<<LineCount<<endl;
    showData();

    return 0;
}

ところで、元の問題ステートメントは、ユーザー ファイルを受け入れ、すべての単語の行インデックスを作成するインデックス プログラムを作成することでした。

于 2009-03-16T13:29:22.343 に答える
4

私はこれをコンパイルしようとはしていませんが、Boostを使用するのとほぼ同じくらい簡単ですが、余分な依存関係がない代替手段があります。

#include <iostream>
#include <sstream>
#include <string>

int main() {
  std::string line;
  while (std::getline(std::cin, line)) {
    std::istringstream linestream(line);
    std::string word;
    while (linestream >> word) {
      std::cout << word << "\n";
    }
  }
  return 0;
 }
于 2009-03-18T03:20:54.060 に答える
0

cout<<t2<<end;ステートメントを while ループに移動してみてください 。

これにより、コードが基本的に機能するようになります。

他のアプローチについては、この同様の投稿を参照してください。

于 2009-03-16T06:27:55.023 に答える
0

このような例がインターネット上に投稿されています。これは、私が高校生の頃に書いた単語カウント プログラムです。出発点として使用してください。私が指摘したい他のことは次のとおりです。

std::stringstream :you std::getline 行全体を取得し、 std::stringstream を使用してそれを細かく切り刻み、トークン化します。std::getline を使用して行全体を取得し、それを std::string に入力すると、それを std::stringstream に渡すことができます。

繰り返しますが、これは単なる例であり、やりたいことを正確に実行するわけではありません。やりたいことを実行するには、自分で変更する必要があります!

#include <iostream>
#include <map>
#include <string>
#include <cmath>
#include <fstream>

// Global variables
        std::map<std::string, int> wordcount;
        unsigned int numcount;

void addEntry (std::string &entry) {
        wordcount[entry]++;
        numcount++;
        return;
}


void returnCount () {
        double percentage = numcount * 0.01;
        percentage = floor(percentage + 0.5f);

        std::map<std::string, int>::iterator Iter;

        for (Iter = wordcount.begin(); Iter != wordcount.end(); ++Iter) {
                if ((*Iter).second > percentage) {
                        std::cout << (*Iter).first << " used " << (*Iter).second << " times" << std::endl;
                }
        }

}

int main(int argc, char *argv[]) {
        if (argc != 2) {
                std::cerr << "Please call the program like follows: \n\t" << argv[0] 
                        << " <file name>" << std::endl;
                return 1;
        }

        std::string data;

        std::ifstream fileRead;
        fileRead.open(argv[1]);
        while (fileRead >> data) {
                addEntry(data);
        }
        std::cout << "Total words in this file: " << numcount << std::endl;
        std::cout << "Words that are 1% of the file: " << std::endl;
        returnCount();
}
于 2009-03-16T06:30:36.483 に答える
0

ブースト ライブラリを使用できる場合は、boost::tokenizerを使用することをお勧めします。

boost Tokenizer パッケージは、文字列またはその他の文字シーケンスを一連のトークンに分割するための柔軟で使いやすい方法を提供します。以下は、フレーズを単語に分割する簡単な例です。

// simple_example_1.cpp
#include<iostream>
#include<boost/tokenizer.hpp>
#include<string>

int main(){
   using namespace std;
   using namespace boost;
   string s = "This is,  a test";
   tokenizer<> tok(s);
   for(tokenizer<>::iterator beg=tok.begin();beg!=tok.end();++beg){
       cout << *beg << "\n";
   }
}
于 2009-03-16T13:51:30.620 に答える