C++:使用 getline() 从外部文件读取的后续问题。如何获取文件数据的子集?

发布于 2024-10-17 15:24:39 字数 2346 浏览 6 评论 0原文

我需要从外部文件读取数字并将它们存储在整数向量中。我现在能做到这一点要感谢 Howard Hinnant 和 wilhelmtell,他们耐心地帮助我找出了昨天我的编码无法工作的原因。

我一直在试图弄清楚如何将附加功能合并到代码中,但我已经耗尽了我对流的知识,并且希望得到一些建议。

我希望能够处理包含多组数据的文件。是否可以仅将文件中的某些数据提取到向量中?我想最终得到几个包含来自文件不同部分的数据的向量。我在网上搜索过,但没有看到任何提及这一点。

这是代码以及我想要从中获取数据的文件示例(我们称之为“测试”)。


编辑: 我根据 CashCow 的建议编辑了代码。我现在可以从数据文件中获取一个块。但我不知道如何获得我想要的块。如果我按原样运行代码,我会得到一个包含元素 2,5,8 的向量(这不是我想要的)。为了获得 vectorTwo (在我制作的示例中为 4,5,6),我尝试在 while 语句周围添加此内容:

if( line == "vectorTwo" )
{
      // The while statement and its contents
}

它不起作用。我没有从运行代码中得到任何结果(尽管它已编译)。谁能看出问题是什么吗?我想我可以使用这个语句来搜索我需要的数据块的标题。


//以下是示例文件的内容

vectorOne // 一个向量的数据子集的标识符

'1' '2' '3'

vectorTwo // 我将如何得到这一个向量?或者任何其他向量?

'4' '5' '6'

vectorThree // 另一个向量的数据子集的标识符

'7' '8' '9'

// 代码: '\'' 字符是行分隔符。第一个 ' 之前的所有内容都会被忽略,然后直到下一个 ' 之前的所有内容都是数字的一部分。这将继续,直到逻辑失败(文件结尾)。我怎样才能让它停在数据块的末尾呢?

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

int main()
{
    std::string line;
std::string block;         // Edited, from CashCow
    const std::string fileName = "test.dat";  

    std::ifstream theStream( fileName.c_str() ); 

    if( ! theStream )
          std::cerr << "Error opening file test.dat\n";

    std::vector<int> numbers;  // This code is written for one vector only. There would be three vectors for the example file I provided above; one for the vectorOne data in the file, and so on.

    while (true)
    {
        // get first '
        std::getline(theStream, line, '\'');
        // read until second '
        std::getline(theStream, line, '\'');
        std::istringstream myStream( line );

        std::getline( theStream, block, '\n' );  // Edited, from CashCow
        std::istringstream blockstream( block ); // Edited, from CashCow
        std::getline(blockstream, line, '\'');   // Edited, from CashCow


        int i;
        myStream >> i;
        if (myStream.fail())
            break;
        numbers.push_back(i);
    }
    std::copy(numbers.begin(), numbers.end(),
              std::ostream_iterator<int>(std::cout, "\n"));
}

I need to read in numbers from an external file and store them in a vector of ints. I can do this now thanks to Howard Hinnant and wilhelmtell, who patiently helped figure out why my coding was not working yesterday.

I have been trying to figure out how to incorporate an additional feature into the code, but I have exhausted my knowledge of streams and would appreciate some advice.

I want to be able to deal with files containing many sets of data. Is it possible to extract only certain data from the file into a vector? I want to end up with several vectors that contain data from different parts of the file. I searched online, but have not seen any mention of this.

Here's the code plus an example of a file (let's call it "test") that I want to get data from.


Edit: I edited the code based on CashCow's advice. I can now get a block out of the data file. But I don't know how to get the block I want. If I run the code as it is, I get a vector that contains the elements 2,5,8 (this is not what I want). To get vectorTwo (4,5,6 in the example I made), I tried adding this around the while statement:

if( line == "vectorTwo" )
{
      // The while statement and its contents
}

It did not work. I did not get any results from running the code (it compiled though). Can anyone see what the problem is? I figured I could use this statement to search for the header for the block of data I need.


//Here are the contents of the example file

vectorOne // Identifier for subset of data for one vector

'1' '2' '3'

vectorTwo // How would I get this one vector? Or any other one vector?

'4' '5' '6'

vectorThree // Identifier for subset of data for another vector

'7' '8' '9'

// Code:
The '\'' character is the line delimiter. Everything is ignored up to the first ' and then everything until the next ' is part of a number. This continue until the logic fails (end of file). How can I get it to stop at the end of a data block instead?

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

int main()
{
    std::string line;
std::string block;         // Edited, from CashCow
    const std::string fileName = "test.dat";  

    std::ifstream theStream( fileName.c_str() ); 

    if( ! theStream )
          std::cerr << "Error opening file test.dat\n";

    std::vector<int> numbers;  // This code is written for one vector only. There would be three vectors for the example file I provided above; one for the vectorOne data in the file, and so on.

    while (true)
    {
        // get first '
        std::getline(theStream, line, '\'');
        // read until second '
        std::getline(theStream, line, '\'');
        std::istringstream myStream( line );

        std::getline( theStream, block, '\n' );  // Edited, from CashCow
        std::istringstream blockstream( block ); // Edited, from CashCow
        std::getline(blockstream, line, '\'');   // Edited, from CashCow


        int i;
        myStream >> i;
        if (myStream.fail())
            break;
        numbers.push_back(i);
    }
    std::copy(numbers.begin(), numbers.end(),
              std::ostream_iterator<int>(std::cout, "\n"));
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

热鲨 2024-10-24 15:24:39

当到达块的开头时,只需将行末尾读入字符串,然后解析该字符串。

std::getline( theStream, block, '\n' );
std::istringstream blockStream( block );
std::getline( blockStream, line, '\'' ); // etc

When you reach the start of a block just read to the end of the line into a string, then parse the string.

std::getline( theStream, block, '\n' );
std::istringstream blockStream( block );
std::getline( blockStream, line, '\'' ); // etc
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文