【问题标题】:using functions to input 1 int and 1 string array and looping使用函数输入 1 个 int 和 1 个字符串数组并循环
【发布时间】:2013-11-16 19:32:52
【问题描述】:

我有一个 cs 课程项目,下周晚些时候到期,我几乎完成了,但我遇到了一些问题,我一直在尝试一切,但无法让它发挥作用。我们的项目包括从输入文件中获取 3 个月的 3 位客户信息和每月的水电费,将所有这些存储在数组中,然后计算小计、税收、折扣和支付总额,然后将其存储到数组中,然后输出 1 个季度收据对于每个客户。我们必须使用函数来做到这一点。我的主要问题是它只输出第一个客户收据,我仔细检查了我的 for 循环,对我来说它看起来应该可以工作。

非常感谢

这是输出文件

             Austin City Office, Texas
                           RECEIPT #59, September28, 2013, 09:00PM

客户编号:127654 姓名:杰克琼斯 地址:2059 Joe Lane, Austin TX, 78646 电话号码:512-520-5862

电费:6 美元 水费:$24 汽油费:12 美元

小计:42 美元 折扣金额:0.84 美元(2% 折扣,因为您的小计低于 100 美元)

折扣后小计:41.16 美元(加上 2% 的折扣)

销售税金额:2.4696 美元(6% 税,因为折扣后的小计低于 100 美元)

支付的总金额:43.6296 美元(加上 6% 的销售税)

.................................................. ..................................................... …… 退款政策:如果在付款之日起 30 天内报告错误,则 100%。仅退还 75% 30天后。 感谢您及时付款。


这是我的输入文件

Austin City Office, Texas
RECEIPT #59, September28, 2013, 09:00PM
Refund Policy: 100% if an error is reported within 30 days from the date of payment. Only 75% refund 
after 30 days.
Thank you for prompt payment.
127654
Jack Jones
2059 Joe Lane, Austin TX, 78646
512-520-5862
2
8
4
2
8
4
2
8
4
Austin City Office, Texas
RECEIPT #59, September28, 2013, 09:00PM
Refund Policy: 100% if an error is reported within 30 days from the date of payment. Only 75% refund 
after 30 days.
Thank you for prompt payment.
124325
Jack Williams
2788 Eagle Drive, Austin TX, 78646
512-623-7676
2
8
20
2
8
20
2
8
20
Austin City Office, Texas
RECEIPT #59, September28, 2013, 09:00PM
Refund Policy: 100% if an error is reported within 30 days from the date of payment. Only 75% refund 
after 30 days.
Thank you for prompt payment.
125672
John Jones
3422 Hawk Drive, Austin TX, 78646
512-522-4564
2
8
40
2
8
40
2
8
40

这是我的代码

#include<iostream>
#include<iomanip>
#include<string>
#include<string>
#include<fstream>

using namespace std;

//define varibles
    int ncustomer1;
    double  discount, tax;
    string dc, dsc, tc, dtpc;
    //validation constant
    const int MIN_N = 1, MAX_N = 3, MAX_TITLE=200, MAX_CINFO=200;
    const float MIN_CHARGE=1.00, MAX_CHARGE= 1000.00;
    // Array constant
    const int MAX_NUMCUST=3, MAX_NUMMONTH=3, MAX_NUMCHARGE=3, MAX_NUMHEAD=6, MAX_NUMINFO=9, MAX_NUMTOTAL=8;
    //customer info array
    string NonNum[MAX_NUMCUST][MAX_NUMINFO];
    //charges array
    double Num[MAX_NUMCUST][MAX_NUMMONTH][MAX_NUMCHARGE] = {0};
     //calculated array
    double custTotals[MAX_NUMCUST][MAX_NUMTOTAL] = {0};

    //functions
    void input(string NonNum[MAX_NUMCUST][MAX_NUMINFO], double Num[MAX_NUMCUST][MAX_NUMMONTH][MAX_NUMCHARGE], int& count);
    double subtotal(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count);
    double discount1(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count);
    double tax1(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count);
    void receipts(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], string NonNum[MAX_NUMCUST][MAX_NUMINFO], int&count);

int main()

