1

金曜日です。私はこのアプリを開発していて、頭が爆発しそうです。どこにも問題が見つかりません!!! 私は初心者のコーダーなので、stackoverflowの神々が私を正しい方向に導いたり、フィードバックを提供したりできることを願っています!! :]

このコンソールアプリは、単なる駐車時間のチケットです。コードはエラーなしで正常に準拠しています。しかし、私の数学はすべてめちゃくちゃです!

結果の例を次に示します。時刻を3:50として入力し、車両をTとして5:29を終了します。

 TIME-IN          -858993460:858993460
 TIME-OUT                -858933460:-858993460

 PARKING TIME             0:-858993460

 TOTAL CHARGE             -214748352.00

そして、これが私のコードです

 #include <iostream>   //used for cout/cin
 #include <iomanip>   //used to manipulate data 


 void getData(int* ehour, int* emin, int* exhour, int* exmin);
 void rate(int exhour, int exmin, int ehour, int emin, int* thour, int* tmin, int* round);
 void charge(char* vehic, float* rate1, float* rate2, int ehour);
 void result(int exhour, int exmin, int ehour, int emin, int thour, float rate1, float rate2, int round, float total);

 int main(void)
 {
   char vehic;
   int ehour;
   int emin;
   int exhour;
   int exmin;
   int thour;
   int tmin;
   int round;

   float rate1;
   float rate2;
   float total;

   getData(&ehour, &emin, &exhour, &exmin);
   rate(exhour, exmin, ehour, emin, &thour, &tmin, &round);
   charge(&vehic, &rate1, &rate2, ehour);
   total= rate1 + rate2;
   result( exhour, exmin, ehour, emin, thour, rate1, rate2, round, total);
   return 0;
 }

  void getData(int* ehour, int* emin, int* exhour, int* exmin)
 {
   char v;
   printf("Enter C for car, B for bus, T for truck: ");
   scanf("%c", &v);
   printf("\nHour vehicle entered 0-24: ");
   scanf("%d", &ehour);
   printf("\nMinute vehicle entered 0-60: ");
   scanf("%d", &emin);
   printf("\nHour vehicle exited 0-24: ");
   scanf("%d", &exhour);
   printf("\nMinute vehicle exited 0-60: ");
   scanf("%d", &exmin);
   return;
 }
 void rate(int exhour, int exmin, int ehour, int emin, int* thour, int* tmin, int* round)
 {
   if(emin < exmin)
   {
          emin= emin + 60;
          exhour= exhour - 1;
   }
   *thour = ehour - exhour;
   *tmin = emin - exmin;
   if ((*tmin > 0 && *tmin <= 60))
   {
          *thour = *thour + 1;
          *round = *tmin * 0;
   }
   return;
 }
 void charge(char* vehic, float* rate1, float* rate2, int ehour)
 {
   switch (*vehic)
   {
   case 'c': if (ehour <= 3)
                   {
                         *rate1 = 0.00;
                         if (ehour > 3)
                              *rate2 = 1.25 * (ehour - 3);
                   }
                   break;

   case 'b': if (ehour <= 2)
                   {
                         *rate1 = 2.00 * ehour;
                         if (ehour > 2)
                                *rate2 = 2.50 * (ehour - 2);
                   }
                   break;
   case 't': if (ehour <= 1)
                   {
                         *rate1 = 3.75 * ehour;
                         if (ehour > 1)
                         *rate2 = 4.50 * (ehour - 1);
                   }
                   break;
   }
   return;
 }
 void result(int exhour, int exmin, int ehour, int emin, int thour, float rate1, float rate2, int round, float total)
 {
   printf("\n\t\t PARKING LOT CHARGE \t\t\n");
   printf("\nType of vehicle: Car or Bus or Truck");
   printf("\nTIME-IN\t\t %d:%d", ehour, emin);
   printf("\nTIME-OUT\t\t %d:%d", exhour, exmin);
   printf("\n\t\t\t --------");
   printf("\nPARKING TIME\t\t %d:%d", thour, round);
   printf("\n\t\t\t --------");
   total= rate1 + rate2;
   printf("\nTOTAL CHARGE\t\t %4.2f\n\n", total);

   return;
   }

申し訳ありませんが、これはたくさんのコードです!私はとても困惑しています!!! 私のintは正しくフォーマットされていませんか?数学は間違っていますか?

4

6 に答える 6

