A How to Create a Matrix in C++

Create a basic matrix in C (input by user !)

How about the following?

First ask the user for the number of rows and columns, store that in say, nrows and ncols (i.e. scanf("%d", &nrows);) and then allocate memory for a 2D array of size nrows x ncols. Thus you can have a matrix of a size specified by the user, and not fixed at some dimension you've hardcoded!

Then store the elements with for(i = 0;i < nrows; ++i) ... and display the elements in the same way except you throw in newlines after every row, i.e.

for(i = 0; i < nrows; ++i)
{
for(j = 0; j < ncols ; ++j)
{
printf("%d\t",mat[i][j]);
}
printf("\n");
}

How to create a matrix structure in C?

As a beginner C programmer you should get to know and at least initially avoid complex cases of pointer arithmetic. For the matrix case you can actually do things simple. I took the liberty of adding very basic error detection using assert.

To begin with, use single pointer when possible:

typedef struct matrix{
int rows;
int columns;
int *data;
}matrix;

Adapt your allocation procedure:

matrix startmatrix(int n_row, int n_col){
assert(n_row>0 && n_col>0);
matrix mat;
mat.rows=n_row;
mat.columns=n_col;
mat.data=calloc(n_row*n_col,sizeof(int)); /* allocate memory and clear to zero */
return mat; /* return copy of mat */
}

The prototype of this functions looked a little funny to me so I changed it a bit. It should have the same effect as the old one.

If you want to make the most of the structure, make accessor functions instead of working with the raw array index:

int* matrixcell(matrix mat, int column, int row){
assert(column < mat.columns && row < mat.rows);
return &mat.data[row*mat.columns + column]; /* pointer arithmetic */
}
/* example of using it */
*matrixcell(mat, 1, 1) = new_value;

The arithmetic is a very basic way of navigating through 2D data in a 1D array. Try it out on pen and paper, writing does the addresses of each cell. You'll see it makes sense.

How do I create a square matrix in the C programming language?

The elements of the first matrix can be set with:

a[i][j] = i + j;

There's no need for an if statement inside the loop. The whole thing looks like:

void computeMatrix(int rows, int cols, int sqMatrix[][cols])
{
int i,j;

for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
arr[i][j] = i + j;
}
}
}

How do i create a matrix with words in C

Try this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_ROWS 8 // to limit the usecase
#define MAX_COLS 8
#define MAX_MAT_STR_LEN 15 //

char* str_dupe (const char* str, const int max_slen)
{
if (!str || max_slen < 1) return NULL;
char* dupe = malloc (max_slen + 1);
if (!dupe) {
perror("\nERROR: str_dupe-malloc");
return NULL;
}
dupe[max_slen] = '\0'; // guard
for (int ci =0; ci < max_slen; ++ci) {
dupe[ci] = str[ci];
if ('\0' == dupe[ci])
break; // stop copying
}
return dupe;
}

void free_strMatrix (char ***sm, const int rows, const int cols)
{
if (!sm || rows < 1 || cols < 1) return;

for (int ri = 0; ri < rows; ++ri) {
if (sm[ri]) {
for (int ci = 0; ci < cols; ++ci) {
if (sm[ri][ci]) { // check if it's NULL
free (sm[ri][ci]);
sm[ri][ci] = NULL; //prevent dangling pointers
}
}
free (sm[ri]); // row of string pointers
sm[ri] = NULL; // good practice
}
}
free (sm);
}

char*** read_strMatrix (int *rows, int *cols)
{
while (1) {
printf ("\nChoose Rows [1..%d]: ", MAX_ROWS);
if (1 == scanf("%d", rows) && *rows > 0 && *rows <= MAX_ROWS)
break;
else
printf ("\nERROR: Invalid Row-Count. Try Again!");
}
while (1) {
printf ("\nChoose Columns [1..%d]: ", MAX_COLS);
if (1 == scanf("%d", cols) && *cols > 0 && *cols <= MAX_COLS)
break;
else
printf ("\nERROR: Invalid Column-Count. Try Again!");
}

char*** sm = (char***) calloc ((*rows), sizeof (char**));
if (NULL == sm) {
perror("read_strMatrix-malloc-1");
return NULL;
}
for (int ri = 0; ri < *rows; ++ri) {
sm[ri] = (char**) calloc ((*cols), sizeof (char*));
if (NULL == sm[ri]) {
perror ("read_strMatrix-malloc-2");
//ideally you should free allocated memory before return
free_strMatrix(sm, *rows, *cols);
return NULL;
}
}
char str[256]; //interim string buffer;
for (int ri = 0; ri < *rows; ++ri) {
for (int ci=0; ci < *cols; ++ci ) {
printf ("String for strMatrix[%d][%d] : ", ri, ci);
// strings more than 255 chars will be split ; so be within limit duing input
while (1 != scanf ("%255s", str));
// only copying MAX_MAT_STR_LEN chars
sm[ri][ci] = str_dupe (str, MAX_MAT_STR_LEN);
if (NULL == sm[ri][ci]) {
perror("read_strMatrix-strndup");
//ideally you should free allocated memory before return
free_strMatrix (sm, *rows, *cols);
return NULL;
}
}
printf ("\n");
}
return sm;
}