{
    //Ask number of customers from user
        cout<< "Enter a number for amount of customers you would like to make a receipt for number should be between 1 and 3."<<endl;
        cin >> ncustomer1;

    //validate users entry
        while(ncustomer1 > MAX_N || ncustomer1 < MIN_N )
        {
            cout << "Error: the number of customers must be between "<< MIN_N << " and "<< MAX_N  <<endl;
            cout<< "Re-Enter the number of customers"<<endl;
            cin>> ncustomer1;
        }

    //output to screen when users entry is correct
        cout<< "Ok, individual receipt(s) will be added to the output file for "<< ncustomer1<< " customer(s)."<<endl;

        //customer for loop
    for (int count = 0; count < ncustomer1; ++count)
        {
        input(NonNum, Num, count);
        subtotal(custTotals, count);
        discount1(custTotals, count);
        tax1(custTotals, count);
        receipts(custTotals, NonNum, count);
        }

return 0;

}

//functions
void input(string NonNum[MAX_NUMCUST][MAX_NUMINFO], double Num[MAX_NUMCUST][MAX_NUMMONTH][MAX_NUMCHARGE], int& count)
{
    //objects to help read input file
                ifstream inputFile;

            //open the input file
                inputFile.open("Project5_a02418790_Input.txt");

            //validation of input file
                if(!inputFile)
                {
                    cout<<"error opening input file.";

                }
            // For loop for non numeric data id, number...
                        for(int head = 0; head < 9; ++head)
                            {
                                //Get customer data as strings from input
                                getline(inputFile,NonNum[count][head]);

/*                              Validate inputed customer data
                                if(NonNum[count][head].length()>MAX_CINFO)
                                    {
                                        cout<<"customer "<<count<<"(customers are from 0-X, so customer 1=0) heading "<<head<<" String is too long"<<endl;
                                        continue;
                                    }
*/
                            }//end non numeric data for loop


                //number of months For loop
                for(int mnth = 0; mnth < 3; ++mnth)
                    {

                        //number of charges For loop
                        for(int charge = 0; charge < 3; ++charge)
                            {
                                //input charges
                                inputFile >> Num[count][mnth][charge];

                                //Running totals of the 3 charges
                                custTotals[count][charge] += Num[count][mnth][charge];
                            }//end of number of charges for loop

                    }//end of number of months foor loop

}


double subtotal(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count)
{
// calculate the subtotal
//subtotal          =    Elec total      +   Water Total      +   Gas Total
custTotals[count][3]=custTotals[count][0]+custTotals[count][1]+custTotals[count][2];

}

double discount1(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count)
{
//figure out the discount based on the subtotal
                //if(subtotal=,<,> a number)
                //  discount%= x, comment= x;
                if(custTotals[count][3]<100)
                    discount= .02, dc = "(2% discount since your subtotal is less than $100)", dsc="(With 2% discount added)";
                if(custTotals[count][3]>=100&&custTotals[count][3]<250)
                    discount= .03, dc = "(3% discount since your subtotal is greater or equal to $100)", dsc="(With 3% discount added)";
                if(custTotals[count][3]>=250&&custTotals[count][3]<500)
                    discount=.04, dc = "(4% discount since your subtotal is greater or equal to $250)", dsc="(With 4% discount added)";
                if(custTotals[count][3]>=500)
                    discount=.05, dc = "(5% discount since subtotal is greater or equal to $500)", dsc="(With 5% discount added)";

            //calculate the amount of discount
            //discount amount      =     subtotal      * discount %
            custTotals[count][4] = custTotals[count][3]*discount;

            //calculate the subtotal after the discount
            //subtotal after dis=    subtotal        - discount
            custTotals[count][5]=custTotals[count][3]-custTotals[count][4];
}

double tax1(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], int&count)
{


    //figure out how sales tax percent and what captions
    //if(subtotal after dis =,<,> a num)
    //  tax percent= x, comment= x;
    if(custTotals[count][5]< 100 )
        tax= .06, tc="(6% Tax since your subtotal after the discount is less than $100)", dtpc= "(With 6% Sales Tax added)";
    if( custTotals[count][5] >=100&& custTotals[count][5] <250)
        tax= .07, tc="(7% Tax since your subtotal after the discount is greater or equal to $100)", dtpc= "(With 7% Sales Tax added)";
    if( custTotals[count][5] >=250&& custTotals[count][5] <500)
        tax=.08, tc="(8% Tax since your subtotal after the discount is greater or equal to $250)", dtpc= "(With 8% Sales Tax added)";
    if( custTotals[count][5] >=500)
        tax=.09, tc="(9% Tax since your subtotal after the discount is greater or equal to $500)", dtpc= "(With 9% Sales Tax added)";

//calculate the sales tax amount
//amount of tax    = subtotal after dis  * tax percent
custTotals[count][6]= custTotals[count][5]*tax;

//calculate total amount paid
//total paid       =  subtotal after dis   + amount of tax
custTotals[count][7]= custTotals[count][5] + custTotals[count][6];

}

