【问题标题】:Is there a way to request a certain location of a text file to be read in C++?有没有办法请求在 C++ 中读取文本文件的某个位置?
【发布时间】:2017-04-20 07:27:14
【问题描述】:

我正在使用一个两行的文本文件。每行都有几千个数字(有符号双打)。所以它看起来像这样:

X.11   X.12   X.13   ...
X.21   X.22   X.23   ...

对于程序的每个循环,我想从每一行读取一个数字。因此,对于循环的第一次迭代,它将是 X.11X.21,对于第二次迭代,X.12X.22 等等。我不需要存储这些值。

预期输出:

X.11  X.21
X.12  X.22
X.13  X.23

如何在 C++ 中做到这一点? 我通常使用fstream 读取文件,并使用std::getline(file, line) 逐行读取文件。如何从每一行读取一个数字?

【问题讨论】:

  • X.11 & X.12 应该是 X.11 & X.21??
  • 你可以做你想做的事,但编写一个程序来转置整个文件然后逐行读取它可能更容易。
  • 你的号码长度和行长是固定的吗?在这种情况下,您可以计算下一列的开始位置并使用seekg(询问原因是示例看起来像...)
  • 只是说:以二进制形式预处理此文件可能很有用(固定偏移量)
  • “对于我程序的每个循环,我想从每一行中读取一个数字。” 但是您在第一次迭代中尝试读取 X.11X.12 ?这两个数字不是包含在同一行吗?您能否添加一些伪代码来阐明您真正想要实现的目标?看起来您只是想读取每行的前两个数字,这有点简单。

标签: c++ file text fstream


【解决方案1】:

我不需要存储这些值。

当然,但是如果你这样做了,比如在两个双精度数组中,那么你的循环将是微不足道的,并且比常规磁盘读取快得多。两个数千个双精度数组的内存使用量可能比您想象的要少。 1 Mb 的 RAM 可以包含 131072 个八字节双精度。

【讨论】:

    【解决方案2】:

    我假设您需要: 我想从每一行中读取一个数字。
    否则评论我;我将删除答案。

    使用 2 个并行流读取 文件

    std::ifstream input_file_stream_1( "file" );
    std::ifstream input_file_stream_2( "file" );
    
    std::string line_1;
    std::string line_2;
    std::string ignore;
    std::getline( input_file_stream_2, ignore );    // ignore the whole first line
    
    for( ; input_file_stream_1 >> line_1 && input_file_stream_2 >> line_2; ){
        std::cout << line_1 << " and " << line_2 << '\n';
    }
    
    input_file_stream_1.close();
    input_file_stream_2.close();  
    

    输入:

    X.11   X.12   X.13   ...
    X.21   X.22   X.23   ...
    

    输出:

    X.11 and X.21
    X.12 and X.22
    X.13 and X.23
    ... and ...
    

    它是如何工作的?
    由于您的文件只有 2 行,所以我在同一个文件上使用了两个 input_stream。其中一个用于第一行,另一个用于第二行。但在进入 for 循环之前。 input_file_stream_2 读取第一行并且不需要使用它,因为input_file_stream_1 想要读取此内容。所以在忽略那一行(第一行)之后。 input_file_stream_1 有第 1 行,input_file_stream_2 有第 2 行。现在你有两行与 to 流。在 for 循环(或 while )中,您可以通过 &gt;&gt; 运算符提取每个文本


    std::regex库:

    std::ifstream input_file_stream( "file" );
    
    std::string line_1;
    std::string line_2;
    std::getline( input_file_stream, line_1 );
    std::getline( input_file_stream, line_2 );
    
    std::regex regex( R"(\s+)" );
    std::regex_token_iterator< std::string::iterator > begin_1( line_1.begin(), line_1.end(), regex, -1 ), end_1;
    std::regex_token_iterator< std::string::iterator > begin_2( line_2.begin(), line_2.end(), regex, -1 ), end_2;
    
    while( begin_1 != end_1 && begin_2 != end_2 ){
        std::cout << *begin_1++ << " and " << *begin_2++ << '\n';
    }
    
    input_file_stream.close();  
    

    输出:(同上)

    X.11 and X.21
    X.12 and X.22
    X.13 and X.23
    ... and ...
    

    注意:
    这样做的方法不止一种

    【讨论】:

    • 谢谢。你能解释一下第一种方法中的for循环吗?没有迭代器如何工作?
    • @Hadi 是的。我会做的
    【解决方案3】:

    如果您已经使用std::getline(file, line) 阅读了该行,则可以获取您得到的字符串,并将其标记为char* p = strtok (yourline, " ");,然后 *p 将在第一行中生成 X.11,而对于下一行,您只需再次致电strtok

    【讨论】:

      【解决方案4】:

      对于 fstream,您可以使用 tellgseekg 来存储和恢复流中的位置。但是,我还没有验证它们是否可以很好地与格式化输入一起使用。

      假设您不想将结果存储在内存中并且只有两行,另一种解决方案是打开文件两次 - 并将其视为从两个不同文件中读取行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-10
        • 2015-08-03
        • 2010-11-18
        • 1970-01-01
        • 2022-08-04
        • 1970-01-01
        • 1970-01-01
        • 2021-10-31
        相关资源
        最近更新 更多