我从文件中读取数字,应用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
我读了一篇类似的文章,但它是关于读入1变量的,所以它似乎不可行。
如果我在break
循环结束时设置while
,那很好。有没有办法不使用break
?
答案 0 :(得分:3)
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());
答案 1 :(得分:0)
我的猜测是你过早检查eof - 它只在你尝试阅读时设置,并且因为你在文件末尾而读取失败。尝试在fin >> arr
之后添加此内容:
if (fin.eof()) break;
实际上你应该在每次IO操作后检查错误 - 不是这样做是编码粗糙而且不稳健。