I am working on a programing that needs to accept a text file as input and read that data into an NxM matrix. The only given size limitation is that the max row length is 1024. Additionally, the program needs to produce an error if all rows do not contain the same number of columns.
I figure that I need a 2D array to store the values, but I can't figure out how to do it, since I don't know the size to begin with.

int MAX_COLS=1024;
void readInput(ifstream & in)
{
	int rows=1, cols=0;
	float temp=0;
	while (in.peek()!='\n') 
       //counts columns in first row
	{
		in>>temp;
		cols++;
	}
	while (!in.eof()) 
	{
		int col_count=0;
		if (in.peek()=='\n') //at the end of a line
		{
			in.ignore(3,'\n'); //ignore newline character
			rows++;//increment rows
		}
		else
		{
			while (in.peek()!='\n')
                  //while not at end of line, count columns in current row
			{
				in>>temp;
				col_count++;
				if (in.eof()) 
					break;
			}
			if (col_count!=cols) //if the columns in current row aren't equal to columns in first row, output Error and exit
			{
				cout<<"Error invalid data"<<endl;
				exit(1);
			}
		}
	}
	
	cout<<"Rows "<<rows<<" Cols "<<cols<<endl;
	in.close();
		
}

My code shows my function that computes rows and columns, and checks that each row has the same number of columns. In the code, I'm storing values in temp, but I need to change that to store them in a way that I can access them outside the loops.

Could someone please help me figure out a way to store these values?

If you do not know the size ahead of time, you can use the MAXIMUM size to make sure you have now overflow. There is no maximum size for this. There's a maximum number of columns, but not a maximum number of rows. So you are left with a few options:

  1. Go through the file, count the number of rows and columns, but don't store the matrix values. Declare the 2-D array to be the (now known) number or rows and columns, then go through the file again and read in the values.
  2. Dynamically resize your array as needed as you read through the file (i.e. have enough storage to handle ten rows, then when you hit row 11, resize the array to something larger, and keep going (will potentially involve a deep copy of the array to another location).
  3. Use vector(s), which also resize, but they do all the resizing and deep copying work for you.

Use std::list to read data from file, than copy all data to std::vector.

Hi, have you tried this?

ifstream mat2(matrix2); 
int      nrows2=0, ncols2=0,col_count=0;
const    char EOL = '\n'; float    temp;
while   ( mat2.peek()!=EOL){mat2>>temp;  ncols2++; }
while   (!mat2.eof())      { if (mat2.peek()==EOL){ mat2.ignore(3,EOL); nrows2++; }
			  else{ while (mat2.peek()!=EOL){ mat2 >>temp;col_count++; if (mat2.eof()) break;}}}
	mat2.close();

ifstream mat4(matrix2); 
for (row=0; row<nrows2; row++){for (col=0; col<ncols2; col++){mat4 >> parameters[row][col];}}

It seems like a risky set up for a problem. You are really counting on no hiccups within the system. I read matrices from text files quite often, and I like to have the matrix dimension entered in the file as the very first entry. It might not create the perfect set up, but it provides one more level of redundancy for checking the system. I mean, if the user enters a 2 for the matrix dimension, but the file has 23 entries, that indicates that perhaps a typo has been made, or the file is wrong, or something, so I output an error message and prompt the user to re-check the data. If the user is up at 3 am and they are getting absent-minded, forcing them to give the data file a second look can't hurt.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.