gpt4 book ai didi

c++ - 出于不同目的重复读取由空格(或其他分隔符)分隔的 double 列表

转载 作者:行者123 更新时间:2023-11-30 04:35:19 25 4
gpt4 key购买 nike

我是 C++ 的新手,遇到了以下问题。

我的目标:我想要一个执行以下操作的代码:

  1. 用户输入包含以某种方式分隔的 double 的行
  2. double 被解析成 double 数组
  3. 对数组进行计算(*)。例如它的总和
  4. 如果用户没有中断循环,它会读取一个新行,然后循环回到 1。
  5. 一旦用户打破了第一个循环(通过输入空行或类似的东西),一个新的循环开始。
  6. 用户输入包含以某种方式分隔的 double 的行
  7. double 被解析成 double 数组
  8. 对数组进行计算(**)。例如它的平均值。
  9. 用户停止第二个循环。
  10. 程序退出。

我的代码:

#include <iostream>

int main()
{
do {
double x1, x2, x3, y1, y2, y3;
std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
if (!std::cin){
break;
}
std::cout << "\n The sum is: " << (x1+y1+x2+y2+x3+y3) << "\n";
} while (1);

do {
double x1, x2, x3, y1, y2, y3;
std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
if (!std::cin){
break;
}
std::cout << "\n The average is: " << (x1+y1+x2+y2+x3+y3)/6 << "\n";
} while (1);
return 0;
}

问题:当我尝试停止第一个循环,并通过点击 CTRL-D 或输入一个字母进入第二个循环时,程序退出并跳过第二个循环。我意识到它与cin机制有关,但我未能治愈它。

问题:我应该如何对此进行编程?克服这个问题最不痛苦的方法是什么?提前致谢!

最佳答案

The Problem: When I try to stop the first loop, and move to the second by either hitting CTRL-D or giving a letter as input, then the program quits and skips the second loop. I realized that it relates to the cin mechanism, but I failed to cure it.

这是因为当您尝试读取一个字母或 EOF (Ctrl-D) 时,这会将流的状态设置为错误状态。一旦发生这种情况,流上的所有操作都会失败(直到您重置它)。这可以通过调用 clear() 来完成

std::cin.clear();

The question: How should I program this? What is the least painful manner to overcome the problem?

我不会使用这种技术。
我会使用类似空行的东西作为循环之间的分隔符。因此代码看起来像这样:

while(std::getline(std::cin, line) && !line.empty())
{
// STUFF
}
while(std::getline(std::cin, line) && !line.empty())
{
// STUFF
}

试试这个:
注意:在 C++ 中,当数字以空格分隔时,流工作得最好。因此,只需使用空格或制表符分隔数字即可。

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

struct Average
{
Average(): result(0.0), count(0) {}
void operator()(double const& val) { result += val;++count;}
operator double() { return (count == 0) ? 0.0 : result/count;}
double result;
int count;
};
struct Sum
{
Sum(): result(0.0) {}
void operator()(double const& val) { result += val;}
operator double() { return result;}
double result;
};

int main()
{
std::string line;

// Read a line at a time.
// If the read fails or the line read is empty then stop looping.
while(std::getline(std::cin, line) && !line.empty())
{
// In C++ we use std::Vector to represent arrays.
std::vector<double> data;
std::stringstream lineStream(line);

// Copy a set of space separated integers from the line into data.
// I know you wanted doubles (I do this next time)
// I just wanted to show how easy it is to change between the types being
// read. So here I use integers and below I use doubles.
std::copy( std::istream_iterator<int>(lineStream),
std::istream_iterator<int>(),
std::back_inserter(data));

// Sum is a functor type.
// This means when you treat it like a function then it calls the method operator()
// We call sum(x) for each member of the vector data
Sum sum;
sum = std::for_each(data.begin(), data.end(), sum);
std::cout << "Sum: " << static_cast<double>(sum) << "\n";
}

// Read a line at a time.
// If the read fails or the line read is empty then stop looping.
while(std::getline(std::cin, line) && !line.empty())
{
// In C++ we use std::Vector to represent arrays.
std::vector<double> data;
std::stringstream lineStream(line);

// Same as above but we read doubles from the input not integers.
// Notice the sleigh difference from above.
std::copy( std::istream_iterator<double>(lineStream),
std::istream_iterator<double>(),
std::back_inserter(data));

// Average is a functor type.
// This means when you treat it like a function then it calls the method operator()
// We call average(x) for each member of the vector data
Average average;
average = std::for_each(data.begin(), data.end(), average);
std::cout << "Average: " << static_cast<double>(average) << "\n";
}
}

//或者我们可以稍微模板化代码:

template<typename T, typename F>
void doAction()
{
std::string line;

// Read a line at a time.
// If the read fails or the line read is empty then stop looping.
while(std::getline(std::cin, line) && !line.empty())
{
std::stringstream lineStream(line);

// F is a functor type.
// This means when you treat it like a function then it calls the method operator()
// We call action(x) for each object type 'T' that we find on the line.
// Notice how we do not actual need to store the data in an array first
// We can actually processes the data as we read it from the line
F action;
action = std::for_each( std::istream_iterator<T>(lineStream),
std::istream_iterator<T>(),
action);
std::cout << "Action Result: " << static_cast<double>(action) << "\n";
}
}

int main()
{
doAction<int, Sum>();
doAction<double, Average>();
}

关于c++ - 出于不同目的重复读取由空格(或其他分隔符)分隔的 double 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5391538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com