Ragged Arrays! (Need Help)

Hi guys, for this program I have been struggling with it for couple of days trying to read it from file by using pointers. Can you guys help me out on how I should start it?

The program starts by reading data from a file into a dynamically allocated ragged array. The data file, ragged.txt, begins with n, the number of rows. On
the next n lines, for each row in the ragged array, there is an integer representing the size of that row, followed by the numbers (type double) on that row. Here is an example:

4
3 23.9 51.2 35.6
5 12.2 23.5 54.6 5.8 56.8
1 88.8
2 12.1 34.9
closed account (48T7M4Gy)
http://stackoverflow.com/questions/7542522/read-irregular-file-into-a-2-dimension-array-using-c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>

// Use std::vector where you have a choice - and you have a choice in most contexts -  Stroustrup
// http://www.cplusplus.com/forum/beginner/176462/2/#msg871761
// https://cal-linux.com/tutorials/vectors.html

std::vector<double> make_array_from_line( std::string line )
{
    // http://www.artima.com/cppsource/streamstrings3.html
    std::istringstream stm(line) ; // create a stringstream to parse the line
    std::size_t num_values ;
    stm >> num_values ; // number of values in this line

    std::vector<double> array ;
    array.reserve(num_values) ; // may be safely omitted; a vector automagically resizes itself as required

    double value ;
    while( num_values-- && stm >> value ) // for each value in the line, up to a maximum of num_values
    array.push_back(value) ; // append this value to the end of the array

    return array ;
}

std::vector< std::vector<double> > get_ragged_array( std::istream& stm )
{
    std::vector< std::vector<double> > ragged_array ;

    std::size_t num_lines ;
    stm >> num_lines ;
    ragged_array.reserve(num_lines) ; // can be omitted; a vector automagically resizes itself as required

    // http://www.cplusplus.com/forum/general/69685/#msg372532
    stm.ignore( 1000000, '\n' ) ; // throw away the new line after the first line

    std::string line ;
    // http://www.cplusplus.com/reference/string/string/getline/
    while( num_lines-- && std::getline( stm, line ) ) // for each line in the file, up to a maximum of nlines
        ragged_array.push_back( make_array_from_line(line) ) ; // add the array from this line to the ragged array

    return ragged_array ;
}

void create_a_test_file( std::string file_name ) // file used for for testing our code
{
    std::ofstream(file_name) << "4\n"
                                "3 23.9 51.2 35.6\n"
                                "5 12.2 23.5 54.6 5.8 56.8\n"
                                "1 88.8\n"
                                "2 12.1 34.9\n" ;
}

int main()
{
    const std::string file_name = "ragged.txt" ;

    create_a_test_file(file_name) ;

    if( std::ifstream file{ file_name } ) // if the file was opened successfully
    {
        // http://www.stroustrup.com/C++11FAQ.html#auto
        const auto ragged_array = get_ragged_array(file) ;

        // to verify that we have read things correctly, print out the array
        std::cout << "successfully read " << ragged_array.size() << " rows\n\n" ;
        
        // http://www.stroustrup.com/C++11FAQ.html#for
        for( const auto& row : ragged_array ) // for each row in the jagged array
        {
            for( double value : row ) // for each value in the row
                std::cout << std::fixed << std::setprecision(2) << std::setw(7) << value ;

            std::cout << "   (#values in this row: " << row.size() << ")\n" ;
        }
    }
}

http://coliru.stacked-crooked.com/a/c88b7f8b267fa8f8
closed account (48T7M4Gy)
LOL
¿what's so funny?

By the way, ¿why the unnecessary conversion?
1
2
3
4
5
6
7
8
std::cin>>rows;
ragged_matrix.resize( rows );
for(int K=0; K<rows; ++K){
   std::cin>>columns;
   ragged_matrix[K].resize(columns);
   for(int L=0; L<columns; ++L)
      std::cin>>ragged_matrix[K][L];
}
Last edited on
> ¿what's so funny?

std::vector<>, that too in a C++ program! Now, what could be more ludicrous than that?


> By the way, ¿why the unnecessary conversion?

It is unnecessary if we do not intend to correctly handle lines which may contain fewer or more values than num_values numbers. ie, cause garbage left unread in one line to be read as data for the next row (more values) or trash the next line by extracting data belonging to it (less values)

line 23:
while( num_values-- && stm >> value ) // for each value in the line, up to a maximum of num_values

line 42:
while( num_lines-- && std::getline( stm, line ) ) // for each line in the file, up to a maximum of nlines

Note that vector<>::reserve() (not vector<>::resize()) was used in both cases.
Thank you JLBorges! This helped a lot
Topic archived. No new replies allowed.