2014-06-15 63 views
0

我有一個程序,我正在進行日期驗證。我以MM/DD/YYYY的形式接收用戶的輸入並將其存儲爲字符數組。如何獲得一個字符數組的特定索引的實際值

首先,我試圖用鑄造

char UserDate[10]; 
int month = 00, day = 00, year = 0000; 
cout << "Enter a date in the format of MM/DD/YYYY" << endl; 
cin >> UserDate; 
month = (int)UserDate[0] + (int)UserDate[1]; 
day = (int)UserDate[3] + (int)UserDate[4]; 
year = (int)UserDate[6] + (int)UserDate[7] + (int)UserDate[8] + (int)UserDate[9]; 

然後我試圖把它拆開分解成int對於月日和年變量,而鑄造

char UserDate[10]; 
int month = 00, day = 00, year = 0000; 
cout << "Enter a date in the format of MM/DD/YYYY" << endl; 
cin >> UserDate; 
month = UserDate[0] + UserDate[1]; 
day = UserDate[3] + UserDate[4]; 
year = UserDate[6] + UserDate[7] + UserDate[8] + UserDate[9]; 

的問題是我不能得到實際值超出數組的索引。 我得到的日期,結果進入01/01/2014如下:

month = 48'0' + 49'1'; //months value is 97 
day = 48'0' + 49'1'; //days value is 97 
year = 50'2' + 48'0' + 49'1' + 52'4'; //years value is 199 

這裏面有我上面是否投炭int或沒有這兩種方法。如何獲得存儲在我想要的索引中的值,因爲沒有UserDate[1].Value ??

+0

使用'scanf'讀入整數值。 –

+2

@JoelCornett他爲什麼要那樣做? –

回答

3

Casting不會將char轉換爲int。減去'0'以獲得int值。

month = 10 * (UserDate[0] - '0') + UserDate[1] - '0'; 
+0

b-e-a-u-tiful ..但爲什麼10 *?你能解釋爲什麼這個工作嗎? –

+0

@AndyLink由於數字小夥子的小數位!對於超過99的數字,使用額外的'100 *(UserDate [0] - '0')+ ...'! –

+0

大聲笑我沒有看到任何小數位的地方..我看到我的調試器爲什麼 - 0所以我明白了,但我仍然不明白10 *部分.. –

1

UserDate陣列實際上的字符陣列,每個由標準的ASCII碼錶示(見完整ASCII表here)。像你一樣使用顯式轉換的結果是將char(無論是字母還是數字)轉換爲整數ASCII代碼。

int digit = (int)UserDate[...] - '0' 
: - 例如字符「0」具有48的ASCII值,所以寫 (int)'0'等於48.

由於數字0-9在ASCII表順序地出現,可以通過寫入評估每個字符

這裏的數學非常簡單,所以我相信你理解爲什麼這是真的。

請注意,如果您的角色不是數字,則此轉換會導致一個負整數或大於9的數字,因此您應該檢查您收到的值是否有效。

0

您遇到的問題是,C不會以這種方式將字符轉換爲數字。 char是一個1字節的數字。 char是否有符號或無符號取決於您的編譯器,除非您在代碼中特別指定。如果我這樣做:

char x = '1'; 
int y = (int)x; 

我實際上有我的編譯器和我的平臺上的y = 49。這是字符1的ASCII值,爲了討論的目的,對於其他人可能會有所不同(具體來說,如果我使x爲無符號字符,我可能沒問題,並且1的ASCII值足夠低它可能是無論如何)。除非你知道你在做什麼,否則不要認爲字符會持有特定的價值。有些人使用它們作爲小整數,如果你理解ASCII,你可以做的技巧。在我看來,這些最好藏在圖書館裏,或者只在非常特殊的情況下使用。其次,你不能只添加鑄造值:即使假設鑄造工作,你要添加數字 - 在1999年,你的方法會給28。因爲它不,你是什麼gets是字符串那部分的ASCII值的總和。如果你想+連接字符串,你必須使用std::string來處理所有事情。否則,字符基本上是1個字節的整數。

如果您確實絕對肯定字符串有效,您可以執行以下操作。如果它無效,這會中斷,所以你需要驗證字符串。這是一個演示該技術的程序。這不是最好的編碼習慣:你應該使用std :: string,使parseDate成爲一個構造函數,並且做一些其他的事情。我保留了這個故意簡單的代價是一些好的設計實踐。在現實中,我建議尋找一個日期處理庫:boost.date_time是不是我已經使用過的,但根據我的經驗與其他部分的提振將使它成爲我的第一選擇。除非這是一個非常小的項目,否則您最終需要更多的功能,爲什麼要重新發明輪子?總之:

#include <stdio.h> 

class date { 
    public: 
    int day, month, year; 
}; 

date parseDate(const char* str) { 
    date d; 
    sscanf(str, "%i/%i/%i", &d.month, &d.day, &d.year); 
    return d; 
} 

void main() { 
    char test[255]; 
    scanf("%s", &test); 
    date d = parseDate(test); 
    printf("%i %i %i", d.day, d.month, d.year); 
} 

需要注意的是,至少在我看來,sscanfscanf實際上比很多cincout更強大的方式,對這種專門分析,並沒有引進外部庫,他們'幾乎總是我的第一選擇。既然你已經使用了一個char數組(這是不安全的,你應該使用std :: string),你不需要額外的轉換。如果您需要將std :: string傳入此目錄,請使用std :: string :: c_str(),如下所示:

string dateString; 
cin>>dateString; 
date d = parseDate(dateString.c_str()); 

希望這會有所幫助。

相關問題