void disp_strMatrix (char ***sm, const int rows, const int cols)
{
if (!sm || rows < 1 || cols < 1) return;
printf ("\nStringMatrix [%d][%d]:\n", rows, cols);

for (int ri = 0; ri < rows; ++ri) {
if (sm[ri]) {
for (int ci = 0; ci < cols; ++ci)
printf ("%s\t", sm[ri][ci]);
}
printf ("\n");
}
printf ("\n");
}

int main()
{
int rows, cols;
char ***strMatrix;
strMatrix = read_strMatrix (&rows, &cols);
if (!strMatrix) {
printf ("\nERROR: reading strMatrix\n");
return 1;
}
disp_strMatrix (strMatrix, rows, cols);
free_strMatrix (strMatrix, rows, cols);
strMatrix = NULL; // good practice

return 0;
}

You can also prepare an input.txt file like:

3 4
aaaaa sssss ffg gggg
hhhh jj kkkkkk lllll
qqq wwwww eeeee rrrrr

On Linux you can run the program like:

./a.out < input.txt 

How to make simmetric matrix in C language

You are not getting symmetric matrix because you are accessing the index of matrix not properly. Let me explain in a bit detail.

The matrix that you are using is of size size-1 x size-1, so if size=5 then the matrix that you are allocating is of size 4x4, so you effectively have only 16 elements in your matrix. (And you actually want 25 elements).

But when traversing the matrix to populate it, you are accessing index like[4,4] which means your matrix should (logically) have 25 elements. (But it is not having).

So there are two ways to get rid of this mistake:

  • You can change your for loop to for(int i=0;i<size-1;i++) so you don't access elements in an unexpected way.
  • You can increase the size of your array to size x size instead of size-1 x size-1.

The final code will look something like this (I'm posting only the core part):

int matrix[size][size];
for(int i=0;i<size;i++){
for(int j=i;j<size;j++){
num = rand()%100+1;
matrix[i][j]=num;
matrix[j][i]=num;
}
}

As an optimization you can avoid re-writing the values by putting starting the inner-loop for j from i itself, so that the values in the upper triangle of matrix are generated by random number and the lower triangle values are filled by the value in the corresponding symmetric cell in the upper triangle.

I think your intention for asking the question is to learn and get better, so I answered in detail with some extra comments. I hope this was helpful. :)

Reading through a file to create a matrix in c

Sorry I haven't been able to post the answer sooner.

Here is the end result:

/Matrix reading/

matrix_t mat_frd(char* fname){

int r, c;
int i, j;
FILE * matrix_file;

matrix_file = fopen(fname, "r");

fscanf(matrix_file, "%d", &r);
fscanf(matrix_file, "%d", &c);

//create new matrix
matrix_t mfile = mat_new(r,c);

for(i = 0; i < r; i++){
for (j = 0; j < c; j++){
fscanf(matrix_file,"%lf", &mfile->mat[i][j]);
}
}
fclose(matrix_file);
return mfile;
}

I was able to get this to work by calling the file name in the main method like so:

char* fname = "sample_matrix.txt";
matrix9 = mat_frd(fname);

sample_matrix.txt - being the txt file in my program
matrix9 - random matrix I created to test it

I essentially first achieved the two numbers in the first two lines of the text file, which gave me the dimensions of the matrix (first number - rows, second number - columns). I then created the matrix with those parameters, and created the for loops that would call fscanf for every space in the matrix (able to do this bc everything else in the file was a double). My output after using this code is as follows (you would have to create a print statement for this, but with mine:

MATRIX: after file-read Type: 13 , Dims 3, 4

0.000 1.000 2.000 3.000

10.100 11.100 12.100 13.100

200.200 210.200 220.200 230.200

Hope this helps everyone and thanks for all the advice!



Related Topics



Leave a reply



Submit