使用函数和文件输入进行半衰期确定的C ++程序

时间:2015-11-09 15:06:39

标签: c++ function file visual-c++ c++-standard-library

以下是我正在处理的问题:

  

您将开发一个菜单驱动的程序,该程序允许使用以下等式分析文件Patient_Data.txt中的数据:

enter image description here

  
    

Ct = C0e ^ -kt

         

t1 / 2 = ln(2)/ k

  
     

其中:
   Ct 是时间t的ug / L浓度    C0 是ug / L的初始浓度    t 是小时的时间    k 是时间常数(1 /小时)
   t1 / 2 是小时的半衰期

     
      
  • 程序的用户必须能够获得平均半衰期(小数点后2位)以及用于计算已收集数据的5名患者中任何一名患者的平均值的测量次数。
  •   
  • 该计划还必须能够显示具有最高半衰期平均值的患者的2个患者数和平均值。
  •   
  • 必须使用菜单选择不同的选项,并为Exit提供附加选项。程序必须运行,直到用户选择退出。
  •   
  • 必须使用功能设计程序。      
        
    • 名为analyzeData的功能必须将患者编号作为输入,并且必须同时返回输入患者编号的平均半衰期和平均测量次数。
    •   
    • 一个名为halfLife的单独函数用于根据C0(初始浓度),Ct(时间t的浓度)和t(时间)计算t1 / 2(半衰期)数据文件。
    •   
    • 还必须使用称为highest2halfLifes的第三个函数来确定来自五个不同患者的平均半衰期最长的两个患者。必须将所有四个值(patient1halfLife1patient2halfLife2)返回到主函数。
    •   
  •   

以下数据文件Patient_Data.txt分别列出了C0,Ct和t的值

1 325 160 2.0
1 600 100 6.2
2 325 220 1.0
3 600 200 4.4
4 325 100 3.0
4 325 88 3.2
2 600 200 3.3
2 325 100 3.3
4 600 210 3.4
5 325 105 3.5
1 600 110 6.0
3 325 100 3.1
2 600 120 5.5
2 600 125 5.5
5 120 60 2.2
2 325 100 3.4

这是我到目前为止所做的:

#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>

using namespace std;

bool analyzeData(int patientNum, double *avgHalfLife, int *numMeasurements);
double halfLife(double C0, double Ct, double t);
bool highest2halfLifes(double avgHalfLife, int *patient1, double *halflife1, int *patient2, double *halflife2);


int main()
{
    int patientNum;
    char option;
    double avgHalfLife = 0;
    int numMeasurements = 0;

    do
    {
        cout << "\nNew Pain Drug - Half-Life Determination\n";
        cout << "---------------------------------------\n";
        cout << " [P] - Patient Summary\n";
        cout << " [H] - Highest two half-lifes\n";
        cout << " [X] - to Exit\n";
        cout << "\nEnter Option: ";
        cin >> option;

        switch (option)
        {
        case 'p': 
            cout << "Enter patient number (1-5): ";
            cin >> patientNum;
            analyzeData(patientNum, &avgHalfLife, &numMeasurements);
            cout << "Half-life of patient #" << patientNum << " is " << fixed << setprecision(2) << avgHalfLife << " hrs, using " << numMeasurements << " measurements.\n";
            break;

        case 'h': 
            break;

        case 'x': option = false;
            break;

        default: cout << "Invalid option entered.\n";
        }
    }
    while (option);
    return 0;
}

bool analyzeData(int patientNum, double *avgHalfLife, int *numMeasurements)
{
    double C0, Ct, t, t1/2;
    double sumHalfLifes = 0;

    int patient;
    ifstream fin;
    fin.open ("Patient_Data.txt");

if (fin)
{
    while (fin >> patient >> C0 >> Ct >> t) 
    {
        if (patient == patientNum)
        {
            bool analyzeData = true;
            t½ = halfLife(C0, Ct, t);

            *numMeasurements++;
            sumHalfLifes = sumHalfLifes + t½;
            *avgHalfLife = sumHalfLifes/ *numMeasurements;
        }
    }
}
else
cout << "Error opening file.";

    fin.close();
    return analyzeData;
}


double halfLife(double C0, double Ct, double t)
{
    double k, t1/2;

    k = - log(Ct/C0)/t;
    t½ = log(2)/k;

    return t1/2;
}

