我目前正在为我的项目制定会计程序。我正在努力从文件中读取嵌套结构。关于该如何处理的任何指导?我知道我希望它停止读入帐户数据,并在到达空白行(空终止符)时移至下一个客户。基本上,一些客户有两个帐户,另一些客户有两个以上(但不超过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
答案 0 :(得分:0)
我注意到的问题:
strncpys(person[i].cust_name, buff, 10);
我假设您打算使用strncpy
,而不是strncpys
。即使那样,10也太小。您需要使用20。
strncpy(person[i].number, line, 10);
此处,10太大。您需要使用5。
j
需要在外部循环内重新初始化为0
。
检查内部while
循环中空行的逻辑是有缺陷的。您已经使用
cin.getline(line, 20);
作为循环的最后一行,但我认为这是发布到SO中的错误。我认为您有
fin.getline(line, 20);
这是一个问题,因为您消耗了文件中的下一行,但其中的数据只是被扔掉了。
但是,我提出的更重要的建议是:
重新考虑解析输入文件的策略。我发现最简单的方法是逐行读取文件的内容,然后分别处理每一行。
创建较小的函数以读取不同的输入,并从main
中使用它们。
写出输出的内容,这样您就可以清楚地看到未读取数据的位置,就像您希望的那样。
我建议对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);
}