-2

This seems like such an easy task, but everything I've tried hasn't worked so far.

I have a file foo.txt:

3
3 4 2

Now I want to read this file, read the first line and instantiate an int array with the size of the number it read on the first line. Then it should populate that array with the elements in the second line, which has the exact same amount of elements and noted in line one.

cherrun
  • 2,102
  • 8
  • 34
  • 51
  • 1
    Could you share some of your solutions that haven't worked? – Jimbo Oct 24 '13 at 15:29
  • 3
    _This seems like such an easy task_ still you never searched this on SO, several questions related to this – P0W Oct 24 '13 at 15:30
  • @P0W I actually did. I tried for the last 3 hours. Here are the readings I did: http://stackoverflow.com/questions/890164/how-can-i-split-a-string-by-a-delimiter-into-an-array, http://stackoverflow.com/questions/11546177/how-to-read-lines-of-text-from-file-and-put-them-into-an-array, http://stackoverflow.com/questions/7868936/c-read-file-line-by-line and several others. The main reason is, I'm not used to C/C++ and the weird file handling (`fstream`, `iostream`) – cherrun Oct 24 '13 at 15:37
  • If you tried searching for `[c++] file number` you would have found http://stackoverflow.com/questions/3125810/reading-a-number-from-file-c which answers half your question. – Ben Voigt Oct 24 '13 at 15:51
  • @BenVoigt I literally copy pasted the solution from your suggested question, and it only returns `0`, no matter what value I have in my text file. – cherrun Oct 24 '13 at 15:55
  • 1
    @cherrun: Yes, the value is put in the variable, not in the return code from `main`. And did you remember to fix the filename? – Ben Voigt Oct 24 '13 at 15:59

4 Answers4

2

If we're going to give you example code, might as well show you the best way to do it:

std::ifstream datafile("foo.txt");

if (!datafile) {
    std::cerr << "Could not open \'foo.txt\', make sure it is in the correct directory." << std::endl;
    exit(-1);
}

int num_entries;
// this tests whether the number was gotten successfully
if (!(datafile >> num_entries)) {
    std::cerr << "The first item in the file must be the number of entries." << std::endl;
    exit(-1);
}

// here we range check the input... never trust that information from the user is reasonable!
if (num_entries < 0) {
    std::cerr << "Number of entries cannot be negative." << std::endl;
    exit(-2);
}

// here we allocate an array of the requested size.
// vector will take care of freeing the memory when we're done with it (the vector goes out of scope)
std::vector<int> ints(num_entries);
for( int i = 0; i < num_entries; ++i )
    // again, we'll check if there was any problem reading the numbers
    if (!(datafile >> ints[i])) {
        std::cerr << "Error reading entry #" << i << std::endl;
        exit(-3);
    }
}

Demo (with small changes because I can't provide a file with the right name on ideone): http://ideone.com/0vzPPN

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Ok. Now I'm pretty sure that something is wrong with my setup. I get errors like `No member named 'cerr' in namespace 'std'`, `No member named 'vector' in namespace 'std'; did you mean 'hecto'?`. – cherrun Oct 24 '13 at 16:02
  • @cherrun: Make sure you have `#include ` and `#include ` and `#include `. – Ben Voigt Oct 24 '13 at 16:02
  • Yeah, I missed that. Now my `datafile` is `nil/null` though. It just gives me the `Could not open...` error, although the files are definitely in the same folder. And yes, I did change the file name. – cherrun Oct 24 '13 at 16:14
  • 1
    @cherrun: Are you running the program from the command line or inside an editor environment? The editor might not be using the directory you expect... – Ben Voigt Oct 24 '13 at 16:17
0

You need to use ifstream object just like you use cin

ifstream fin("foo.txt"); //open the file
if(!fin.fail()){
    int count;
    fin>>count; //read the count
    int *Arr = new int[count];

    for(int i=0;i<count;i++){ //read numbers
        fin>>Arr[i];
    }
    //... do what you need ...

    //... and finally ... 
    delete [] Arr;
} 
SHR
  • 7,940
  • 9
  • 38
  • 57
0

If you open a file using input filestream you can simply do that:

std::ifstream file_txt("file.txt");

int number_count = 0;
file_txt >> number_count; // read '3' from first line

for (int number, i = 0; i < number_count; ++i) {
      file_txt >> number; // read other numbers
      // process number
}

Filestreams just like other standard streams (std::cin, std::cout) can apply formatting depending on type supplied to operator>> (in this case an int). This apply to both input and output.

0

Alternatively, you could avoid the entire need to read in the size beforehand by simply loading it into a std::vector:

std::ifstream fin("myfile.txt"); 
std::vector<int> vec{std::istream_iterator<int>(fin), std::istream_iterator<int>()};
fin.close();

or, if you cannot use C++11 syntax:

std::ifstream fin("myfile.txt");
std::vector<int> vec;
std::copy(std::istream_iterator<int>(fin), std::istream_iterator<int>(), std::back_inserter(vec));
fin.close();
Zac Howland
  • 15,777
  • 1
  • 26
  • 42