7
char v;
printf("Enter C for car, B for bus, T for truck: ");
scanf("%c", &v);
printf("\nHour vehicle entered 0-24: ");
scanf("%d", ehour);
printf("\nMinute vehicle entered 0-60: ");
scanf("%d", emin);
printf("\nHour vehicle exited 0-24: ");
scanf("%d", exhour);
printf("\nMinute vehicle exited 0-60: ");
scanf("%d", exmin);

すでにポインタであったパラメータのアドレスを取得しました。


一般的な指の練習として、より一般的なC++スタイルでできることは次のとおりです。

/////////////////////////////////////
// timepoint classes (booking.hpp)

struct timepoint
{
    int hour, minute;

    timepoint normalized()                     const; 
    int totalMinutes    ()                     const; 
    int roundedHours    ()                     const; 
    timepoint operator- (timepoint const& rhs) const; 
};

struct booking_t
{
    char vehicle;
    timepoint enter, exit;

    timepoint parked() const { return exit - enter; }
};

/////////////////////////////////////
// main program (main.cpp)
booking_t inputData();
void displayBill(booking_t const& booking);

int main(void)
{
    auto booking = inputData();
    displayBill(booking);
}

/////////////////////////////////////
// timepoint methods (booking.cpp)

timepoint timepoint::normalized() const
{
    timepoint tmp { (hour + minute/60) % 24, minute % 60 };
    while (tmp.minute < 0) tmp.hour--, tmp.minute+=60;
    while (tmp.hour   < 0) tmp.hour+=24;
    return tmp;
}

int timepoint::roundedHours() const
{
    return (totalMinutes()-1) / 60 + 1; // TODO check rounding logic
}

int timepoint::totalMinutes() const
{
    return hour*60 + minute;
}

timepoint timepoint::operator-(timepoint const& rhs) const
{
    return timepoint { 0, totalMinutes() - rhs.totalMinutes() } .normalized();
}

#include <iostream>   //used for cout/cin

timepoint getTime(std::string label)
{
    int hour, minute;
    std::cout  << "\nHour "   << label << " 0-24: ";
    std::cin >> hour;
    std::cout  << "\nMinute " << label << " 0-60: ";
    std::cin >> minute;
    return { hour, minute };
}

/////////////////////////////////////
// global functions - input
booking_t inputData()
{
    std::cout << "Enter C for car, B for bus, T for truck: ";
    char v;
    std::cin >> v;
    auto entered = getTime("vehicle entered");
    auto exited  = getTime("vehicle exited");
    return { v, entered.normalized(), exited.normalized() };
}

/////////////////////////////////////
// calculation + billing
#include <sstream>
#include <iomanip>   //used to manipulate data 
#include <map>

static std::ostream& operator <<(std::ostream& os, timepoint const& tp)
{
    std::ostringstream oss;
    oss << std::setw(2) << std::setfill('0') << tp.hour << ':' 
        << std::setw(2) << std::setfill('0') << tp.minute;
    return os << oss.str();
}

std::pair<float,float> charge(booking_t const& booking)
{
    struct tariff_t { int threshold; float rate1, rate2; };
    const static auto tariffs = std::map<char, tariff_t> {
        { 'c', { 3, 0   , 1.25 } },
        { 'b', { 2, 2.  , 2.5  } },
        { 't', { 1, 3.75, 4.5 } } ,
    };

    auto& tariff = tariffs.at(std::tolower(booking.vehicle));
    auto  parked = booking.parked().roundedHours();

    return std::make_pair(
            tariff.rate1 * std::min(tariff.threshold, parked)    ,
            tariff.rate2 * std::max(0, parked - tariff.threshold));
}

void displayBill(booking_t const& booking)
{
    std::cout << "\n\n    PARKING LOT CHARGE\n";
    std::cout << "Type of vehicle: Car or Bus or Truck\n";
    std::cout << "TIME-IN         " << booking.enter << "\n";
    std::cout << "TIME-OUT        " << booking.exit  << "\n";
    std::cout << "                " << "--------\n";
    std::cout << "PARKING TIME    " << booking.parked() << "\n";
    std::cout << "        ROUNDED " << booking.parked().roundedHours() << "\n";
    std::cout << "                " << "--------\n";

    auto  rates = charge(booking);
    float total = rates.first + rates.second;
    std::cout << "TOTAL CHARGE    " << std::fixed << std::setw(7) << std::setprecision(2) << total << "\n\n";
}
于 2012-11-09T21:51:46.020 に答える
3

