2012-04-06 26 views
1

我只在C++上工作了大約一個月。我不是很瞭解它是如何工作的,但是我需要爲學校編寫一個程序。我用了一個void函數,它似乎工作到目前爲止,但我不知道該怎麼辦下一步我在第44行丟失,我不知道如何使它工作,有沒有辦法從一個值某些字符串?如果這個值在兩個字符串中,我將如何確定哪個值?這裏是我的任務:如何使用getline和stringstream分析格式化的日期和時間輸入?

停車場收費最低爲2美元停車長達三小時的費用。車庫每小時或每小時額外收費0.50美元,超過三小時。任何給定24小時期限的最高收費爲10美元。將車停放超過24小時的人每天將支付8美元。

編寫一個計算和打印停車費用的程序。您的程序輸入是汽車進入停車庫的日期和時間,以及同一輛汽車離開停車場的日期和時間。兩個輸入是在YY/MM/DD,格式爲HH:MM

這裏是我到目前爲止已經編寫的代碼:

#include <iostream> 
#include <fstream> 
#include <iomanip> 
#include <string> 
#include <cmath> 
#include <algorithm> 
#include <sstream> 
using namespace std; 

stringstream ss; 
string enter_date; 
string enter_time; 
string exit_date; 
string exit_time; 
int calculatecharge; 
int num; 
int i; 
int year; 
int month; 
int ddmmyyChar; 
int dayStr; 
string line; 
int x; 

void atk() 
{ 
    getline (cin,line);    // This is the line entered by the user 
    stringstream ss1(line);  // Use stringstream to interpret that line 
    ss >> enter_date >> enter_time; 
    stringstream ss2(enter_date); // Use stringstream to interpret date 
    string year, month, day; 
    getline (ss2, year, '/'); 
} 

int main() 
{ 
    cout << "Please enter the date and time the car is entering "<< endl 
     << "the parking garage in the following format: YY/MM/DD hh:mm"<< endl; 
    atk(); 
    cout << "Please enter the date and time the car is exiting "<< endl 
     << "the parking garage in the following format: YY/MM/DD hh:mm"<< endl; 
    atk(); 
    if (hr - hr < 3) 
     cout<<"Parking fee due: $2.00" << endl; 
+0

您包含的某些頭文件不是必需的。例如,如果您沒有執行文件I/O,則不需要'#include '。 – bwDraco 2012-09-17 01:56:11

回答

0

所有同時作爲字符串的日期和第一字符串的時間是連續的(不包​​含空格),你不需要使用stringstream來分析這一行。你可以這樣讀取日期和時間:

cin >> enter_date >> enter_time; 
cin >> exit_date >> exit_time; 

現在你需要的是將這些字符串轉換爲實際的日期和時間。由於這兩種格式是固定的,你可以寫這樣的事情:當然

void parse_date(const string& date_string, int& y, int& m, int& d) { 
    y = (date_string[0] - '0')*10 + date_string[1] - '0'; // YY/../.. 
    m = (date_string[3] - '0')*10 + date_string[4] - '0'; // ../mm/.. 
    d = (date_string[6] - '0')*10 + date_string[7] - '0'; // ../../dd 
} 

這個代碼是有點醜陋,並且可以更好的方式來寫,但我認爲這種方式更容易理解。有了這個功能,它應該是顯而易見如何寫這一個:

void parse_time(const string& time_string, int& h, int &m); 

現在你已經解析的日期和時間,你需要實現減去兩個日期的方法。事實上,您關心的是從輸入日期時間到退出日期時間四捨五入的小時數。我在這裏建議的是,您將日期從某個初始時刻(例如00/01/01)轉換爲天數,然後減去這兩個值。然後將這兩次轉換爲自00:00以來的分鐘數並再次減去它們。這不是語言特定的,所以我相信這些提示應該足夠了。再次使用一些內置庫可以更容易完成,但我不認爲這是您的任務。

當你有四捨五入的時間後,你需要做的只是實現聲明中的規則。這隻需要幾個ifs,而且其實很簡單。

希望這會有所幫助。我故意不給出更詳細的解釋,以便有什麼可供您思考。畢竟這是作業,是爲了讓你思考如何去做。

+0

非常感謝!我一直在爲此工作好幾天,而且你是第一個解釋它足以讓我理解的人。對此,我真的非常感激。 – user1311854 2012-04-06 06:02:12

+0

這使得更有意義的是,我的老師告訴我,使用cin是行不通的,我不得不使用getline把我扔掉,謝謝你澄清它。 – user1311854 2012-04-06 06:46:10

3

編寫一個計算和打印停車費用的程序。

這是我們程序的目標。基本上,這是輸出。

到你的程序的輸入是當汽車進入 停車場,以及日期和時間時,同一輛車離開 停車庫的日期和時間。兩個輸入是在YY/MM/DD,格式爲HH:MM

所以,我們要轉換輸入爲一個字符串的日期格式轉換成時間差某種方式。您可以將時間存儲在int中,該時間表示停車期間過去的分鐘數(我選擇分鐘數,因爲這是輸入的最小時間段)。這裏的挑戰是將字符串解析爲這個整數。

你可以寫這樣的功能:

int parseDate(std::string dateStr) 
{ 
    // Format: YY/MM/DD hh:mm 
    int year = atoi(dateStr.substr(0, 2).c_str()); 
    int month = atoi(dateStr.substr(3, 2).c_str()); 
    int day = atoi(dateStr.substr(6, 2).c_str()); 
    int hour = atoi(dateStr.substr(9, 2).c_str()); 
    int min = atoi(dateStr.substr(12, 2).c_str()); 

    // Now calculate no. of mins and return this 
    int totalMins = 0; 
    totalMins += (year * 365 * 24 * 60); // Warning: may not be accurate enough 
    totalMins += (month * 30 * 24 * 60); // in terms of leap years and the fact 
    totalMins += (day * 24 * 60);  // that some months have 31 days 
    totalMins += (hour * 60); 
    totalMins += (min); 

    return totalMins; 
} 

小心!我的功能只是一個例子,並沒有考慮到閏年和月份長短等微妙之處。你可能需要改進它。重要的是要識別它試圖取一個字符串並返回自'00以來已過去的分鐘數。這意味着我們只需要減去兩個日期字符串兩個整數找到經過時間:

int startTime = parseDate(startDateString); 
int endTime = parseDate(endDateString); 
int elapsedTime = endTime - startTime; // elapsedTime is no. of minutes parked 

這可能是問題的最困難的部分,一旦你有這個工作了,剩下的應該是更簡單。我會給你一些更多的提示:

停車場收取最低費用2美元,最多停放3小時 小時。

基本上只是一個統一費率:無論如何,描述成本的輸出變量應該至少等於2.00

該車庫每小時額外收費0.50美元,每小時 或部分超過三小時。

計算過去三小時過去的小時數 - 從elapsedTime減去180。如果這大於0,則將其除以60並將結果存儲在float(因爲它不一定是整數結果),稱爲excessHours。使用excessHours = floor(excessHours) + 1;將此數字向上取整。現在乘以0.5;這是額外的成本。 (試着理解爲什麼這在數學上工作)。

給定24小時內任何 的最大費用爲10.00美元。停車時間長於 的人比24小時後每天支付8.00美元。

我會留下這個給你解決,畢竟這是作業。希望我已經在這裏爲您提供了足夠的東西來獲得需要做的事情。這個問題也有很多可能的解決方案,這只是一個,可能會或可能不是「最好的」。

+0

非常感謝你幫助我!我對數學不太確定,但你如何解釋這個數字很有意義。對此,我真的非常感激。 – user1311854 2012-04-06 06:21:12

+0

樂意幫忙! :) – 2012-04-06 06:26:21

