我从一个文件中读取数字,应用3个函数并打印到另一个文件:
int main(int argc, char** argv) {
std::ifstream fin;
fin.open("input.txt");
std::ofstream fout;
fout.open("output.txt", std::ios::app);
char arr[50];
int a,b;
int N;//number to factor
while (!fin.eof()){
//Print backward
fin >> arr;
PrintBackward( arr );
fout << endl;
//Greatest common divisor
((fin >> a) >> b);
fout << gcd( a, b );
fout << endl;
//Find prime factor
fin >> N;
PrimeFactor(N);
fout << endl;
}
fin.close();
fout.close();
return 0;
}
运行后,结果重复:
olleh
3
2 3 7
olleh
3
2 3 7
我读过一篇类似的文章,但它是关于读取到一个变量,所以似乎不可行。
如果我在while
循环的末尾设置一个break
,它是好的。有没有办法不使用break
?
while (!whatever.eof())
基本上总是错误的,并且永远不会正确地检测文件的结尾。在您的情况下,最简单的方法是将读取合并在一起,然后执行所有处理,如下所示:
while (fin >> arr >> a >> b >> N) {
PrintBackwards(arr);
fout << "n";
fout << gcd(a, b) << "n";
fout << PrimeFactor(N) << "n";
}
关键的部分是检查读取的结果,而不是分别检查和读取。
更多的建议:我会使用std::string
而不是数组。我还将反转字符串与打印字符串分开,因此您可以拥有如下内容:
fout << reverse(arr) << "n"
<< gcd(a, b) << "n"
<< PrimeFactor(N) << "n";
强调操作之间的共性往往是一件好事。
编辑:为了好玩,如果你想的话,我会指出另一种你可以做的方法。由于您基本上是作为一个组来读取和处理这四个条目,因此您可以使分组更明确一些:struct item {
std::string arr;
int a, b, N;
friend std::istream &operator>>(std::istream &is, item &i) {
return is >> arr >> a >> b >> N;
}
};
struct process {
std::string operator()(item const &i) {
std::ostringstream buffer;
buffer << reverse(arr) << "n" << gcd(a, b) << "n" << PrimeFactor(N);
return buffer.str();
}
}
有了这个,你可以让标准库处理所有的读写细节,检查文件结束等:
std::transform(std::istream_iterator<item>(fin),
std::istream_iterator<item>(),
std::ostream_iterator<std::string>(std::cout, "n"),
process());
我猜您检查eof太早了—它只在您尝试读取并且读取失败时设置,因为您在文件的末尾。试着在fin >> arr
:
if (fin.eof()) break;
实际上,您应该在每次IO操作后检查错误-不这样做是草率的编码,并且不会健壮