当前正在研究从Stroustrup的介绍到C ++的练习,它要求:写一个给定两个向量的函数,price和weight计算一个值(“索引”),该值是所有price [i] * weight [一世]。确保具有weight.size()== price.size()
vector<double> weight;
vector<double> price;
void read_weight() {
cout << "Input weight" << '\n';
for (double weights; cin >> weights; ) {
weight.push_back(weights);
if (!(cin >> weights)) {
cin.clear();
cin.ignore(numeric_limits<double>::max(), '\n' );
break;
}
}
}
void read_price() {
cout << "Input price" << '\n';
for (double prices; cin >> prices; ) {
price.push_back(prices);
if (!( cin >> prices)) {
cin.clear();
cin.ignore( numeric_limits<double>::max(), '\n' );
break;
}
}
}
void calculate() {
double sum = 0;
for (int i = 0; i < price.size(); ++i)
sum += price[i] * weight[i];
cout << "Sum is " << sum << '\n';
}
int main() {
read_weight();
read_price();
calculate();
}
这是我当前拥有的代码,但是我无法弄清楚如何正确终止输入。在之前的章节中,他的书中提到您可以使用输入(除了双精度字之外)来终止(例如|)。但是,我了解到这只会使cin进入失败状态,并且不允许我进入价格函数。不幸的是,这本书到目前为止还没有介绍如何处理这个问题,所以我只是复制了有关cin.clear和cin.ignore的代码,希望它能起作用。但这没什么用。我注意到,如果我将向量更改为int而不是double,并且实际上因行为差异而感到困惑,那么实际上允许我输入一个。我想知道是否有人可以给我提示如何解决此问题?
答案 0 :(得分:2)
您可以使用std :: getline将cin的整行读取为字符串。此后,您需要确定输入的行是否为双精度行。我通常不建议对正则表达式使用太多内容(我在C ++中不经常使用它们),但是在这种情况下,我认为这是一个非常简单而合理的解决方案。如果字符串的格式为“ 32.23”(数字点数字),则可以使用std :: stod将其转换为双精度,将其压入向量并继续从cin读取。如果不是,则中断循环并继续执行程序流程。
远离使用全局变量,使用局部变量并将其传递给周围环境。
此外,请注意您的函数read_price和read_weight几乎相同。在这种情况下,您绝对只想编写一个(参数化的)函数。在这种情况下,您甚至都不需要参数,只需对两者使用相同的函数即可。
(您还可以将值直接从流(std :: cin)中读入双变量,由于您需要较少的转换,这可能被认为是更优雅的方法,但是下面的方法很简单,您不必担心在std :: cin中输入了什么)
#include <vector>
#include <string>
#include <iostream>
#include <regex>
std::vector<double> get_doubles_from_cin(){
std::vector<double> doubles;
std::regex double_regex ("\\d+\\.\\d+");
std::string input;
while(std::getline(std::cin, input)){
if (std::regex_match(input, double_regex)){
doubles.push_back(std::stod(input));
}
else{
break;
}
}
return doubles;
}
void calculate(std::vector<double>& weights, std::vector<double>& prices) {
double sum = 0;
for (int i = 0; i < prices.size(); ++i) {
sum += weights[i] * prices[i];
}
std::cout << "Sum is " << sum << '\n';
}
int main() {
std::cout << "Enter weights" << std::endl;
auto weights = get_doubles_from_cin();
std::cout << "Enter prices" << std::endl;
auto prices = get_doubles_from_cin();
calculate(weights, prices);
}
答案 1 :(得分:2)
您已经在那儿了。我已经写了read_weights()
的评论替代品;您应该可以从那里拿走它。
#include <vector>
#include <limits>
#include <iostream>
// Use return values instead of working on global variables.
// Avoid using global variables whenever possible, they are a
// maintenance pain.
std::vector< double > read_weights()
{
std::vector< double > weights;
double weight;
// You can embed the \n right in the string, no need to put it as a
// separate character.
std::cout << "Input weights; enter a non-number to terminate input.\n";
// If anything not double is entered, cin goes into fail state --
// that is our terminating condition right there, so use it!
while ( std::cin >> weight )
{
weights.push_back( weight );
}
// Clean up cin
std::cin.clear();
// Use the correct type for max(); you had 'double' here...
cin.ignore( numeric_limits< std::streamsize >::max(), '\n' );
// Don't worry about the apparent copying of the vector upon return.
// Any modern compiler should be able to optimize this away.
return weigths;
}
一个简单的main()进行测试:
int main()
{
std::vector< double > weights = read_weights();
std::cout << "Vector contents:\n";
for ( auto & v : weights )
{
std::cout << v << "\n";
}
}
现在您所需要添加的只是一个read_price()
...现在等等,您不是吗?由于您实际上所做的只是与read_weights()
中的事情相同,因此请输入两倍!因此,将输入提示移出read_weights()
,并使其成为 one 函数read_values()
,您可以调用它两次,一次获取weights
,一次获取{{ 1}} ...
prices
对于int main()
{
std::cout << "Enter weights; enter a non-number to terminate input.\n";
std::vector< double > weights = read_values();
std::cout << "Enter prices; enter a non-number to terminate input.\n";
std::vector< double > prices = read_values();
// ...
}
函数,对参数使用引用,这样就不必复制向量:
calculate
一旦这一切运行起来,请记住,以后,您(至少应该是 )将学习void calculate( std::vector<double> & weights, std::vector<double> & prices )
,函子和lambda。 。它应该消除对<algorithm>
的需求,并用一个优雅的单行代码代替它……但这还没有到来,在这一点上,我不想让您感到困惑。