bool highest2halfLifes(double avgHalfLife, int *patient1, double *halflife1, int *patient2, double *halflife2)
{
    double highest = avgHalfLife;

    if (avgHalfLife > highest)
        highest = avgHalfLife;

    return highest2halfLifes;
}

以下是我得到的输出:

enter image description here

我需要帮助的是让函数analyzeData返回正确的数据,因为截至目前,程序输出始终为零。另外,我们还没有学到std::的任何内容,所以我不想使用它。有关如何解决此问题或更正我的代码的任何建议将不胜感激。

1 个答案:

答案 0 :(得分:2)

您的代码有几个不正确的地方。我会告诉他们每个人:

bool analyzeData(int patientNum, double *avgHalfLife, int *numMeasurements);
//...
bool highest2halfLifes(double avgHalfLife, int *patient1, double *halflife1, int *patient2, double *halflife2);

使用pass-by-reference而不是传递指针by-value以返回多个值时,它更简单,更容易阅读:

bool analyzeData(int patientNum, double& avgHalfLife, int& numMeasurements);
//...
bool highest2halfLifes(double avgHalfLife, int& patient1, double& halflife1, int& patient2, double& halflife2);
int patientNum;
char option;
double avgHalfLife = 0;
int numMeasurements = 0;

在代码中保持一致。 始终使用正确的数据类型值初始化变量。

int patientNum = 0;
char option = 0;
double avgHalfLife = 0.0;
int numMeasurements = 0;
       switch(option) {
       //...
               analyzeData(patientNum, &avgHalfLife, &numMeasurements);
       //...

由于我们现在通过引用传递值,因此我们不传递地址:

switch(option) {
//...
analyzeData(patientNum, avgHalfLife, numMeasurements);
//...
           case 'x': option = false;
               break;

在空格和格式方面保持一致。 char不是bool,但任何非零值都被视为true,任何零值都被视为false:

case 'x':
    option = 0;
    break;
default: cout << "Invalid option entered.\n";

一致性:

default:
    cout << "Invalid option entered.\n";
bool analyzeData(int patientNum, double *avgHalfLife, int *numMeasurements) {
    double C0, Ct, t, t1 / 2;
    double sumHalfLifes = 0;

    int patient;
    ifstream fin;
    fin.open("Patient_Data.txt");

    if(fin) {
        while(fin >> patient >> C0 >> Ct >> t) {
            if(patient == patientNum) {
                bool analyzeData = true;
                t½ = halfLife(C0, Ct, t);

                *numMeasurements++;
                sumHalfLifes = sumHalfLifes + t½;
                *avgHalfLife = sumHalfLifes / *numMeasurements;
            }
        }
    } else
        cout << "Error opening file.";

    fin.close();
    return analyzeData;
}

不要使用逗号运算符声明变量。它使代码更难阅读和遵循。 始终初始化变量。 在你的声明中保持一致。

 bool analyzeData(int patientNum, double& avgHalfLife, int& numMeasurements) {
     double C0 = 0.0;
     double Ct = 0.0;
     double t = 0.0;
     double t_half = 0.0;
     double sumHalfLifes = 0.0;
bool analyzeData = true;

您已将变量命名为与函数名称相同的变量。不要这样做。

bool is_data_analyzed = true;
t½ = halfLife(C0, Ct, t);

//...
sumHalfLifes = sumHalfLifes + t½;

虽然在某些上下文中允许使用变量名称中的Unicode并不安全,但将变量重命名为t_half或类似。

    return analyzeData;

这不符合你的想法!您在内部范围块中声明了analyzeData,因此在其外部不可见。因为它不存在于该块之外并且您将其命名为与该函数相同,所以实际上是将该地址返回给该函数!由于函数的地址永远不为零,因此它将始终返回true!

   double k, t1 / 2;

这只是......错了。

double k = 0.0;
double t_half = 0.0;
   k = -log(Ct / C0) / t;
   t½ = log(2) / k;

您打算使用自然对数吗? std::log相当于数学&#34; log base e&#34;或&#34; ln&#34;。如果你想要数学&#34; log base 2&#34;或&#34;记录基数10&#34;,分别使用log2(...)log10(...)

bool highest2halfLifes(double avgHalfLife, int *patient1, double *halflife1, int *patient2, double *halflife2) {
   double highest = avgHalfLife;

   if(avgHalfLife > highest)
       highest = avgHalfLife;

   return highest2halfLifes;
     

}

此功能不起作用。您已将highest初始化为avgHalfLife,然后检查其是否高于highest。这是一个矛盾。此外,您将再次返回该函数的地址!