0

Question: why does it print out the correct values inside the while loop (while reading / inputting the file) but not outside the while loop? I don't understand. Thank you very much for any help.

input file:

1
2
3
4
5

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

using namespace std;

int sumNumbers(int sum, int* numbers, int numElements, int count) 
{
    if (count == numElements)   return sum;

    sumNumbers(sum + numbers[count], numbers, numElements, count + 1);

    return 0;
}

int main(int argc, char* argv[]) 
{
    int* numbers;
    int numElements = 0;; 
    int sum = 0;

    string fileName = argv[2];

    ifstream ifile(fileName);

    if( ifile.fail() ) {    
        cout << "The file could not be opened. The program is terminated." << endl;
        return 0;
    }

    while ( !ifile.eof() ) {
        numbers = new int[++numElements];
        ifile >> numbers[numElements - 1];
        cout << "Position " << numElements - 1 << ": " << numbers[numElements - 1] << endl;
    }

    cout << numbers[0] << endl;
    cout << numbers[1] << endl;
    cout << numbers[2] << endl;
    cout << numbers[3] << endl;
    cout << numbers[4] << endl;

    cout << "--------------\n";

    for(int i = 0; i < numElements; i++) {
        cout << "Position " << i << ": " << numbers[i] << endl;
    }

    sumNumbers(sum, numbers, numElements, 0);

    cout << "The sum of the numbers in the file is: " << sum << endl;

    return 0;
}

output:

Position 0: 1
Position 1: 2
Position 2: 3
Position 3: 4
Position 4: 5
0
-805306368
0
-805306368
5
--------------
Position 0: 0
Position 1: -805306368
Position 2: 0
Position 3: -805306368
Position 4: 5
The sum of the numbers in the file is: 0
juanchopanza
  • 223,364
  • 34
  • 402
  • 480

2 Answers2

2

You are instantiating (and leaking) a new array in each loop iteration. And you only fill one element of that array. After the loop ends, you are left with the final array, with only the last element set.

There are many questions on SO that deal with the problem of reading numbers from a file into an array or container. Here, numbers are read into an std::vector.

#include <fstream>
#include <vector>
#include <iterator>
#include <iostream>
#include <algorithm>

int main()
{
    std::vector<int> numbers;
    ifstream ifile(fileName);
    std::istream_iterator<int> eof;
    std::istream_iterator<int> it(ifile);
    std::copy(it, eof, std::back_inserter(numbers));

    for(int i = 0; i < numbers.size(); ++i) 
    {
        cout << "Position " << i << ": " << numbers[i] << endl;
    }

}

Alternatively, you can replace the istream_iterators and the call to std::copy by a while loop:

int n=0;
while (ifile >> n) {
  numbers.push_back(n);
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
1

This part:

while ( !ifile.eof() ) {
        numbers = new int[++numElements];
        // ...

repeatedly allocates memory for numbers. At each new, previous values are lost, and the memory from the previous allocation is leaking. You can print the value correctly before the next call to new so it seems to work within the loop.

It is better to use a vector:

int new_number;
while ( ifile >> new_number) {
        numbers.push_back(new_number);
        // ...

and don't use file.eof() in the while condition.

Community
  • 1
  • 1
perreal
  • 94,503
  • 21
  • 155
  • 181
  • Thank you very much! How come I should not use file.eof()? And, what do you recommend I do instead? (In general... I see what you used here). Also, I don't quite understand the statement "while (file >> new_number). @perreal – Rafael Vergnaud Aug 04 '14 at 07:15
  • `ifile >> new_number` will evaluate to false when the operation is not successful so you can check this in the while condition as I did above. `eof()` will not tell you whether the next read operation will be successful or not, it is the status of the previous read. – perreal Aug 04 '14 at 07:27