如何读取具有特定结构的ASCII文件,每25行重复一次?

时间:2017-09-03 13:15:26

标签: c++ ascii

我有一个ASCII数据文件,它有25行不同的变量,重复。我想在每个结构上进行循环,并且对于每个结构,元素将被添加到数组中。例如,结构中的第一个数字或数字将是从1,2,3 ......等的事件编号,第二个数字将是该事件的时间(以linux时间格式)。这是重复文件的样本。

   1   1481492919 298362 
   1     936    642    618   1346   2648      0    103   1651     69     76      7      0
   1    63   58   43   63   43    0   59   54   21   45   80   66   49   38
   1    50   65   39   67  119    0   87   47   79   78   50   73   24   35
   1    37   48   44   58   49   58   45   66   61   55   86  138   80   43
   1    32    0   45   95   49   54   57   62   42   55  107  162   67   40
   1  1688 1678 1675 1674 1670 1684 1707 1675 1687 1683 1686 1695 1693 1690
   1  2047 2047 2047 2047 1808 2047 2047 2047 2047 2047 2047 2047  648 2047
   1  1776 1770 1776 1797 1799 1790 1774 1768 1791 1784 1800 1789 1775 1747
   1  2047 2047 2047 2047 2047 2047 2047 2047 2047 2047 2047 2047 2047 2047
   1   108  155   97   84  100  109   98   90  292
   1  2047  581 2047 2047 2047 2047 2047 2047 2047
   1    45   44  175   60   50   55   48   39   22
   1  2047 2047 2047  610 2047 2047 2047 2047 2047
   1    65   77   53   78   52   53   46  134   40
   1  2047 2047 2047 2047 2047 2047 2047 2047 2047
   1    0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
   1    1 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000
   1    0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
   1    0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

screenshot

1 个答案:

答案 0 :(得分:1)

一种典型的方法是使用结构为每个文本行建模。这可以称为记录

您的文件格式看起来有不同类型的记录,因此您需要不同的结构。

在每个结构中,重载operator>>以从格式化的流中读取成员。这样可以简化编程:

Record1 r;
my_file >> r;

您可以将输入语句放入for循环:

std::vector<Record> block_of_data;
Record r;
for (unsigned int i = 0U; i < 5; ++i)
{
  my_file >> r;
  block_of_data.push_back(r);
}

您可以使用结构中的记录建模文件 希望使用std::vector而不是数组,因为您可能不知道编译时的数据量。

编辑1:示例
数据的第一行包含两个数字。所以,让我们创建一个类来模拟:

class Record1
{
  public:
    int   x; // First number
    int   y; // Second number;
  // Overload operator>> to read in the numbers
    friend std::istream& operator>>(std::istream& input, Record1& r);
};

std::istream& operator>>(std::istream& input, Record1& r)
{
    input >> r.x;
    input >> r.y;
    input.ignore(10000, '\n'); // Eat remaining newline if there is one.
    return input;
}

您的输入循环可能如下所示:

int item_number = 0;
Record1  r1;
while (data_file >> item_number) // Read in first number on the text line.
{
    // Read the first line (record)
    data_file >> r1;  
    // ...
}

您的下一条记录包含12个数字,因此它可能如下所示:

class Record2
{
  public:
    std::vector<int>  data;
  friend std::istream& operator>>(std::istream& input, Record2& r);
};

std::istream& operator>>(std::istream& input, Record2& r)
{
    // another technique:  read in as a line of text, then parse the string.
    std::string text;
    std::getline(input, text);
    std::istringstream  text_stream(text);
    int number = 0;
    while (text_stream >> number)
    {
        data.push_back(number);
    }
    return input;
}

文件读取循环:

Record1 r1;
Record2 r2;
int item_number;
while (data_file >> item_number)
{
  data_file >> r1; // Read first record;
  data_file >> item_number;
  data_file >> r2; // Read second record;
  // etc.
}

如果需要,可以将行封装到一个类中:

class Data_Item
{
  public:
    int          item_number;
    Record1      r1;
    Record2      r2;
    //...
  friend std::istream& operator>>(std::istream& input, Data_Item& d);
};

std::istream& operator>>(std::istream& input, Data_Item& d)
{
    // Note: first number on row is item number.
    // Row 1
    input >> d.item_number;
    input >> d.r1;

    // Row 2
    input >> d.item_number;
    input >> d.r2;
    //...
    return input;
}

您的文件将是Data_Item的容器,所以让我们以这种方式阅读:

std::vector<Data_Item> database;
Data_item d;
while (data_file >> d)
{
    data_file >> d;
    database.push_back(d);
}

有关重载输入运算符的更多信息,请在Internet上搜索“c ++重载运算符流示例”。

我建议您获取Scott Meyer的 Effective C ++ 系列,其中包含重载operator>>operator<<的说明和示例。