繁体   English   中英

嵌套结构,从由空行分隔的文件中读取数据

[英]Nested Structures, reading data from a file separated by a blank line

我目前正在为我的项目制定会计程序。 我正在努力从文件中读取嵌套结构。 关于该如何处理的任何指导? 我知道我希望它停止读入帐户数据,并在到达空白行(空终止符)时移至下一个客户。 基本上,一些客户有两个帐户,另一些客户有两个以上(但不超过5个,结构数组仅包含5个)。 该项目本身更加深入(结构包含更多变量)。 我目前仅使用练习文件来尝试弄清楚这个概念。

到目前为止,这是我的代码:

 struct ACCOUNT
 {
 char acct_num[7];
 char balance[8];
 };

 struct CUSTOMER
{ 
char cust_name[20];
char number[5];
ACCOUNT acct[5];
};

int main()
{
  CUSTOMER person[3];
  fstream fin;
  fin.open("accounts.dat", ios::in);
  int i, j;
  i = 0, j = 0;
  char buff[20];
  char line[20];
  while (fin.getline(buff, 20))
    {
    strncpys(person[i].cust_name, buff, 10);
    fin.getline(line, 10);
    strncpy(person[i].number, line, 10);


    do {
        fin.getline(line, 20, ' ');
        strncpy(person[i].acct[j].acct_num, line, 10);
        fin.getline(line, 20);
        strncpy(person[i].acct[j].balance, line, 10);
        j++;
        cin.getline(line, 20);

    } while (*line != 0);
    i++;
}
return 0;
}

我试图读入的数据文件:

Jane Smith
FD12
SSDFSS 64.51
SD5545 88.51

John Smith
FD45
SFG789 77.21
NM4521 21.223
MM7888 33.33

John Doe
FSS4
SFGSGG 77.65
HN5555 22.31

我注意到的问题:

问题1

strncpys(person[i].cust_name, buff, 10);

我认为您打算使用strncpy ,而不是strncpys 即使那样,10也太小。 您需要使用20。

问题2

strncpy(person[i].number, line, 10);

在这里,10太大。 您需要使用5。

问题3

j需要在外部循环内重新初始化为0

问题4

检查内部while循环中的空行的逻辑是有缺陷的。 你用过

    cin.getline(line, 20);

作为循环的最后一行,但我认为这是发布到SO中的错误。 我想你有

    fin.getline(line, 20);

这是一个问题,因为您消耗了文件的下一行,但是其中的数据只是被扔掉了。


但是,我有更重要的建议是:

  1. 重新考虑解析输入文件的策略。 我发现最简单的方法是逐行读取文件的内容,然后分别处理每一行。

  2. 创建较小的函数以读取输入的不同部分,并从main使用它们。

  3. 向stdout写入读取的内容,以便可以清楚地看到未按期望读取数据的位置。

我建议对main进行以下更新。

int main()
{
   CUSTOMER person[3];
   fstream fin;
   fin.open("socc.in", ios::in);
   int i = 0;

   std::string line;
   while ( getline(fin, line) )
   {
      read_customer_name(line, person[i]);
      std::cout << "cust_name: " << person[i].cust_name << std::endl;

      if ( getline(fin, line) )
      {
         read_customer_number(line, person[i]);
         std::cout << "number: " << person[i].number << std::endl;
      }
      else
      {
         // Read was not successful.
         // Break the loop.
         break;
      }

      // Define it in this scope only.
      int j = 0;
      while ( getline(fin, line) )
      {
         if ( line.empty() )
         {
            break;
         }

         read_customer_account(line, person[i].acct[j]);
         std::cout << "acct[j].acct_num: " << person[i].acct[j].acct_num << std::endl;
         std::cout << "acct[j].balance: " << person[i].acct[j].balance << std::endl;

         j++;
      }
   }
   return 0;
}

辅助函数在哪里:

void read_customer_name(std::string const& line, CUSTOMER& person)
{
   strncpy(person.cust_name, line.c_str(), 20);
}

void read_customer_number(std::string const& line, CUSTOMER& person)
{
   strncpy(person.number, line.c_str(), 5);
}

void read_customer_account(std::string const& line, ACCOUNT& acct)
{
   std::istringstream str(line);
   str.getline(acct.acct_num, 10, ' ');
   str.getline(acct.balance, 10);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM