Beto36
Beto36

Reputation: 3

Reading values from a file with a different amount of values per column, C++

I try to read values from a data file. However, it has a different amount of values per column which I need to extract.

The list of values looks like this:

8
11
0        0   -50
1000     0   -50
2000     0     0
0      500     0
500    500     0
0     1000   -50
1000  1000     0
2000  1000   150

With the code below I can store all values in the array but I want to store the 8 and the 11 seperatly. Furthermore should the first column (0 to 2000) be stored in one array, the second one (0 to 1000) in a second array and the third one (-50 to 150) in a third array.

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    cout << "PROGRAM PIPE NETWORK" << endl;

    //Read input data file
    int n;
    double *array;

    cout << "How many data sets do you have?\nDatasets: ";
    cin >> n;

    ifstream infile("pipedata.dat");
    array = new double[n];

    for (int i = 1; i < n; ++i)
        infile >> array[i];

    return 0;
}

I hope some of you can help me and please try to not write a general answer. I am quiet new in this topic. Greetings.

EDIT 1:

An other attempt is the following, however it works sometimes but I also get erros with data adresses or heap difficulties. Sometimes it works but most of the time my program just stops working.

int main()
{
cout << "PROGRAM PIPE NETWORK" << endl;

// Read input all data files
int n; double *input;
int limit_x, x; double *array_x;
int limit_y, y; double *array_y;
int limit_q, q; double *array_q;
int n_nodes, n_tubes;

cout << "How many data sets do you have?\nDatasets: ";
cin >> n;

ifstream infile("pipedata.dat");
input = new double[n];
for (int i = 0; i<n; ++i) infile >> input[i];

// Assign input values to their variables
// Number of nodes and number of tubes
n_nodes = input[0];
n_tubes = input[1];

cout << "Input values" << endl;
for (int i = 0; i < n; ++i)
{
    cout << input[i] << endl;
}
cout << "---------------------------------------" << endl;
cout << "X-Values" << endl;
// Node data x-values
x = n_nodes;
limit_x = n_nodes * 3;
array_x = new double[x];
for (int i = 0; i < limit_x; i += 3)    array_x[i] = 0;
for (int i = 0; i < limit_x; i+=3)      array_x[i] = input[i+2];

for (int i = 0; i < limit_x; i+=3)      cout << array_x[i] << endl;
return 0;
}

Everything works fine with "input" but not with array_x. Also I want to do the exact same thing with 5 other variables. I know it isnt the best solution but I realy dont understand why it does not work.

Upvotes: 0

Views: 109

Answers (1)

Thomas Matthews
Thomas Matthews

Reputation: 57698

I don't know what the complications are, but here is an example:

std::vector<int> array_1;
std::vector<int> left;
std::vector<int> middle;
std::vector<int> right;
int temp;

// Read two numbers into an array
data_file >> temp;
array_1.push_back(temp);
data_file >> temp;
array_1.push_back(temp);

// Read columns of data into separate arrays
int left_value, middle_value, right_value;
while (data_file >> left >> middle >> right)
{
  left.push_back(left_value);
  middle.push_back(middle_value);
  right.push_back(right_value);
}

The above is one example of many. It is not optimized.

Another example uses std::getline and std::istringstream, which would comply better with the alignment of the rows.

Edit1: Line by line processing

std::string text_line;
std::istringstream parser;

// Read a line from the file
std::getline(data_file, text_line);

// Extract the numbers from the line:
parser.str(text_line); // Initialize the std::istringstream with the text line.
int value_1 = 0;
parser >> value_1; // Extract the first number of the first line.

// Read the second line from the file
std::getline(data_file, text_line);

// Extract the numbers from the line:
parser.str(text_line); // Initialize the std::istringstream with the text line.
int value_2 = 0;
parser >> value_2; // Extract the first number of the second line.

// After reading 2 lines, the file pointer should be pointing
//   at the 3rd line.
// The data format changes at the 3rd line with 3 numbers per line.
// Let's use an array this time, one per column.
const unsigned int  ARRAY_CAPACITY = 256;
int column_1[ARRAY_CAPACITY];
int column_2[ARRAY_CAPACITY];
int column_3[ARRAY_CAPACITY];
unsigned int row = 0;

// Read until the data stream fails, usually at EOF.
while (std::getline(data_file, text_line))
{

  // ** Very important, check for overflow before using array**
  if (row >= ARRAY_CAPACITY)
  {
     // Either reallocate and copy old array or ...
     // Crash the program.
     std::cerr << "Array capacity is too small.\n";
     exit(1);
  }

  // Initialize the parser
  parser.str(text_line);

  // Extract the first value and place into array, directly.
  parser >> column_1[row];  

  // Likewise, the next columns.
  parser >> column_2[row];
  parser >> column_3[row];

  // Advance the column index to the next row (line)
  ++row;
}

Upvotes: 1

Related Questions