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 tofor(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 ofsize-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
"String Could Not Resolved" Error in Eclipse for C++ (Eclipse Can't Resolve Standard Library)
Passing a Variable as a Template Argument
Order of Evaluation of Elements in List-Initialization
How to Find the Actual Path Found by Bfs
Random Array Generation with No Duplicates
"The System Cannot Find the File Specified" When Running C++ Program
How to Use Polymorphic Attributes with Boost::Spirit::Qi Parsers
C++17 Class Template Partial Deduction
Create a Function to Check for Key Press in Unix Using Ncurses
How to Declare a Member Vector of the Same Class
No Match for 'Operator<<' in 'Std::Operator
Matching Alias Template as Template Argument
What's the Behavior of an Uninitialized Variable Used as Its Own Initializer