2013-09-25 34 views
1

我正在尋找清理一些已經運行的代碼,我有。首先,這是一個賦值,賦值指定整數必須作爲整數,雙精度等等,否則我可能只是將輸入作爲雙精度來投射,如同int if(number%1==0)C + + int或雙輸入

我已經將代碼修剪成只處理輸入(使用輸出語句來驗證它是否正常工作)。

int wholePart=0; 
double decimalPart=0; 
cout << "Input a number: "; 
cin >> wholePart; 
if(cin.peek() != '\n') 
    cin >> decimalPart; 

cout << "wholePart = " << wholePart << endl << "decimalPart = " << decimalPart << endl; 

現在...這是是利國利民的,經過我添加代碼來處理相結合的整數和小數,如果decimalPart不爲0的話,我已經做了超過轉讓要求,但我期待學習,並且我想盡可能地清理這些代碼。

我可以用其他輸入驗證來包裝整個輸入部分,以確保用戶實際上輸入的是數字而不是字符。但我主要關心的是if(cin.peek() != '\n')不夠好。也許if(cin.peek() == '.')是一個更好的選擇,但我很好奇什麼是完成我在這裏完成的工作的最佳方式。有任何想法嗎?

請不要只是把它寫成「哦,它是作業」。我想強調的是,我的計劃已經超出了功課額外的功勞部分。我只是想了解更多關於該語言的信息,以及處理這種輸入的最佳方式。

回答

2

我猜想類似"1.0"應該被視爲 雙爲好;這幾乎消除了諸如 讀取double之類的東西,然後檢查它是否實際上是一個整數。

唯一的辦法是解析數據,看看你是否遇到 東西,可以解釋爲int或不。如果你要使用流的轉換功能,這個漂亮的意思就是掃描輸入兩次。明顯的解決方案是 是將輸入放入一個字符串;這些很容易 掃描多次。如果您不允許這樣做,您可以使用 使用istream::tellg記住位置,向前掃描,並且您已經決定 ,istream::seekg可以返回到您開始從 開始的位置。但我不知道你的教練施加了什麼規則。

如果你找不到,你可以嘗試手動黑客入侵。首先閱讀 和int,然後偷看下一個字符。如果它是'.',那麼您的 可以讀取一個double,它將爲您提供小數部分 ,您可以將其添加到您已閱讀的整數中。如果它是 和'E'或和'e',它會變得更加困難;你可能需要提前 ,讀一個int,並手動使用pow。 但是這還不夠完美:如果雙數的形式爲 "1.2E6",那麼最終將以200000作爲「分數」部分; 你需要一些檢測這個的方法,並且縮放你已經讀取的 整數。如果數字爲".3",則在讀取整數時會出現一個錯誤:您可以事先檢查 (但不要忘記"-.3"),或者在執行其他任何操作之前重置錯誤 。當然,有可能 雙倍的組成部分不適合int(或甚至 a long long)。

總而言之,這對我來說似乎有點虛僞。在實踐中,您將 讀入一個字符串,並在 中與其匹配正則表達式,以確定您想如何解釋它。

+0

我同意在整體上它看起來很人造,當然不是我在做任務的限制之外做的。您能否更詳細地向我解釋tellg和seekg函數的作用以及如何正確使用這些函數? – nhgrif

+0

@nhgrif它們是'std :: istream'的標準成員函數:第一個返回當前位置(作爲std :: streampos),第二個從先前的調用中獲取std :: streampos到'告訴',並在那裏進行下一次閱讀。 –

+0

謝謝。我想我可能會實現'tellg'和'seekg',而不是像我的任務那樣額外增加額外的部分,因爲這似乎更有可能在if(cin.peek()==')方面具有更多的未來用處。 ')'方法。 – nhgrif

1

它可能更容易在整行中作爲字符串讀取,檢查一個小數點,然後將該行送入一個字符串流,然後可以將其轉換爲int或double(取決於小數點是提供):

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

using namespace std; 

int main() { 
    string line; 
    int anInteger; 
    double aDouble; 

    getline(cin, line); 
    stringstream ss(line); 
    if (line.find('.') == string::npos) { 
    ss >> anInteger; 
    } else { 
    ss >> aDouble; 
    } 

    return 0; 
} 
+0

讀一個字符串是我的第一個想法,也是我會做的,但同樣,這個特定的賦值明確指出輸入不能作爲字符串處理。不過謝謝。 – nhgrif

0

鑑於你的規範,我會讀一個std::string,看看有沒有什麼能比一個整數別的東西,並根據結果解析爲intdouble。例如

int   integer; 
double  number; 
std::string value; 
if (std::cin >> value) { 
    if (value.find_first_of(".Ee")) { 
     if (std::istringstream(value) >> number) { 
      std::cout << "read double=" << number << '\n'; 
     } 
     else { 
      std::cout << "failed to read double from '" << value << "'\n"; 
     } 
    } 
    else { 
     if (std::istringstream(value) >> integer) { 
      std::cout << "read integer=" << integer << '\n'; 
     } 
     else { 
      std::cout << "failed to read integer from '" << value << "'\n"; 
     } 
} 
+0

讀一個字符串是我的第一個想法,也是我會做的,但是這個特定的賦值語句明確指出輸入不能作爲字符串處理。不過謝謝。 – nhgrif