【问题标题】:C++ Read file line by line then split each line using the delimiterC++ 逐行读取文件,然后使用分隔符分割每一行
【发布时间】:2010-10-11 22:14:01
【问题描述】:

我想逐行读取一个txt文件,读取每一行后,我想根据选项卡“\t”分割该行并将每个部分添加到结构中的一个元素中。

我的结构是 1*char 和 2*int

struct myStruct
{
    char chr;
    int v1;
    int v2;
}

其中 chr 可以包含多个字符。

一行应该是这样的:

randomstring TAB number TAB number NL

【问题讨论】:

  • 一个 char 不能包含多个字符,您可能是指 char* 也是 v1 和 2 的用途对我来说并不完全清楚。
  • @Mark 他可能正在忙着编辑……
  • 有什么代码可以给我们看吗?你能告诉我们v1v2 是什么吗?有限制吗?
  • @sikas:好的,你已经把伪代码搞定了。那么是什么阻止您将其翻译成 C++ 呢?
  • @sikas 那么现在是重新学习 C++ 的好时机。否则,您是否只是希望这里有人为您完成所有工作?

标签: c++ readfile


【解决方案1】:

尝试:
注意:如果 chr 可以包含超过 1 个字符,则使用字符串来表示。

std::ifstream file("plop");
std::string   line;

while(std::getline(file, line))
{
    std::stringstream   linestream(line);
    std::string         data;
    int                 val1;
    int                 val2;

    // If you have truly tab delimited data use getline() with third parameter.
    // If your data is just white space separated data
    // then the operator >> will do (it reads a space separated word into a string).
    std::getline(linestream, data, '\t');  // read up-to the first tab (discard tab).

    // Read the integers using the operator >>
    linestream >> val1 >> val2;
}

【讨论】:

    【解决方案2】:

    除非您也打算将此结构用于 C,否则我会将预期的 char* 替换为 std::string。

    接下来,由于我打算能够从流中读取它,我将编写以下函数:

    std::istream & operator>>( std::istream & is, myStruct & my )
    {
        if( std::getline(is, my.str, '\t') )
           return is >> my.v1 >> my.v2;
    }
    

    以 str 作为 std::string 成员。这将写入您的结构,使用制表符作为第一个分隔符,然后任何空白分隔符都将在接下来的两个整数之前执行。 (你可以强制它使用标签)。

    要逐行阅读,您可以继续阅读这些内容,或者先将行读入字符串,然后将字符串放入 istringstream 并调用上述内容。

    您需要决定如何处理失败的读取。上述任何失败的读取都会使流处于失败状态。

    【讨论】:

      【解决方案3】:
      std::ifstream in("fname");
      while(in){
          std::string line;
          std::getline(in,line);
          size_t lasttab=line.find_last_of('\t');
          size_t firsttab=line.find_last_of('\t',lasttab-1);
          mystruct data;
          data.chr=line.substr(0,firsttab).c_str();
          data.v1=atoi(line.substr(firsttab,lasttab).c_str());
          data.v2=atoi(line.substr(lasttab).c_str());
      }
      

      【讨论】:

      • 请查找为什么不使用 in 作为循环的条件。
      【解决方案4】:

      我在遵循这里的一些建议时遇到了一些困难,因此我发布了一个完整的示例,该示例在制表符分隔的文件上重载结构的输入和输出运算符。作为奖励,它还从stdin 或通过命令参数提供的文件获取输入。

      我相信这在遵守运算符语义的同时尽可能简单。


      pairwise.h

      #ifndef PAIRWISE_VALUE
      #define PAIRWISE_VALUE
      
      #include <string>
      #include <iostream>
      
      struct PairwiseValue
      {
          std::string labelA;
          std::string labelB;
          float value;
      };
      
      std::ostream& operator<<(std::ostream& os, const PairwiseValue& p);
      
      std::istream& operator>>(std::istream& is, PairwiseValue& p);
      
      #endif
      

      pairwise.cc

      #include "pairwise.h"
      
      std::ostream& operator<<(std::ostream& os, const PairwiseValue& p)
      {
          os << p.labelA << '\t' << p.labelB << '\t' << p.value << std::endl;
          return os;
      }
      
      std::istream& operator>>(std::istream& is, PairwiseValue& p)
      {
          PairwiseValue pv;
      
          if ((is >> pv.labelA >> pv.labelB >> pv.value))
          {
              p = pv;
          }
      
          return is;
      }
      

      test.cc

      #include <fstream>
      #include "pairwise.h"
      
      int main(const int argc, const char* argv[])
      {
          std::ios_base::sync_with_stdio(false); // disable synch with stdio (enables input buffering)
      
          std::string ifilename;
          if (argc == 2)
          {
              ifilename = argv[1];
          }
      
          const bool use_stdin = ifilename.empty();
          std::ifstream ifs;
          if (!use_stdin)
          {
              ifs.open(ifilename);
      
              if (!ifs)
              {
                  std::cerr << "Error opening input file: " << ifilename << std::endl;
                  return 1;
              }
          }
      
          std::istream& is = ifs.is_open() ? static_cast<std::istream&>(ifs) : std::cin;
      
          PairwiseValue pv;
      
          while (is >> pv)
          {
              std::cout << pv;
          }
      
          return 0;
      }
      

      编译

      g++ -c pairwise.cc test.cc
      g++ -o test pairwise.o test.o
      

      用法

      ./test myvector.tsv
      cat myvector.tsv | ./test
      

      【讨论】:

        猜你喜欢
        • 2017-03-25
        • 1970-01-01
        • 2020-11-21
        • 1970-01-01
        • 2012-10-21
        • 1970-01-01
        • 2015-05-21
        • 1970-01-01
        • 2021-09-27
        相关资源
        最近更新 更多