這裏有幾種解決方案。我會發布其中2個。由於stod
函數,第一個解決方案需要C++ 11標準。你可以這樣做,通過-std=c++11
標誌gcc
或clang++
。微軟編譯器默認啓用C++ 11。
解決方案1 。它由通過cin >> input_string
並使用標準C++ 11函數stod
一直讀取字符串。 stod代表字符串翻倍。如果stod
無法解析double
,則會拋出std::invalid_argument
異常。
這種解決方案會是這樣的:
#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <stdexcept>
using namespace std;
int main() {
vector<double> vec;
string input;
try {
while (getline(cin, input)) {
vec.push_back(stod(input));
}
}
catch (std::invalid_argument &) {
cout << "Invalid argument caught\n";
//Failed to parse a double
}
//If pressed Ctrl+D (in linux, which sends EOF), failbit and eofbit are set
//If it is through invalid_argument the way the loop was exit, then,
//eof and failbit are not set and cin can be used without clearing.
double average = accumulate(vec.begin(), vec.end(), 0.0)/vec.size();
cout << "EOF: " << cin.eof() << endl;
cout << "Fail: " << cin.fail() << endl;
//Clean eof and failbit to be able to use cin again
cin.clear();
cout << "EOF after cleaning: " << cin.eof() << endl;
cout << "Fail after cleaning: " << cin.fail() << endl;
cout << average << endl;
}
編輯:我測試,當你把每行有多個號碼,將只得到第一個未拋出std::invalid_argument
。它只會在線條以非雙線開始時開始線條時拋出std::invalid_argument
。這是因爲stod
函數的行爲如下所示:stod reference。
請注意,此解決方案只允許讀取每行兩個。
解決方案2。直接使用cin >> input_double
閱讀。這可能會失敗。請注意,iostream
s在C++中默認不使用exceptios。您可以使用api激活它們,但我不建議您這樣做,因爲您可以在本地管理所有錯誤處理。
您可以讀取任何數量的任何空格分隔雙打:
#include <iostream>
#include <vector>
#include <numeric>
#include <limits>
using namespace std;
int main() {
double x = 0.0;
vector<double> data;
//cin will fail to read the first non-double in the input.
//You can input as many doubles as you wish. Spaces will
//be ignored. At the first non-double, cin will fail to read
//and will exit the loop, setting istream::failbit.
//Alternatively, you can send EOF (Linux is Ctrl+D) and the loop also will finish.
while (cin >> x) {
data.push_back(x);
}
double average = accumulate(data.begin(), data.end(), 0.0)/data.size();
//If you wanted to use again cin, you should:
//1. Clear failbit. You can do like this:
cin.clear();
//2. Cleaning the remaining input. Will stop when finding end of line.
string rubbish;
geline(cin, rubbish);
//cin is usable here again if you need it and with the input clean already.
cout << average << '\n';
}
你可以給像這樣在輸入時,某行:
1 2.4 -38.7 5.8 28.9打招呼。
會發生什麼?循環將消耗到28.9,停在你好。之後,failbit被設置。我們清理故障位以便能夠繼續讀取直到行結束。既然你好被認爲是「垃圾」,因爲我們想讀雙打,所以我們用getline
清理它,我們可以再次使用cin
沒有麻煩。
'typeid(x)'取決於'x'的*類型*,它由您聲明'x'首先確定的內容決定。 – juanchopanza
你如何區分輸入的int,float和double?例如,如果我輸入2.0,那麼你認爲它是什麼? –
juanchopanza:那麼我該如何檢查用戶的輸入是不是雙精度? –