What you have here is a monolithic program - there is one function. That is only reasonable for the most trivial of programs and, in my opinion, your program is not quite trivial enough for that to be acceptable. For this reason, I think you need to break this into functions. This will also help you sort things out because you can focus on and debug one thing at a time. This needs to be broken into a series of functions. I would make one function to read the file and create the matrix. The creation of the matrix should also be its own function and there needs to be a corresponding matrix free function the releases all the memory it allocated. Then you should make a function to sort the matrix and one to write the matrix. The matrix writer should take a file object pointer as an argument so you can pass it a handle to an open file to write it or pass it stdout to display it in your console. BTW - you know that "printf" and "fprintf to stdout" are essentially the same thing, right?
You have all the code for each of these functions so just need to call them appropriately. The hardest thing will probably be to sort out how to mass your matrix around. The answer is simple - you pass an argument of the type "int**" since that is how you declared m. Once you get these functions and their prototypes sorted out your main function should look something like this :
int main(void)
{
const char * inputFile = "input.dat";
const char * outputFile = "output.dat";
FILE *pfile = nullptr;
int **m = nullptr;
m = ReadMatrix( inputFile ); if( ! m )
return -1;
printf( "file %s was read - matrix is :\n", inputFile );
WriteMatrix( m, stdout );
SortMatrix( m );
printf( "sorted matrix is :\n" );
WriteMatrix( m, stdout );
pfile = fopen( outputFile, "w");
if( ! pfile )
{
fprintf( stderr, "Error opening file '%s'!\n", outputFile );
return -1;
}
WriteMatrix( m, pfile );
fclose( pfile );
printf( "file %s was written\n", outputFile );
ReleaseMatrix( m );
printf( "matrix was released - sayonara\n" );
return 0;
}
That makes four functions you need to write and you have the code for all of them already. Now you can focus on debugging each of them as they are called in your program. If you separate creating the matrix and reading file into two functions then you will have five functions.
This is the larger programs and libraries are written - you break the code into components that can potentially be used many times in various places.
-edit-
I see noOfRows comes from somewhere else. This means you can separate reading and allocating the matrix easily.