0

I have generated a data.txt file that contains a huge number of integers into two columns.

How can I save these integers into arrays?

You can find the data.txt here if that helps. Sample:

600000
523887 283708
231749 419866
293707 273512
296065 215334
233447 207124
264381 460210
374915 262848
449017 329022
374111 151212
2933 496970

I have tried this but for some reason its not working..

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    fstream input("data-for-union-find.txt");
    int i=0;
    float a;
    int size=0;
    size=i/2;
    while (input >> a)
    {i++;
     }

    int *x=new int[size];
    int *y=new int[size+1];

    for(int j=0;j<(size+1);j++)
    {
        input>>x[j];
        input>>y[j];
        cout<<x[j]<<" "<<y[j]<<"              "<<j<<endl;
    return 0;
    }
}
Celeo
  • 5,583
  • 8
  • 39
  • 41
bjzero
  • 39
  • 2
  • 6
    `push_back` to `std::vector` is your friend – Ben Voigt Oct 28 '14 at 18:07
  • `std::vector myvector; std::copy(std::istream_iterator>(std::ifstream("data-for-union-find.txt")),std::istream_iterator>(),std::back_insert_iterator(myvector));` – Mooing Duck Oct 28 '14 at 18:11
  • 1
    @MooingDuck There's no extractor defined for `std::pair` and `std::istream_iterator` takes a non-const lvalue reference. – David G Oct 28 '14 at 18:14
  • @0x499602D2: And I used the wrong name for the back_inserter function. Turns out that extractor bit is harder to workaround than I'd expected. http://coliru.stacked-crooked.com/a/d16b8bd180180e61 – Mooing Duck Oct 28 '14 at 18:31
  • @MooingDuck I found a related post on that subject. -- http://stackoverflow.com/questions/16548379/dependent-name-resolution-namespace-std-standard-library – David G Oct 28 '14 at 20:44

2 Answers2

2

To add more elements to an array, beyond its capacity, you have to:

  1. Allocate a new, larger array.
  2. Copy all elements from old array to new array.
  3. Delete old array.
  4. Append new element(s).

A safer solution is to use std::vector and the push_back method.

If you have a large amount of data, you may want to declare the std::vector with a large size to reduce the number of reallocations.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

I would write directly into a single container which avoids allocations:

#include <deque>
#include <iostream>
#include <sstream>

template <typename Sequence>
inline int xvalue(const Sequence& data, std::size_t index) {
    return data[2*index];
}

template <typename Sequence>
inline int yvalue(const Sequence& data, std::size_t index) {
    return data[2*index + 1];
}

int main() {
    std::istringstream stream(""
        "600000\n"
        "523887 283708\n"
        "231749 419866\n"
        "293707 273512\n"
        "296065 215334\n"
        "233447 207124\n"
        "264381 460210\n"
        "374915 262848\n"
        "449017 329022\n"
        "374111 151212\n"
        "2933 496970\n");
    // Get rid of the suspicious first value:
    int suspicious;
    stream >> suspicious;
    // Use a sequence, which avoids allocations
    std::deque<int> data
    // Read x,y:
    int x;
    int y;
    while(stream >> x >> y) {
        data.push_back(x);
        data.push_back(y);
    }
    // Display:
    for(std::size_t i = 0; i < data.size() / 2; ++i)
        std::cout << "x = " << xvalue(data, i) << ", y = " << yvalue(data, i) << '\n';
    // If you need contiguous memory
    std::vector<int> contiguous(data.begin(), data.end());
}