【问题标题】:Processing lines from one text file to another处理从一个文本文件到另一个文件的行
【发布时间】:2013-09-27 15:54:05
【问题描述】:

我要感谢所有帮助我解决问题的人。我终于可以按出生年份排列数据了!非常感谢。如果有人可以帮助我解决最后一个问题,那就太好了

如果我在文本文件中有如下所示的行:

1    4:48:08   Orvar Steingrimsson                 1979   30 - 39 ara      IS200 
2    4:52:25   Gudni Pall Palsson                  1987   18 - 29 ara      IS870 

我怎样才能将此数据输出到一个新的文本文件中,但只列出三件事:年份 - 名称 - 时间......这样这两行看起来像这样:

1979   Orvar Steingrimsson   4:48:08
1987   Gudni Pall Palsson    4:52:25

我的猜测是这样的:

ifstream in("inputfile.txt");
ofstream out("outputfile.txt");
int score, year;
string name, time, group, team;
while (getline(in,str));
in >> score >> time >> name >> year >> group >> team;
//and then do something like this
out << year << name << time << '\n';

但是我有一种感觉,我无法在整个文本文件和所有 200 行中循环。任何提示表示赞赏!谢谢

【问题讨论】:

  • 我不会为此使用 C++
  • 这是什么意思?我刚刚开始了一个 C++ 课程,我们被要求这样做。巨大的任务,今晚到期,我无法得到帮助,因为我在我的大学里一个人都不认识。我知道其他人只是在互相帮助和共享代码。但我必须自己做,遗憾的是,在 C++ 中!
  • 为什么要一一提取第 1 2 3rd..6 行?
  • @P0W 为什么他的while 中间有一个return?为什么他试图在while 循环的中间定义一个函数?我认为我们必须假设这不是真正的代码,因为它不会编译(而且他并没有询问奇怪的编译器错误)。

标签: c++ stream xcode5


【解决方案1】:

“我知道年份总是每行的第 54 到 58 个字符”

所以,考虑一下:

int main ()
{
    ifstream  in("laugavegurinn.txt", ios::in);
    ofstream out("laugavegurinn2.txt");
    string str;
    multimap<int, string> datayear;

    while (getline(in,str)) {
         int year = stoi(str.substr(54, 4));
         datayear.insert(make_pair(year,str)); //use insert function
         // multimap don't have [] operator
           }

    for (auto v : datayear) 
        out << v.second << "\n";

    in.close();
    out.close();
}

【讨论】:

  • 你,我最好的朋友,是救命稻草。尽管为此工作了大约一周并在此站点上提出了无数问题,尝试了多种方法并一遍又一遍地阅读我的 C++ 书,但没有任何效果。直到你出现。真诚的,谢谢你
【解决方案2】:

对于初学者,将这些行读入std::vector&lt;std::string&gt;, 使用std::getline。然后按所需的顺序对它们进行排序。 然后输出它们。所以main基本上变成了三行:

std::vector<Line> data( readLines( inFile ) );
sortByBirthYear( data );
std::copy( data.begin(), data.end(), std::ostream_iterator<std::string>( outFile, "\n" ) );

当然readLinessortByBirth需要写成 好吧,但它们也都相当微不足道。

另外,可能更好的是,您可以定义 带有operator&gt;&gt;operator&lt;&lt;DataLine 类和 一个比较函数 (operator&lt;),然后你只需要:

std::vector<DataLine> data(
    (std::istream_iterator<DataLine>( inFile )),
    (std::istream_iterator<DataLine>()) );
std::sort( data.begin(), data.end() );
std::copy( data.begin(),
           data.end(),
           std::ostream_iterator<std::string>( outFile, "\n" ) );

这就是我会做的,但如果你刚刚开始使用 C++,你可能不会 已经涵盖了必要的基础知识,例如类和运算符 重载。

根据您的代码,我还要添加一件事:永远不要访问 您输入的数据没有先检查输入 成功了。

编辑(仅使用基本功能实现):

如上(但没有Line 类型):

std::vector<std::string> data( readLines( inFile ) );
std::sort( data.begin(), data.end(), orderByBirthYear );
std::copy( data.begin(), data.end(),
           std::ostream_iterator<std::string>( outFile, "\n" ) );

与:

std::vector<std::string>
readLines( std::istream& source )
{
    std::vector<std::string> results;
    std::string line;
    while ( std::getline( source, line ) ) {
        results.push_back( line );
    }
    return results;
}

bool
orderByBirthYear( std::string const& lhs, std::string const& rhs )
{
    return lhs.compare( 54, 4, rhs, 54, 4 ) < 0;
}

但我坚持:这不是一个人应该如何解决它。任何 合理的解决方案将从为您定义一个类开始 数据,并使用它定义所有操作。这表示 不仅定义了class,还定义了运算符重载;如果 你刚刚开始,你可能还没有看到这些 (并且就 课程质量)。

对于其余的,你在正确的轨道上;面向线的 输入,您应该使用getline 阅读。然而在那之后, 该行已从输入中提取;进一步解析它, 你需要用它初始化一个std::istringstream,然后阅读 从此。除了您的输入格式似乎基于 列,所以你可能会使用 substr 函数 std::string 获取各个字段。一旦你有了 他们,你会想要去除前导和尾随空格,并且 可能转换为数字类型(尽管只是排序 年,这不是必需的)。但这一切合乎逻辑 发生在用户定义的 operator&gt;&gt;Data 类中。 (同样,您可以提供一个用户定义的operator&lt;&lt; 来编写 整理出来的数据。通常,orderByBirthYear,上面, 也是一个类。)

【讨论】:

  • 是的,刚刚开始,我们还没有涵盖 sh**。尽管如此,这就是项目。您能帮我理解定义 DataLine 类的意思吗?我知道我需要定义它,就像在 class DataLine { .... 但是然后呢?
  • @MagnusOttiBenediktsson 我无法描述如何在这个论坛上编写课程;太多了。我已经编辑了一个粗略的草稿,说明如何在没有任何额外课程的情况下做到这一点,但这不是在现实生活中做到这一点的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-23
  • 1970-01-01
  • 2014-02-24
  • 2016-03-26
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
相关资源
最近更新 更多