The previous solution, although entirely correct, does not explain why that second test is necessary. Here is the full story:
After you have read the last character of the stream by
infile.get (ch);
the stream is
not yet in the end-of-file state. So the next loop iteration will still occur. Only after get attempts to read beyond the stream end the eof flag in the stream will be set. In that last iteration, in which get hits the end-of-file, ch will be set to the value EOF instead a valid character. And that EOF value (usually a -1) is what you see in your output.
In fact you could have written your loop with only one test like this:
while (true)
{
infile.get (ch);
if (!infile.good())
break;
outfile.put (ch);
}