2009-03-16 8 views
7

私はファイルを読んで、行数を数えると同時に、その中の単語を数えなければならない割り当てに取り組んでいます。 whileループ内でgetlineとstrtokの組み合わせを試しましたが、うまくいきませんでした。テキストファイルを単語に分割する方法は?

ファイル: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; 
} 
+0

あなたは "動作しませんでした" 以上のことを言う必要があります。何が起こったのか、あるいはあなたのプログラムが期待したものとは異なることを特定した事を教えてください。そして、特定の質問をしてください。あなたの宿題をデバッグしたり、書き直したりすることはありません。 – Blorgbeard

+17

次の例のいくつかはどうですか:http://www.codeproject.com/KB/recipes/Tokenizer.aspx非常に効率的でやや優雅です。 String Toolkit Libraryは、C++で複雑な文字列処理を簡単かつ簡単に行います。 –

答えて

0

あなたのwhileループにあなたのcout<<t2<<end;文を移動してみてください。

あなたのコードは基本的に機能するはずです。

その他の方法については、this similar postを参照してください。

0

このような例がインターネット上に掲載されています。ここで私が高校に通っていたときに書いたカウントワードプログラムです。開始点として使用します。私が指摘したいことが他にあります:

std :: stringstream:std :: stringlineを使用して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(); 
} 
+0

こんにちは、 迅速な返信をいただき、ありがとうございました、Blorgbeard、Reed、X-Istence 私は線を解析するだけでなく、線も追跡する必要があります。問題のステートメントは、表示される行番号の単語のリストを作成することです。 –

+0

Ravi:ちょうど私があなたに与えたコードがそこに途中で行くでしょう。私たちはあなたの宿題をするためにここにいません! –

+0

ああいいえ!それは私の意図ではありませんでした。私はちょうど最初の部分で問題を抱えています。それが固定されると、私は自分自身で残りをやろうとします。 –

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; 
} 

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

+0

strtokは使用しないでください。マルチスレッドコードを書く必要があるとすぐにあなたを噛ませるようになるでしょう。標準的なC++の良い置き換えはstd :: istringstreamです。 – Tom

0

あなたはブーストライブラリを使用することができる場合、私は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"; 
    } 
} 
3

私はこれをコンパイルしようとしていないが、ここでブーストを使用するのとほぼ同じくらい簡単である代替だが、余分な依存関係なし。

#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; 
} 
+0

+1それは私がそれをやる方法です。カウンターを挿入するだけで完了です。 – Frank

0
ifstream is {"my_file_path"}; 
vector<string> b {istream_iterator<string>{is},istream_iterator<string>{}}; 

いけない、これを含めることを忘れ:

<iterator> 
関連する問題