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:
#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#autoconstauto 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#forfor( constauto& 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" ;
}
}
}
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.