0

コマンドラインからファイルを読み込み、文字を配列に読み込み、文字の個性を数え、結果を出力しようとしています。コードはエラーなしでコンパイルされますが、個々の文字数は大きなファイルの場合よりもはるかに多く、小さなファイルの場合はまったくカウントされません。

#include <iostream>
#include <fstream>
#include <string.h> 
#include <cctype> 
#include <algorithm>

using namespace std;


int main(int argc, char **argv){ 
if(argc !=2){
     cout << "usage: " << argv[0] << " <filename>\n";
}
else{
     ifstream myfile (argv[1]); 
     if(!myfile.is_open())  //check to see if file is opened.
        cout << "Can not open your file\n";
    else{
        static int array[26];  //stores the frequency of letters.
        char t;       
    while(!myfile.eof()){     
        while(myfile.get(t)){
            if(isupper(t)){    
                int i = 0;
                do{
                    array[tolower(t)-'a']++;
                    i++;
                }
            while(i < 26);
            }
        }
    int x = 0;
    while(x < 26){
        cout << 'a' + x << ":" << array[x] << endl;
        x++;
    }
    }
    }
    }
return 0;
}
4

2 に答える 2

1

問題はmyfile.get(t)、ストリームから文字を抽出し、それをに取り込むことですt。ここで、読み取られた文字が大文字の場合は、配列を26回繰り返し、小文字の数を増やします。あなたはそれを一度だけする必要があります。

また、入力ストリームで非英字を処理する必要があります。

while(!myfile.eof()){     
    myfile.get(t);
    if(isalpha(t) { // process only alphabets.
        if(isupper(t)) // convert upper case to lower case
            t = tolower(t);
        array[t-'a']++; // increment the count
    }
}
于 2012-10-11T03:33:25.933 に答える
1

これはコマンド ラインでファイル名を受け入れません (標準入力を処理するだけです) が、もう少し単純な一般的なアプローチのヒントになるかもしれません。

#include <ctype.h>
#include <iostream>
#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>

int main() {
    std::vector<size_t> freqs(26);

    std::for_each(std::istream_iterator<char>(std::cin), 
        std::istream_iterator<char>(),
        [&](char ch) { if(isalpha(ch)) ++freqs[tolower(ch)-'a']; });

    for (int i=0; i<26; i++)
        std::cout << (char)('a'+i) << ":" << freqs[i] << "\n";

    return 0;
}
于 2012-10-11T04:27:24.890 に答える