4

テキストファイルの最後の10行を印刷するオプションが必要です。このプログラムを使用すると、テキストファイル全体を読み取ることができましたが、テキストファイルが保存されている配列を操作する方法がわかりません。何か助けがありますか?

// Textfile output
#include<fstream>
#include<iostream>
#include<iomanip>
using namespace std;

int main() {
    int i=1;
    char zeile[250], file[50];
    cout << "filename:" << flush;
    cin.get(file,50);                          ///// (1)
    ifstream eingabe(datei , ios::in);          /////(2)
    if (eingabe.good() ) {                       /////(3)           
       eingabe.seekg(0L,ios::end);               ////(4)
       cout << "file:"<< file << "\t"
            << eingabe.tellg() << " Bytes"       ////(5)
            << endl;
       for (int j=0; j<80;j++)
           cout << "_";
           cout << endl;
       eingabe.seekg(0L, ios::beg);              ////(6)
       while (!eingabe.eof() ){                  ///(7)
             eingabe.getline(zeile,250);         ///(8)
             cout << setw(2) << i++
                  << ":" << zeile << endl;
             }      
           }
    else
        cout <<"dateifehler oder Datei nicht gefunden!"
             << endl;
            
             return 0;
    }
4

6 に答える 6

5

これを試して:

#include <list>
#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>

// 演算子を使用して行を読み取る方法を知っているクラス >>

struct Line
{
    std::string theLine;
    operator std::string const& () const { return theLine; }
    friend std::istream& operator>>(std::istream& stream, Line& l)
    {
        return std::getline(stream, l.theLine);
    }
};

// 最後の n 行だけを保存する循環バッファ。

class Buffer
{
    public:
        Buffer(size_t lc)
            : lineCount(lc)
        {}
        void push_back(std::string const& line)
        {
            buffer.insert(buffer.end(),line);
            if (buffer.size() > lineCount)
            {
                buffer.erase(buffer.begin());
            }
        }
        typedef std::list<std::string>      Cont;
        typedef Cont::const_iterator        const_iterator;
        typedef Cont::const_reference       const_reference;
        const_iterator begin()  const       { return buffer.begin(); }
        const_iterator end()    const       { return buffer.end();}

    private:
        size_t                      lineCount;
        std::list<std::string>      buffer;
};    

// 主要

int main()
{
    std::ifstream   file("Plop");
    Buffer          buffer(10);

    // Copy the file into the special buffer.
    std::copy(std::istream_iterator<Line>(file), std::istream_iterator<Line>(),
            std::back_inserter(buffer));

    // Copy the buffer (which only has the last 10 lines)
    // to std::cout
    std::copy(buffer.begin(), buffer.end(),
            std::ostream_iterator<std::string>(std::cout, "\n"));
}
于 2011-04-26T19:48:32.247 に答える
2

基本的に、ファイルの内容を配列に保存していません。次のサンプルは、有利なスタートを提供します。

#include <iostream>
#include <vector>
#include <string>

int main ( int, char ** )
{
    // Ask user for path to file.
    std::string path;
    std::cout << "filename:";
    std::getline(std::cin, path);

    // Open selected file.      
    std::ifstream file(path.c_str());
    if ( !file.is_open() )
    {
        std::cerr << "Failed to open '" << path << "'." << std::endl;
        return EXIT_FAILURE;
    }

    // Read lines (note: stores all of it in memory, might not be your best option).
    std::vector<std::string> lines;
    for ( std::string line; std::getline(file,line); )
    {
        lines.push_back(line);
    }

    // Print out (up to) last ten lines.
    for ( std::size_t i = std::min(lines.size(), std::size_t(10)); i < lines.size(); ++i )
    {
        std::cout << lines[i] << std::endl;
    }
}

ファイル全体をメモリに格納するのは避けた方が賢明なので、最後の 2 つのセグメントを次のように書き直すことができます。

// Read up to 10 lines, accumulating.
std::deque<std::string> lines;
for ( std::string line; lines.size() < 0 && getline(file,line); )
{
    lines.push_back(line);
}

// Read the rest of the file, adding one, dumping one.
for ( std::string line; getline(file,line); )
{
    lines.pop_front();
    lines.push_back(line);
}

// Print out whatever is left (up to 10 lines).
for ( std::size_t i = 0; i < lines.size(); ++i )
{
    std::cout << lines[i] << std::endl;
}
于 2011-04-26T18:56:22.590 に答える
1

eof() 関数はあなたがすることをしません.100万人の他のC++初心者がそうすると思っているようです. 次の読み取りが機能するかどうかは予測しません。C++ では、他の言語と同様に、読み取り前の入力ストリームの状態ではなく、各読み取り操作の状態を確認する必要があります。したがって、正規の C++ 読み取り行ループは次のとおりです。

while ( eingabe.getline(zeile,250) ) {
    // do something with zeile
}

また、 を読み込んstd::stringで、その 250 値を取り除く必要があります。

于 2011-04-26T18:59:11.543 に答える
0
  1. サイズが 10 の文字列の配列があります。
  2. 最初の行を読み取り、配列に格納します
  3. アレイがいっぱいになるまで読み続けます
  4. 配列がいっぱいになったら、最初のエントリを削除して、新しい行を入力できるようにします。ファイルの読み取りが完了するまで、手順 3 と 4 を繰り返します。
于 2011-04-26T18:54:19.500 に答える
0

ここで提案されたアプローチを調査し、すべてをブログ投稿で説明します。より良い解決策がありますが、最後までジャンプして、必要なすべての行を保持する必要があります。

std::ifstream hndl(filename, std::ios::in | std::ios::ate);
// and use handler in function which iterate backward
void print_last_lines_using_circular_buffer(std::ifstream& stream, int lines)
{
    circular_buffer<std::string> buffer(lines);

    std::copy(std::istream_iterator<line>(stream),
              std::istream_iterator<line>(),
              std::back_inserter(buffer));

    std::copy(buffer.begin(), buffer.end(),
            std::ostream_iterator<std::string>(std::cout));
}
于 2019-03-11T14:22:51.933 に答える
0

10 個のスロットを持つ循環バッファーを実行し、ファイル行を読み取りながら、それらをこのバッファーに入れます。ファイルを終了したら、position++ を実行して最初の要素に移動し、それらをすべて出力します。ファイルが 10 行未満の場合は、NULL 値に注意してください。

于 2011-04-26T18:51:26.797 に答える