294

Read a file twice in C++ because of eof?

Question:

I read numbers from a file, apply 3 functions and print out to another file:

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; }

After running, the result is duplicated:

olleh 3 2 3 7 olleh 3 2 3 7

I read a similar article but it's about reading into 1 variable so it seems not to be feasible.

If I set a break at the end of the while loop, it's fine. Is there any way not to use break?

Answer1:

while (!whatever.eof()) is essentially always wrong, and will never detect the end of the file correctly. In your case, it's easiest to coalesce the reads together, and then do all the processing, something like this:

while (fin >> arr >> a >> b >> N) { PrintBackwards(arr); fout << "\n"; fout << gcd(a, b) << "\n"; fout << PrimeFactor(N) << "\n"; }

The crucial part is to check the result of the read, instead of checking and reading separately from each other.

A couple more bits of advice: I'd use an std::string instead of an array. I'd also separate reversing the string from printing it, so you can have something like:

fout << reverse(arr) << "\n" << gcd(a, b) << "\n" << PrimeFactor(N) << "\n";

Emphasizing the commonality between the operations tends to be a good thing.

Edit: Just for fun, I'll point out another way you could do things if you wanted. Since you're basically reading and processing the four items as a group, you could make that grouping a bit more explicit:

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(); } }

With this, you can let the standard library deal with all the details of the reading and writing, checking end of file, etc.:

std::transform(std::istream_iterator<item>(fin), std::istream_iterator<item>(), std::ostream_iterator<std::string>(std::cout, "\n"), process());

Answer2:

My guess is that you're checking eof too early - it's only set when you try to read and the read fails because you're at the end of the file. Try adding this after fin >> arr:

if (fin.eof()) break;

Actually you should be checking for errors after every IO operation - not to do so is sloppy coding and won't be robust.

Recommend

  • Remove border on activex ie control
  • Can I catch out of memory exception in Android in Bitmap allocation for decoding a picture file?
  • Angular 2: how to share one service among several components?
  • How to find the last occurrence of a certain observation in grouped data in R?
  • Using Linq to get the last N number of rows that have duplicated values in a field
  • How can I create a plugin mechanism that calls functions only when the plugin is available?
  • What is Closure Compiler?
  • How to use SBT with multiple sub project web applications?
  • Flex/AS3 very strange simple Number operation issue
  • Create a multiple screen android application
  • Facebook Messenger Platform - Detect user typing
  • Cassandra NoClassDefFoundError: com/google/common/util/concurrent/AsyncFunction
  • Scala: Function returning an unknown type
  • Unable to click on the next page button containing “>” sign
  • SPARQL date range
  • Less Conflicting Session Manager for Zope 2
  • Android Google Maps API v2 start navigation
  • Does Mobilefirst provide a provision to access web services directly?
  • how to avoid repetitive constructor in children
  • How to run “Deployd” on port 80 instead of port 5000 in webserver.
  • Spark fat jar to run multiple versions on YARN
  • Installing Hadoop, Java Exception about illegal characters at index 7?
  • Different response to non-authenticated users and AJAX calls
  • Optimizing database types to compact database (SQLite)
  • TFS: Get latest causes slow project reloading
  • Running a C# exe file
  • ActionScript 2 vs ActionScript 3 performance
  • How can I estimate amount of memory left with calling System.gc()?
  • Apache 2.4 - remove | delete | uninstall
  • php design question - will a Helper help here?
  • json Serialization in asp
  • AngularJs get employee from factory
  • How get height of the a view with gone visibility and height defined as wrap_content in xml?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Authorize attributes not working in MVC 4
  • Django query for large number of relationships
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Reading document lines to the user (python)
  • How can I use `wmic` in a Windows PE script?
  • How to push additional view controllers onto NavigationController but keep the TabBar?