+0

你好,我非常感謝你給我的所有幫助,但我仍然完全迷失。我不知道該怎麼做,甚至不知道你做了什麼。在以正確的格式輸入字符串後,如何使用該字符串以及如何使用計算? – user1311854 2012-04-07 09:20:12

0

您不需要執行單獨的輸入讀取和解析操作。您可以通過引用傳遞必要的變量,並使用stringstream將輸入直接讀入變量。我會使用一個結構來存儲日期和時間,並用算法減去兩個日期/時間值來重載operator-。這是我會怎麼做:

#include <iostream> 
#include <sstream> 

using namespace std; 

struct DateTime { 
    // Variables for each part of the date and time 
    int year, month, day, hour, minute; 

    // Naive date and time subtraction algorithm 
    int operator-(const DateTime& rval) const { 
     // Total minutes for left side of operator 
     int lvalMinutes = 525600 * year 
         + 43200 * month 
         + 1440 * day 
         + 60 * hour 
         + minute; 

     // Total minutes for right side of operator 
     int rvalMinutes = 525600 * rval.year 
         + 43200 * rval.month 
         + 1440 * rval.day 
         + 60 * rval.hour 
         + rval.minute; 

     // Subtract the total minutes to determine the difference between 
     // the two DateTime's and return the result. 
     return lvalMinutes - rvalMinutes; 
    } 
}; 

bool inputDateTime(DateTime& dt) { 
    // A string used to store user input. 
    string line; 
    // A dummy variable for handling separator characters like "/" and ":". 
    char dummy; 

    // Read the user's input. 
    getline(cin, line); 
    stringstream lineStream(line); 

    // Parse the input and store each value into the correct variables. 
    lineStream >> dt.year >> dummy >> dt.month >> dummy >> dt.day >> dummy 
       >> dt.hour >> dummy >> dt.minute; 

    // If input was invalid, print an error and return false to signal failure 
    // to the caller. Otherwise, return true to indicate success. 
    if(!lineStream) { 
     cerr << "You entered an invalid date/time value." << endl; 
     return false; 
    } else 
     return true; 
} 

從這裏開始,在main()功能,聲明兩個DateTime結構,一個用於輸入時間,一個是退出時間。然後在DateTime中讀取,從退出時間中減去輸入時間,並使用結果生成正確的輸出。