4

我希望可以选择打印出 textfile 的最后 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

Basically, you are not saving the file contents to any array. The following sample will give you a head start:

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

It would probably be wiser to avoid storing the whole file into memory, so you could re-write the last 2 segments this way:

// 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() 函数并没有像你那样做,而且似乎有一百万其他 C++ 新手认为它会做。它不能预测下一次读取是否有效。在 C++ 中与任何其他语言一样,您必须检查每个读取操作的状态,而不是读取之前输入流的状态。所以规范的 C++ 读取行循环是:

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

此外,您应该阅读 a std::string,并摆脱 250 的值。

于 2011-04-26T18:59:11.543 回答
0

Do a circular buffer with 10 slots and while reading the file lines, putting them into this buffer. When you finish thr file, do a position++ to go to the first element and print them all. Pay attention for null values if the file has less than 10 lines.

于 2011-04-26T18:51:26.797 回答
0
  1. Have an array of strings with size 10.
  2. Read the first line and store into the array
  3. Continue reading till the array is full
  4. Once the array is full delete the first entry so that you can enter new line Repeate step 3 and 4 till the file is finished reading.
于 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 回答