在函数中使用cin / cout流

时间:2015-09-17 05:17:03

标签: c++

我在学校被教导使用cin / cout来获取功能并在功能中向用户显示信息被认为是不好的做法。我被告知所有输入/输出都应该在main函数中完成。

这是真的吗?为什么?

2 个答案:

答案 0 :(得分:2)

典型的学校,这是一个过于简单化。真正意味着可能是那个

  

输入/输出应与数据处理分开。

这可以通过一个例子轻松说明:

错误:

void doStuff() {
    std::string input;
    std::cout << "Please provide input: ";
    std::cin >> input;

    for (int i = 0; i < input.size(); i += 2) {
        input[i] = ' ';
    }

    std::cout << input << std::endl;
}

int main() {
    doStuff();
}

好多了:

std::string getInput() { 
    std::string input;
    std::cin >> input;
    return input;
}

std::string processData(std::string input) {
    for (int i = 0; i < input.size(); i += 2) {
        input[i] = ' ';
    }
    return std::move(input);
}

void printOutput(std::string const& s) {
    std::cout << s << std::endl;
}

int main() {
    auto input = getInput();
    auto output = processData(input);
    printOutput(output);
}

通过这种方式,您可以轻松地单独模拟或测试每个函数,现在更容易添加输入验证。

std::string getInput() { 
    std::string input;
    if (!(std::cin >> input)) {
        throw std::runtime_error("Input problem!");
    }

    if (input.empty()) {
        throw std::length_error("Input can't be empty!");
    }

    return input;
}

作为附注,main也可以写成:

int main () {
    printOutput(processData(getInput()));
}

答案 1 :(得分:0)

您的老师最有可能阻止像

这样的代码
void add(void) {
  int a, b;
  cin >> a >> b;
  cout << (a + b) << endl;
}

这是初学者程序员经常看到的。这段代码的不好之处在于,它一方面说谎(因为它没有添加,它读取,添加和打印 em>)另一方面滥用最重要的抽象工具,功能:

一个函数旨在解决一个任务(可能很复杂并且由子任务组成)并且更多地过度保持该术语的数学起源 - 作为一种给定的转换某些结果的参数,理想情况下就像纯函数式语言一样,不会改变我们的状态。 (无论何时,何时以及在何种情况下,您致电f(a),如果您一旦获得b结果,那么每当您使用{f致电时,您都会得到a {1}})

将其应用于简单示例

int add(int lhs, int rhs) {
  return lhs + rhs;
}

尽管如此,我们还是需要访问现实世界(这是非常有状态的),所以对于像以下这样的事情,可以在函数中使用IO:

int askInteger(void) {
  int result;
  cout << "Please give me an integer!";
  cin >> result;
  return result;
}

请注意,这只是一个相对愚蠢的例子,没有任何错误处理或参数化。

为了更接近功能风格,建议不要像上面那样硬编码IO的源和目标,而是将它们作为参数传递:

int askInteger(std::istream & from, std::ostream & to) {
  int result;
  to << "Please give me an integer!";
  from >> result;
  return result;
}
// called like
askInteger(cin, cout);