void receipts(double custTotals[MAX_NUMCUST][MAX_NUMTOTAL], string NonNum[MAX_NUMCUST][MAX_NUMINFO], int&count)
{
    //objects to help read output file
                ofstream outputFile;

            //open the  output file
                outputFile.open("Project5_a02418790_Output.txt");

            //validation of output file
                if(!outputFile)
                {
                    cout<<"error opening output file.";

                }

//OUTPUT ALL NEEDED INFO (STILL INSIDE CUSTOMER FOR LOOP)
                        //OUTPUT HEADER
                        outputFile<<setw(58)<<NonNum[count][0]<<endl<<setw(70)<<NonNum[count][1]<<endl;

                        //OUTPUT CUSTOMER INFO FOR LOOP
                        for(int z = 5; z < 9; ++z)
                            {

                                while(z == 5 )//Customer ID
                                    {
                                        outputFile<<endl<<"Customer ID: "<<NonNum[count][z]<< endl;
                                        break;
                                    }

                                while(z == 6 )//Name
                                    {
                                        outputFile<<"Name: "<<NonNum[count][z]<< endl;
                                        break;
                                    }

                                while(z == 7 )//Address
                                    {
                                        outputFile<<"Address: "<<NonNum[count][z]<< endl;
                                        break;
                                    }

                                while(z == 8 )//Phone Number
                                    {
                                        outputFile<<"Phone Number: "<<NonNum[count][z]<< endl;
                                        break;
                                    }

                            }//END OF OUTPUT CUSTOMER INFO FOR LOOP

                        //OUTPUT CHARGES AND TOTALS FOR LOOP
                        for(int y = 0; y < 8; ++y)
                            {

                                while(y == 0 )//Electricity Charges
                                    {
                                        outputFile<<endl<<"Electricity Charges: $"<<custTotals[count][y] << endl;
                                        break;
                                    }

                                while(y == 1 )//Water Charges
                                    {
                                        outputFile<<"Water Charges: $"<<custTotals[count][y] << endl;
                                        break;
                                    }

                                while(y == 2 )//Gas Charges
                                    {
                                        outputFile<<"Gas Charges: $"<<custTotals[count][y] << endl<<endl;
                                        break;
                                    }

                                while(y == 3 )//Subtotal
                                    {
                                        outputFile<<"Subtotal: $"<<custTotals[count][y] << endl;
                                        break;
                                    }

                                while(y == 4)//Discount Amount
                                    {
                                        outputFile<<"Discount Amount: $"<<custTotals[count][y]<<" "<<dc<< endl<<endl;
                                        break;
                                    }

                                while(y == 5 )//Subtotal After the Discount
                                    {
                                        outputFile<<"Subtotal After the Discount: $"<<custTotals[count][y]<<" "<<dsc<< endl<<endl;
                                        break;
                                    }

                                while(y == 6 )//Sales Tax Amount
                                    {
                                        outputFile<<"Sales Tax Amount: $"<<custTotals[count][y]<<" "<<tc<< endl<<endl;
                                        break;
                                    }

                                while(y == 7 )//Total Amount Paid
                                    {
                                        outputFile<<"Total Amount Paid: $"<<custTotals[count][y]<<" "<<dtpc<< endl<<endl;
                                        break;
                                    }

                            }//END OF OUTPUT CHARGES AND TOTALS FOR LOOP


                        //OUTPUT FOOTER BREAK
                        outputFile<<"....................................................................................................."<<endl;

                        //OUTPUT REFUND FOR LOOP
                        for(int w = 2; w < 4; ++w)
                            {
                                outputFile<< NonNum[count][w]<<endl;
                            }

                        //OUTPUT THANKYOU
                        outputFile<<setw(58)<<NonNum[count][4]<<endl;

                        //OUTPUT NEW LINE AND DIVIDER FOR NEW CUSTOMER
                        outputFile<<endl<<"_____________________________________________________________________________________________________"<<endl<<endl;



}

