Well, here is the gist of the problem. When I read in a file of integers, if there is a formatting character at the end, the last integer is repeated. For instance, in the code, it is reading i01.dat. If that file reads as follows:
2
3
4
5

with the newline character (or tab character, or whatever) at the end, then the five is printed twice when I cout the input even though I tried to use a break for the .eof() or .fail(). I have tried to use an if statement to test for \\n or \\t (i.e. if (i != \\n)) but the compiler does not understand this so I am obviously not testing properly. Please help me understand this. Here's what I've got so far.

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <cstdlib>
using namespace std;

struct CommandLineException
{
CommandLineException(int max, int actual)
  {
    cout << endl << "Too many command line arguments." << endl;
    cout << "A maximum of " << max << " arguments are permitted." << endl;
    cout << actual << " arguments were entered." << endl;
  }
};

struct FileException
{
  FileException(char* fn)
  {
    cout << endl << "File " << fn << " could not be opened." << endl;
  }
};

int main(int argc, char* argv[])
{

  try
  {
    char ifn[255], ofn[255];
    switch(argc)
    {
      case 1:
        cout << "Enter the input file name. ";
        cin >> ifn;
        cout << "Enter the output file name. ";
        cin >> ofn;
        break;
      case 2:
        strcpy(ifn, argv[1]);
        cout << "Enter the output file name. ";
        cin >> ofn;
        break;
      case 3:
        strcpy(ifn, argv[1]);
        strcpy(ofn, argv[2]);
        break;
      default:
        throw CommandLineException(2, argc - 1);
        break;
    }
    ifstream i(ifn); if(!i) throw FileException(ifn);
    ofstream o(ofn); if(!o) throw FileException(ofn);

    int testmsg;
    while (true)
    {
    if (i.eof()) break;
    i >> testmsg;
    cout << testmsg << " ";
    }

    o.close();
    i.close();
  }
  catch(...)
  {
    cout << "Program terminated." << endl;
    exit(EXIT_FAILURE);
  }

  return 0;
}

Dani AI

Generated

The symptom (the last integer printing twice) comes from testing eof() before attempting a read. eof() only becomes true after a read tries to go past end‑of‑file; if the final extraction fails the target variable is left unchanged, so the old value gets printed again. Attempts to test for '\n' failed because the code is doing formatted integer reads (comparing an int or a stream to a character is not the right approach), and calling the member incorrectly (for example writing !i.eof instead of !i.eof()) produces the compiler errors seen in the thread.

The reliable rule: test the extraction itself, not eof. For more robust behavior (skip blank lines, handle stray characters) parse line-by-line and then extract ints from each line. Example pattern:

#include <string>
#include <sstream>
#include <fstream>
#include <iostream>

std::ifstream in("i01.dat");
std::string line;
int v;

while (std::getline(in, line)) {
    std::istringstream iss(line);
    while (iss >> v) {
        std::cout << v << ' ';
    }
}

Notes and troubleshooting:

  • If using formatted extraction directly on the stream, only use the value after confirming the extraction succeeded; do not rely on eof() as a loop guard (this is the point was getting at).
  • If a malformed token is encountered and recovery is required, clear the error state and skip to the next line (call in.clear() and in.ignore(...)), then continue.
  • To inspect the next raw character use peek() or get() (useful only for character-level logic).

Following these patterns prevents the “repeat last value” problem and makes parsing resilient to trailing whitespace or stray characters (the issue mentioned about environment differences usually reflects fragile EOF handling, not a compiler bug).

Recommended Answers

All 4 Replies

int testmsg;
    while (true)
    {
    if (i.eof()) break;
    i >> testmsg;
    cout << testmsg << " ";
    }

Try

while(!eof)

or

do
{
i >> testmsg;
cout << testmsg << endl;
}while(testmsg);

Try

while(!eof)

I tried this one

while (!i.eof)
{blah blah}

and it tells me "invalid use of memeber (did you forget the '&' ?)'
"in argument to unary !"

I also tried this with

while (!eof)

and it tells me that this is " 'eof' undeclared (first use this function)"

or

do
{
i >> testmsg;
cout << testmsg << endl;
}while(testmsg);

I tried this one also and it works but with the same problem I originally described. Thanks for the response though.

try

while ( i >> testmsg )
{
..........
}

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.