1

I have a text file with 2 columns and many rows. each column is separated by spaces. i need to read them to a 2D array for further calculations. my data file looks like

0.5 0.479425539
1   0.841470985
1.5 0.997494987
2   0.909297427
2.5 0.598472144
3   0.141120008
3.5 -0.350783228
4   -0.756802495
4.5 -0.977530118
5   -0.958924275  

And my feeble attempt is

#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include <ctype.h>
using namespace std;

int main () {
  char line,element;
  std::ifstream myfile ("C:\\Users\\g\\Desktop\\test.txt");
  if (myfile.is_open())
  {
    while ( myfile.good() )
    {
      getline(myfile,line);
       cout << line<<endl;               
      _getch();
    }
    myfile.close();

  }

  else cout << "Unable to open file"; 

  return 0;

}

The problem is I'm not able to read them correctly.... its either reading the whole line... if I specify the delimiter as 'space' then, its not reading the next row.

Pls point out whats wrong. and what should i do to store the data into 2d array for further calculations. Thank you

2
  • Does your program even compile? There is no overload of std::getline that takes a single character as second argument. There are also lot of other weird things in your code, like the use of bitwise or (the | operator), and the input operator from a char variable. Commented Jan 30, 2013 at 9:32
  • I Have edited the code now ... It does compile... Commented Jan 30, 2013 at 9:37

3 Answers 3

1
#include <fstream>
#include <string>
#include <sstream>
#include <iostream>
#include <vector>

int main(int argc, char** argv) {
   std::ifstream f(argv[1]);
   std::string l;
   std::vector<std::vector<double> > rows;
   while(std::getline(f, l)) {
       std::stringstream s(l);
       double d1;
       double d2;
       if(s >> d1 >> d2) {
           std::vector<double> row;
            row.push_back(d1);
            row.push_back(d2);
            rows.push_back(row);
        }
    }

    for(int i = 0; i < rows.size(); ++i)
        std::cout << rows[i][0] << " " << rows[i][1] << '\n';
}

The last for loop shows how to use the values in the "array". The variable rows is strictly speaking not an array, but a vector of vectors. However, a vector is much safer than c-style arrays, and allows access to its elements using [].

[As I posted this I saw a very similar program posted as a response. I wrote mine independently.]

Sign up to request clarification or add additional context in comments.

5 Comments

std::ifstream f(argv[1]); std::string l; std::vector<std::vector<double> > rows; can u pls expalin me this part.
When you run the program, give the name of the file to be read as the first argument.
Alternatively replace std::ifstream f(argv[1]); with std::ifstream f("C:\\Users\\g\\Desktop\\test.txt");
std::ifstream f(argv[1]); creates and opens an input file stream for the file given as the first command line argument. If you are launching your program in visual studio, right click the project in the solution explorer, select Properties->Configuration Properties->Debugging and type the name of the file you want to read in the field "Command Arguments"
std::vector<double> rows; creates a vector (think of it as an array, but but nicer). The vector stores doubles. Look here: cplusplus.com/reference/vector/vector
1

You can read the whole line into a std::string, then use std::istringstream to extract the values from the line.


A complete working program:

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>

int main()
{
    std::ifstream file("C:\\Users\\g\\Desktop\\test.txt");

    std::string line;

    // Read a line of input from the file
    while (std::getline(file, line))
    {
        // `istringstream` behaves like a normal input stream
        // but can be initialized from a string
        std::istringstream iss(line);

        float value;

        // The input operator `>>` returns the stream
        // And streams can be used as a boolean value
        // A stream is "true" as long as everything is okay
        while (iss >> value)
        {
            std::cout << "Value = " << value << '\t';
        }

        // Flush the standard output stream and print a newline
        std::cout << std::endl;
    }
}

Given the contents in the file being as in the question, the first three lines of output should be:

Value = 0.5 Value = 0.479425539
Value = 1   Value = 0.841470985
Value = 1.5 Value = 0.997494987

For a 2d-array, I would use a std::vector of std::array:

#include <vector>
#include <array>

...

std::vector<std::array<float, 2>> array;

...

float value1, value2;
if (iss >> value1 >> value2)
{
    std::cout << "Values = " << value1 << ", " << value2;

    array.emplace_back(std::array<int, 2>{{value1, value2}});
}

Now the first line values are array[0][0] and array[0][1], and the last lines values are array[array.size() - 1][0] and array[array.size() - 1][1].

3 Comments

I am very New to c++... can u be a little more specific pls
@user2024645 It's kind of obvious that you are new, I suggest you try more basic stuff first. Meanwhile, I felt kind enough to write a working (I hope) example program.
Thank you so much Pileborg... its working fine... Now i need to pass them to a 2d array...pls give me a hint...i'll do the rest...
0

As C++ has evolved over the years, below is a Modern C++ version.

  • It uses auto where possible
  • Uses std::pair to hold 2 values (A std::pair is a specific case of a std::tuple with two elements)
  • Does not close file (destructor does that at end of block)
  • Does not read line by line, as the stream uses <space> and <enter> as delimiters
  • The variables have meaningful names, so the program "reads" easily,
  • Uses a range for loop to output the data.
  • Doesn't bring the whole std namespace into the code - Why is “using namespace std” considered bad practice?

.

#include <fstream>
#include <iostream>
#include <vector>
#include <utility>

int main( int argc, char** argv )
{
    if ( argc < 1 )
        return -1;

    const auto    fileName = argv[ 1 ];
    std::ifstream fileToRead( fileName );

    typedef std::pair< double, double > DoublesPair;
    std::vector< DoublesPair > rowsOfDoublesPair;
    DoublesPair                doublePairFromFile;

    while ( fileToRead >> doublePairFromFile.first >> doublePairFromFile.second )
    {
        rowsOfDoublesPair.push_back( doublePairFromFile );
    }

    for ( const auto row : rowsOfDoublesPair )
        std::cout << row.first << " " << row.second << '\n';
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.