我在学校被教导使用cin
/ cout
来获取功能并在功能中向用户显示信息被认为是不好的做法。我被告知所有输入/输出都应该在main
函数中完成。
这是真的吗?为什么?
答案 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);