开发者

ifstream random integers?

I have been trying to read in integers from a file do some operations and output them to another file. When I input the integers into an array and then print out the result of come up with random numbers. Is this something to do with ifstream that I don't understand or am I missing something obvious?

#include<iostream>
#include<fstream>
using namespace std;

int main(){
    int i=0, test[100];
    ifstream reader("in.txt");
    while(!reader.eof()){
        reader>>test[i];
        i++;
    }
    for(int x=0; test[x]!=-1; x++)
     开发者_如何转开发   cout<<test[x]<<endl;
    return 0;
}

in.txt sample:

1 4 3 2 9 8 18 22 0
2 4 8 10 0
7 5 11 13 1 3 0
-1

the 0 and -1 are sentinels for eol and eof respectively

If there is a much simpler way of doing this I would also like to know that. I am rather new to C++ and am hating the way arrays behave vs other languages.


sizeof(test)/sizeof(test[0])

This is a compile-time computation: it will always result in 100. If you want to know how many integers you actually read, you need to keep track of that yourself (or use a container that keeps track of it for you, like a std::vector).

In addition, testing .eof() in the loop condition is incorrect and the loop will not terminate at the correct time. If an extraction fails, the fail state on the stream will be set and further extractions will fail. The correct way to do this is:

// make sure to test the array bound and test that the extraction succeeded:
while((i < 100) && (reader >> test[i])) 
{
    i++;
}

You can then test the state of the stream to determine whether the loop ended due to an extraction failure or because EOF was reached. If neither was the case, then i should be 100 and you'll have filled the array.

You can read this article for details as to why this is the correct way to do this.


The obvious simpler way would be to use std::vector:

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

int main() { 
    std::vector<int> test;
    std::ifstream reader("in.txt");

    // read the data into the vector:
    std::copy(std::istream_iterator<int>(reader), 
              std::istream_iterator<int>(),
              std::back_inserter(test));

    // show the data in the vector:
    std::copy(test.begin(), 
              test.end(), 
              std::ostream_iterator<int>(std::cout, "\t"));

    // Just for fun, display the average of the numbers:
    std::cout << "Mean = " 
              << std::accumulate(test.begin(), test.end(), 0) / test.size();

    return 0;
}


Use a vector rather than a array.

vector<int> test

Are there actually 0's and a -1 in the file's text? I may misunderstand you on that point, but they shouldn't literally be in the text file.

So, try this:

#include<iostream>
#include<fstream>
#include<vector>
using namespace std;

int main(){
    int i=0, tmp;
    vector<int> test;
    ifstream reader("in.txt");
    while((i < 100) && (reader >> tmp)) 
    {
        test.push_back(tmp);
        i++;
    }
    for(int x=0; x < test.size(); x++)
        cout<<test[x]<<endl;
    return 0;
}

Your biggest flaw in your code is that you're using the size of the array after you set it to 100. This isn't the same as the number of integers read in, so it'll keep printing all 100 items in the array.

Edit added suggestion from other answer

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