【问题标题】:Reading Data from a text file with fstream使用 fstream 从文本文件中读取数据
【发布时间】:2015-09-02 12:09:33
【问题描述】:

我在读取和处理数据文件时遇到了一些问题。我将从数据文件中创建 3 个类别。前两个类别均基于保证不会拆分的数据。第三类可以拆分多次。
下面的代码是我目前正在使用的过程。当每个段只是一个部分(例如segment3 =“dog”)时,这可以完成工作,但我需要应用程序能够处理segment3的可变数量的部分(例如segment3 =“Golden Retriever”或“半金半哈巴狗”)。 segment1 和 segment2 保证是完整的,不会在空格之间分割。我理解为什么我的代码会跳过任何额外的空格(而不是记录“Golden Retriever”,它只会记录“Golden”。我不知道如何操作我的代码,以便它理解在 segment2 之后的行中的任何内容都是段 3 的一部分。

 ______________________________
// This is the structure of the data file. It is a .txt
China 1987 Great Wall of China.
Jordan 1985 Petra.
Peru 1983 Machu Picchu. 
// End of Data file. Code below.
________________________________

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int main()
{
    ifstream myFile("data.txt");
    string segment1;
    string segment2;
    string segment3;
    vector <string> myVec;

    while(myFile >> segment1 >> segment2 >> segment3)
    {
        vector <string> myVec; // 
        myVec.push_back(segment1); myVec.push_back(segment2); myVec.push_back(segment3); 
    int Value = atoi(myVec[1].c_str()); // should print int value prints zero with getline 
    }

    return 0;
}

我搜索了 stackoverflow 和互联网,发现了一些想法,但似乎没有任何方法可以帮助解决我在处理我的代码时遇到的问题。 我最好的想法是放弃我目前读取文件的方法。 1. 我可以使用 getline 将数据解析为向量。 2.我可以将索引0分配给segment1,将索引1分配给segment2。 3. 我可以将索引 3 分配到第 3 段的向量末尾。


Galik 的解决方案帮助我解决了这个问题,但现在我在尝试进行类型转换时遇到了问题。 [int altsegment2 = atoi(segment2.c_str());] 现在总是为零

【问题讨论】:

  • 你想要std::getline
  • 我同意你的想法
  • 你应该从循环中移除第二个vector。它隐藏了真正的vector。并且不要访问向量来转换循环内的数字,当 vector 有一些数据时,在循环之后执行此操作。

标签: c++ file-io c++98


【解决方案1】:

您可以使用std::getline 像这样读取整行的其余部分:

#include <iostream>
#include <fstream>
#include <sstream> // testing
#include <vector>
using namespace std;

int main()
{
    // for testing I substituted this in place
    // of a file.
    std::istringstream myFile(R"~(
    China 1987 Great Wall of China.
    Jordan 1985 Petra.
    Peru 1983 Machu Picchu. 
    )~");

    string seg1;
    string seg2;
    string seg3;
    vector<string> v;

    // reads segments 1 & 2, skips spaces (std::ws), then take
    // the rest of the line into segment3
    while(std::getline(myFile >> seg1 >> seg2 >> std::ws, seg3))
    {
        v.push_back(seg1);
        v.push_back(seg2);
        v.push_back(seg3);
    }

    for(auto const& seg: v)
        std::cout << seg << '\n';

    return 0;
}

输出:

China
1987
Great Wall of China.
Jordan
1985
Petra.
Peru
1983
Machu Picchu. 

【讨论】:

  • 太棒了!这正是我想做的。非常感谢你的帮助。我会尽快将其标记为最佳答案。
  • 不错的答案,保持循环紧凑。为了那些(像我一样)第一次遇到原始字符串文字 R"...()..." 的人的利益,documentation is here
  • 嗨,你能帮我澄清一件事吗?我最初有一些类型转换,但这似乎不再起作用。我已经更新了我的原始帖子以包含该信息。
  • 我也无法使用字符串流进行投射,它也归零。
  • @JohnKraz 你不需要转换。因为segment2 是一个数字,所以只需将变量设为int 而不是stringint segment2;。然后文件操作会将其作为数字读入。
猜你喜欢
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多