元のコードについてはあまり利用できないので、これ自体は答えではありませんが、「純粋なC++」で問題のコードを作成する方法がおもしろいと思うかもしれません。

#include <string>
#include <iostream>
#include <sstream>

bool parse_time(std::string const & s, int & t)
{
    int h, m;
    char c;

    std::istringstream iss(s);

    if (iss >> h >> c >> m >> std::ws && c == ':' && iss.get() == EOF)
    {
        t = 60 * h + m;
        return true;
    }

    return false;
}

int main()
{
    int t_in, t_out;
    std::string line;

    if (!(std::cout << "Enter arrival time: "   &&
          std::getline(std::cin, line)          &&
          parse_time(line, t_in)                &&
          std::cout << "Enter departure time: " &&
          std::getline(std::cin, line)          &&
          parse_time(line, t_out)))
    {
        std::cerr << "Input error! Aborting.\n";
        return 0;
    }

    std::cout << "You spent " << t_out - t_in << " minutes.\n";
}

典型的なセッションは次のとおりです。

Enter arrival time: 5:14
Enter departure time: 8:41
You spent 207 minutes.
于 2012-11-09T22:00:22.387 に答える
1

ルール1:最初に使用する場所の近くで変数を宣言します。そして、それらを作成するときにすべての変数を初期化します。

int main(void)
{
  int ehour = 0;
  int emin = 0;
  int exhour = 0;
  int exmin = 0;
  getData(&ehour, &emin, &exhour, &exmin);

  int thour = 0;
  int tmin = 0;
  int round = 0;
  rate(exhour, exmin, ehour, emin, &thour, &tmin, &round);

  char vehic = 0;
  float rate1 = 0;
  float rate2 = 0;
  charge(&vehic, &rate1, &rate2, ehour);

  float total = 0;
  total= rate1 + rate2;
  result( exhour, exmin, ehour, emin, thour, rate1, rate2, round, total);
  return 0;
}

今それを見float totalますか?変数の宣言と初期化を同じ行に移動します。

  float total = rate1 + rate2;

ルール2:必要がない場合は、ポインターを使用しないでください。関数に渡したり関数から渡したりする整数がある場合は、パラメーターを次のような参照パラメーターにします。

 void getData(int& ehour, int& emin, int& exhour, int& exmin)

主に:

  getData(ehour, emin, exhour, exmin);

getDataの場合:

void getData(int& ehour, int& emin, int& exhour, int& exmin)
{
  char v;
  printf("Enter C for car, B for bus, T for truck: ");
  scanf("%c", &v);
  printf("\nHour vehicle entered 0-24: ");
  scanf("%d", &ehour);
  printf("\nMinute vehicle entered 0-60: ");
  scanf("%d", &emin);
  printf("\nHour vehicle exited 0-24: ");
  scanf("%d", &exhour);
  printf("\nMinute vehicle exited 0-60: ");
  scanf("%d", &exmin);
  return;
}

今、私はあなたの最初の失敗を見つけました。整数ではなく、整数へのポインタを読み取る場所です。これらを参照(「エイリアス」または渡された変数について考えてください)にしたので、&演算子は整数へのポインターではなく、整数へのポインターを取得します。

次にやりたいことは、scanfを使用しないことです。Scanfは使いにくいです。なぜ使いにくいものを使うのですか?

ステップ3:プログラムはデバッグに役立つはずです。

入力から何かを読み取るときは、それを繰り返して、正しく読み取れることを確認してください。つまり、getDataを呼び出した後、次に行うべきことは、読んだ内容を繰り返すことです。最終的には、コードがしっかりしていれば、その「繰り返し」を削除できますが、プログラムを開発するときは、この種のフィードバックが不可欠です。

を使用する代わりに読むためのより良い方法については、KerrekSBを参照してくださいscanf

于 2012-11-09T22:32:09.007 に答える
1

私が気づいたことの1つ—あなた&ehourは友達を渡します。これはあなたの呼び出しへのポインターへのポインターです(あなたはisのときに呼び出しから削除することからscanf始めることができます)。&scanfehourint*

于 2012-11-09T21:49:43.777 に答える
1

&in scanfを取り出してください!それらはすでにポインタです!

于 2012-11-09T21:52:04.420 に答える
1

コードのもう1つのエラーは、変数vehicが値を取得しないことです。あなたはそれに価値を与えるつもりだったようですが、getDataどういうわけかそれを台無しにしました。

于 2012-11-09T21:59:22.843 に答える