【问题标题】:Reading in lines from a text file in reverse order c++以相反的顺序从文本文件中读取行c ++
【发布时间】:2015-01-03 07:21:00
【问题描述】:

我需要找到一种从文件中读取最后 6 行数据的方法。

例如,如果我有 1 2 3 4 5 6 7 8 9 10

我需要阅读才能获得 10、9、8、7、6、5、4。

然后需要将这些放入变量或字符串中以便稍后输出。目前我已经设法读入文件的最后一行,但我不知道如何读入其他 5 个数字。

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

using namespace std; 

int main()
{
    std::ifstream in("test.txt");

    if (in.is_open())
    {
        std::vector<std::string> lines_in_reverse;

        std::string line, line2;

        while (std::getline(in, line))
        {
            // Store the lines in reverse order.
            lines_in_reverse.insert(lines_in_reverse.begin(), line);



        }
        cout << line << endl;
        while (std::getline(in, line2))
        {
            // Store the lines in reverse order.
            lines_in_reverse.insert(lines_in_reverse.begin(), line2);



        }
        cout << line2 << endl;
    }

    cin.get();
    return 0;
}

任何人都可以建议一种方法吗?我不知道有什么功能或方法可以提供帮助。

编辑

此方法输出文件中的最后 6 个数字,但是它们是倒数的,我需要一种方法来反转它们并消除它打印出来的空白。

我不确定如何使用 reverse 以及需要哪些参数 - http://en.cppreference.com/w/cpp/algorithm/reverse

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    char x;
    ifstream f("test.txt", ios::ate);
    streampos size = f.tellg();
    for (int var = 1; var <= size; var++){
        f.seekg(-var, ios::end);
        f.get(x);
        reverse(x);
        cout << x; 
    }
    cin.get();
    return 0;
}

很多回复告诉我如何使用向量而不是最后 6 个数字来反转文本文件,这是我需要的唯一信息。

问候

【问题讨论】:

  • 按顺序读取行,并按顺序将它们添加到向量中,以相反的顺序打印它们。请记住,您可以从头到尾以及从尾到头对向量进行迭代。
  • @JoachimPileborg 这行得通,但我也想知道是否有更直接的方法可以使用 fstream 库来做到这一点。我知道一种方法是直接操作文件指针,但这不是很优雅。考虑当你有一个大文件(几个演出)。存储整个文件将完全浪费内存。
  • 我会试一试并发布它是否有效,谢谢
  • 另外,如果你需要使用反转矢量而不是仅仅打印它,那么it's very easy to reverse it
  • @1110101001 您无法以简单的方式可靠地反向读取文本文件。然后你必须逐个字符地读取,处理换行符,附加到字符串并附加到集合中。从头读取,反转向量并打印向量是四行 C++ 代码(不包括声明)。

标签: c++ io fstream


【解决方案1】:

存储您读入的所有行并不是一个好主意,因为可能存在例如十亿行。

您只需要存储最后 6 个。

以下代码旨在以相反的顺序生成这些行,因为问题表明这是一项要求:

#include <iostream>
#include <string>
#include <deque>
using namespace std;

auto main() -> int
{
    string          line;
    deque<string>   last_lines;
    while( getline( cin, line ) )
    {
        if( last_lines.size() == 6 )
        {
            last_lines.pop_back();
        }
        last_lines.push_front( line );
    }

    for( auto const& s : last_lines )
    {
        cout << s << endl;
    }
}

这里的输出不完全是问题的例子

10, 9, 8, 7, 6, 5, 4

因为那是 7 行,与第一句话中的 6 行相矛盾。

【讨论】:

    【解决方案2】:

    如何读取文件并将其反向打印,只需三个代码语句(不包括声明和其他样板文件):

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    
    void read_and_print_reverse_n(std::istream& is, const int n)
    {
        std::vector<std::string> v;
    
        // This call reads all whitespace-delimited "words" from the input stream
        // and appends them to the vector
        std::copy(std::istream_iterator<std::string>(is),
                  std::istream_iterator<std::string>(),
                  std::back_inserter(v));
    
        // Output the last `n` lines from the input
        for (const auto i = v.rbegin();
             i < v.rend() && i < v.rbegin() + n;
             ++i)
        {
            std::cout << *i << '\n';
        }
    }
    
    int main()
    {
        read_and_print_reverse_n(std::cin, 6);
    }
    

    参考文献

    【讨论】:

    • 我不明白这两行。将该代码格式化为一行并不是什么大问题。另外,我认为这应该是评论,而不是答案。
    • @Cheersandhth.-Alf 也许我应该说“两个陈述”?对于 OP 想要的,这基本上是可能的最短和最简单的解决方案。它只用这两个语句就可以满足 OP 的所有要求,而且它可以是“C++-ish”。
    • 也许你只是读了标题而不是第一行,“我需要找到一种方法来读取文件中最后 6 行数据”。因为这个答案只是关于如何做一件事的评论。
    • @PapaSmurf 使用“正常”for 循环更新答案以仅打印 n 行,其中 n 可以是您想要的任何数字。
    【解决方案3】:

    我认为答案here 将解决您将线条存储在向量中并从末尾迭代向量的目的。

    当您正在寻找一些直接的方法来读取文件时,您可以使用 seekg 和 tellg 从末尾开始逐个字符地读取文件。

        #include <iostream>
        #include <fstream>
        #include <string>
        #include <vector>
        using namespace std;
        int main()
        {
            char x;
            ifstream f("filename.txt",ios::ate);
            streampos size = f.tellg();
            for(int var=1;var<=size;var++){
                f.seekg(-var,ios::end);
                f.get(x);
                printf("%c",x);
            }
            return 0;
        }
    

    您还可以计数 \n 以跟踪从末尾读取的行数。

    【讨论】:

    • 如果数字超过一位,这会向后读取数字。有办法解决吗?
    • @PapaSmurf 由于字符以反向方式打印,您可以存储字符串并使用 c++ 算法库中的 reverse 函数打印其反向。我所说的方法的主要优点是它使您免于读取整个文件,并且只读取从最后一个不同向量开始的所需行。
    • 我一定会试试的
    • @Richik_Jaiswal 嗨,请参阅有关使用反向函数和处理空格的查询的更新。
    • int main() { char x; string s; ifstream f("test.txt",ios::ate); streampos size = f.tellg(); for(int var=1;var&lt;=size;var++){ f.seekg(-var,ios::end); f.get(x); if(x!='\n') { s+=x; } if(x=='\n' || var==size) { cout&lt;&lt;"\n"; reverse(s.begin(),s.end()); cout&lt;&lt;s; s=""; } } return 0; } 这应该可以满足您的所有需求。
    猜你喜欢
    • 2011-01-19
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多