【问题讨论】:

  • 我不知道为什么我的输入文件会这样上传,如果有其他上传方式我会的。
  • 使用调试器一次单步执行您的代码行,看看哪里出了问题。检查变量的内容以帮助找出原因。
  • 另外,使用描述性的自记录名称。 dc、dsc、tc、dtpc 等名称使代码成为阅读和理解的噩梦。避免缩写。名称的每个部分都应该描述一些关于它的东西——像ncustomer1 这样的名称是不可读的——“n”是什么意思?为什么有一个“1”?阅读代码的人(可能是未来的你)不应该问这些问题。更喜欢“numberOfCustomers”之类的内容 - 现在无需进一步阅读即可立即理解。
  • 另外一点,您的代码大量使用了全局变量 - 这是rarely a good idea
  • 我刚刚看到你们所有的 cmets 非常感谢。和@JBentley,我们的教授想要所有东西的全局常量。这里有一段项目描述客户的数量(n)将被声明为全球。此外,对数组的大小使用全局常量。

标签: c++ arrays function for-loop output


【解决方案1】:

你确定它每次都写第一个吗?在我看来,它会写最后一个,因为您每次调用收据时都会覆盖文件而不是附加到它。

获得一组输出恕我直言的关键原因是这一行

outputFile.open("Project5_a02418790_Output.txt");

因为您每次调用收据时都调用它,所以您最终每次都会覆盖文件并只获得一组输出。

还有很多其他的东西是非常糟糕的编码习惯。

问题1:在应该使用结构/或类的地方使用数组: 例如:您将客户信息保存在字符串数组的数组中。

std::string NonNum[MAX_NUMCUST][MAX_NUMINFO]

然后 NonNum[1][5] 是客户 1 的 customerID 的 ID。您应该构建一个结构,它将使您的代码更容易理解。正确命名它 NonNum 告诉我们它包含我们从代码中知道的字符串,它没有告诉我们存储什么样的信息的重要信息(客户 ID / 地址等。)

也看看这个:

for(int z = 5; z < 9; ++z) {
    while(z == 5 )//Customer ID  {
         outputFile<<endl<<"Customer ID: "<<NonNum[count][z]<< endl;
         break; 
    while(z==6) { ...

}

内部while的意义何在?为什么需要for循环?写起来是不是容易多了:

outputFile

问题2:函数之间的依赖关系

小计填充custTotals[i][3] 并依赖于custTotals[i][0]custTotals[i][1]custTotals[i][2]

discount1 根据前面的填充 custTotals[i][4] .. 同样,您正在使用应该使用结构的数组。但是,如果函数的输入和输出清晰且易于理解,它也会让您的生活更轻松。

目前,函数顺序的任何更改都会弄乱逻辑,但从代码中无法看出这一点。

如果你有一个单独的 subTotals 数组,你可以将它传递给 subTotals,这样它就会写入,然后再传递给 Discount1,这样它读取的所有内容就会变得更清晰。

问题 3:您将 int& count 传递给所有这些函数,尽管您不打算更改它。我预计错误是您写了一个内部函数并且没有意识到它。如果将非 const ref 传递给对象,则表明这是函数的输出而不是输入。

【讨论】:

  • 我只是查看了输出文件,它正在输出第一个客户信息,所以我不相信它正在覆盖。问题1;我们不允许使用结构,但我们必须将此代码转换为下一个项目的结构,这很糟糕。问题2;让我看看我能做些什么来编辑那个小计数组。问题3;让我看一下,我对刚开始使用它们的功能仍然有些困惑,而且我不是 cs 专业的。
  • 我还将输出文件添加到我原来的问题中,谢谢@odedsh
  • 所以你还有一个问题。每次调用 Input 函数时,都会重新打开文件。这就是为什么您继续处理第一组数据的原因。所以你的循环基本上一次又一次地打开相同的输入文件,只读取第一组数据。它一次又一次地打开相同的文件输出文件写入相同的数据集
  • 是的,我刚刚意识到我使用 cin.ignore 解决了这个问题,现在就像你在我覆盖之前所说的那样。我将如何解决这个问题。如果我可以将输出文件的开头拉出我的循环,我相信它会工作得很好,但是我不能从循环内部写入它......?
  • 打开输入流,然后将其传递给您的 read_input 函数。打开输出流并将其传递给执行写入的函数。读/写函数接受一个流对象是很常见的无需更改代码
猜你喜欢
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 2019-02-17
  • 1970-01-01
  • 2014-06-21
  • 1970-01-01
相关资源
最近更新 更多