Copying matrix from .txt into array - c

I have a task to read matrix from .txt file and then make an 2D array in C. I read numbers well but I have a problem with writing these numbers into array because I need to allocate memory because im not sure how big the matrix will be.
int read()
{
FILE *f;
int number, i, j, size;
f = fopen("matrix.txt","r");
if (f == NULL)
{
printf("Error reading matrix.txt\n");
return 1;
}
printf("Sucess! \n");
fscanf(f, "%d",&size);
printf("Size of matrix: %d\n", size,size);
int* matrix;
matrix = malloc(size * sizeof(int));
for(; feof(f) == 0;)
{
for(i = 0; i < size; i++)
{
for(j = 0; j < size; j++)
{
fscanf(f,"%i",&number);
// *(*(matrix+j)+i) = number;
printf("%i\t",number);
}
printf("\n");
}
}
fclose(f);

To my understanding, matrix is of type int* and you intend to store size*size elements read from the file into it. First of all, you should allocate memory for size*size times the size of int, which can be done as follows.
matrix = malloc(size * size * sizeof(int));
Next, as you iterate via i and j over the matrix entries which are read from the file, you need to do a proper address calculation. As matrix is of type int*, this can be done as follows.
matrix[ i * ( size - 1 ) + j ] = number;
That being said, perhaps it would be better to have matrix of type int** and allocate space for the rows manually. By doing so, you could do the access to the elements by
matrix[ i ][ j ] = number;
which is perhaps more intuitive.

You can do :
matrix[(size-1)*i+j]=number
To fill the array, that is the usual way to simulate 2D arrays in C, to understand from where did (size-1)*i+j come from notice this example :
1 2 3
4 5 6
7 8 9
the result array is : 1 2 3 4 5 6 7 8 9.
So when we begin in the first row and first column, in the result array 1 is the first element so its index is zero.
When we advance one row(from 1 to 4) we advance three positions in the result array so the index is 3.
Now if we begin with column 1(second column) and the first row we have 2 which has index 1 in the result array, if we advance one row(from 2 to 5) we also advance 3 positions and the index is 4.
Notice that 3 is actually the size of matrix and I think you can verify that i*(size-1)+j is working, the size-1 is like this because C arrays are zero-based.
Note
If your file only has one matrix, I recommend you to get rid of the outermost loop , a simple mistake(like a new line after the matrix or space) will cause a call to fscanf(f,"%i",&number) without finding a number(I'm not sure what will happen then).
Also you should allocate size*size of ints.

Related

how to find the number of elements present in an array in C

suppose I have an array a[10] and it is filled up to 6 places example a[]={10,20,30,40,50,60} now rest 4 places are empty, now how do I print the number of places that are filled in an array-like in the above case it should print 6, given the scenario that I do not know the array beforehand like I do not have any clue what size it is or the elements that are there inside.
int a[]={10,20,30,40,50,60} initilizes all 6 elements.
int b[10]={10,20,30,40,50,60} initilizes all 10 elements, the last ones to 0.
There is no partial initialization in C.
There is no specified "empty".
to find the number of elements present in an array in C
size_t elemnt_count_a = sizeof a / sizeof a[0]; // 6
size_t elemnt_count_b = sizeof b / sizeof b[0]; // 10
I do not know the array beforehand
In C, when an array is defined, its size is known.
if the array is a[]={10,20,30,40,50,60}
here is my psedocode -
int size = 0;
if(i = 0; i < a.length(); i++) {
if(a[i] != null)
size++
}
the value of size should print 6

Store rows of numbers from a list into arrays without leaving empty cells

I want to read rows of numbers from a file and store each of the rows into separate array to then sort and find the median of each array. The problem I'm having is that each row can have a different amount of numbers in it. I though about using a 2D array that would have enough space to fit the largest row in my file. The problem I see with this is that shorter rows in my file would have empty cells in the array and that could cause errors in the sorting and median.
Is there anyway to store each row of the list without having empty cells in the 2D array?
Here's an example of the number list
1 2 3 4 5
5 2 8 5 7 4 3
3 2 5 4 6 5
2 3 1 6 5
9 6 4 6 5 0
Yes you certainly can.
Use dynamic memory allocation for that. This is where it can be useful.
int *p[5];
p[0]= malloc( sizeof(int)*10);
if( p[0]== NULL)
{
fprintf(stderr,"Error in malloc");
exit(1);
}
p[1]= malloc( sizeof(int)*5);
if( p[1]== NULL)
{
fprintf(stderr,"Error in malloc");
exit(1);
}
..
free(p[0]);
free(p[1]);
This way now you have created an array of different sizes. Now to remmeber the sizes you can mention another array sizeArr which will hold the sizes of different arrays.
What I mean is sizeArr[0]=10 and sizeArr[1]=5 denoting the number of elements in p[0] and p[1].
Inputting and outputting the elements of p[0] and p[1] will be similar to that of an array.
if (scanf("%d", &p[0][0]) == 1)
// work with p[0][0];
else
...EOF or conversion failure...
Looping and printing would be similar to
for(size_t arrIndex = 0; arrIndex < 5; arrIndex++)
for(size_t i = 0; i< sizeArr[arrIndex]; i++ )
printf("%d", p[arrIndex][i]);
Here the benefit will be you will not have to worry about unused memory locations. You will allocate whatever memory you need. Also you can change then as you need using realloc() etc.
Note: In this case don't forget to free the memory dynamically allocated after you are done working with it.

2-D matrices using malloc failing to assign correct values

sorry, I'm relatively new to c and am trying to create two 2-D arrays using malloc. I was told that this method is computationally more efficient than creating a pointer array of arrays through a for loop (for large arrays).
int i, j;
double **PNow, **PNext, *Array2D1, *Array2D2;
//Allocate memory
PNow = (double**)malloc(3 * sizeof(double*));
PNext = (double**)malloc(3 * sizeof(double*));
Array2D1 = (double*)malloc(5 * sizeof(double));
Array2D2 = (double*)malloc(5 * sizeof(double));
//Create 2-Dimensionality
for(i = 0; i < 3; i++)
{
PNow[i] = Array2D1 + i * 5;
PNext[i] = Array2D2 + i * 5;
};
//Define Element Values
for(i = 0; i < 3; i++)
{
for(j = 0; j < 5; j++)
{
PNow[i][j] = 10.*(i + j);
PNext[i][j] = 1000.*(i + j);
};
};
//Output two matrices side-by-side.
for(i = 0; i < 3; i++)
{
for(j = 0; j < 5; j++)
{
printf("%6lg", PNow[i][j]);
if(j == 4)
{
printf("|");
};
};
for(j = 0; j < 5; j++)
{
printf("%6lg", PNext[i][j]);
if(j == 4)
{
printf("\n");
};
};
};
My problem is that the first matrix (PNow) turns out as I would expect, but for some reason half of the values in PNext are those of PNow, and I can't for the life of me figure out why it is doing this? I'm obviously missing something.. Also I am not overly clear on what "Array2D1 + i*5" is doing and how this makes PNow a 2-D array?
Any help would be really appreciated.
Thank you.
P.S. This is the output that I am getting, so you can see what I mean:
0 10 20 30 40| 20 30 40 50 20
10 20 30 40 50| 30 40 50 60 5000
20 30 40 50 60| 2000 3000 4000 5000 6000
In C you don't cast the result of mallocs, so your malloc lines should read
PNow = malloc(3*sizeof(double*));
Your problem is you're not actually allocating enough memory in Array2D1 and Array2D2. When you move past the first "row" in your array you're getting beyond your allocated memory! So you're in undefined behavior territory. In your case, it looks like your two matrices step all over each other (though my test just throws an error). You can solve this in two ways:
Specify the full size of your matrix in the malloc and do as you did:
Array2D1 = malloc(15*sizeof(double));
Array2D2 = malloc(15*sizeof(double));
Or malloc each line in your for loop:
for(i=0; i<3; i++){
PNow[i] = malloc(5*sizeof(double));
PNext[i] = malloc(5*sizeof(double));
}
Edit: On the topic of freeing in each example
For the first example, the freeing is straight forward
free(PNow);
free(PNext);
free(Array2D1);
free(Array2D2);
For the second, you must iterate through each line and free individually
for (i = 0; i < 3; i++) {
free(PNow[i]);
free(PNext[i]);
}
Edit2: Realistically, if you're going to hardcode your rows and columns in with a pre-processor macro, there's no reason to malloc at all. You can simply do this:
#define ROW 3
#define COL 5
double PNow[ROW][COL], PNext[ROW][COL];
Edit3: As for what Array2D1 + i * 5 is doing, PNow is an array of pointers, and Array2D1 is a pointer. By adding i * 5 you're incrementing the pointer by i * 5 (i.e., saying "give me a pointer to the memory that is i * 5 doubles away from Array2D1). So, you're filling PNow with pointers to the starts of appropriately sized memory chunks for your rows.
You code does not have 2D arrays, aka matrices. And your pointers cannot point to such an object either.
A proper pointer which can point to a 2D array would be declared like:
#define ROWS 4
#define COLS 5
double (*arr)[COLS];
Allocation is straight-forward:
arr = malloc(sizeof(*arr) * ROWS);
And deleting similar:
free(arr);
Indexing is like:
arr[row][col]
Notice the identical syntax only. The semantics are different.
Nothing more necessary and no need for hand-crafted pointer arrays.
The code above shows another important rule: Don't use magic values. Use constant-like macros instead. These should be #defined at the beginning or in a configuration-section of the code (typically somewhere near the top of the file or a distinct header file). So if you lateron change e.g. the length of a dimension, you don't have to edit all places you explicitly wrote it, but only change the macro once.
While the code above uses constants, you can as well use variables for the dimensions. This is standard C and called variable length array (VLA). If you pass the arrays to other functions, you have to pass them as additional arguments:
void f(size_t rows, size_t cols, double a[rows][cols]);
Remember array-arguments decay to pointers to the first element, so a is actually the same as arr above. The outermost dimension can be omitted, but as you need it anyway it is good for documentation to specify it, too.

Pointer arithmetic with 2D arrays in C

I need help understanding how to use point arithmetic for 2D arrays in C. I'm using this website (http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/) as a reference (using example 1, a single pointer).
int numRows = 2;
int numColumns = 3;
double * arrayMatrix = malloc(numRows * numColumns * sizeof(double));
int row = 0;
int column = 0;
printf("\nPlease enter the elements of your augmented matrix:\n");
for(row = 0; row < numRows; row++)
{
for(column = 0; column < numColumns; column++)
{
printf("A[%d][%d]:", row + 1, column + 1);
scanf("%lf", &arrayElement);
printf("\n");
*(arrayMatrix + row * numColumns + column) = arrayElement;
//arrayMatrix[row + numColumns + column] = arrayElement;
}
}
// TEST PRINT
for(row = 0; row < numRows; row++)
{
for(column = 0; column < numColumns; column++)
{
printf("%5.2lf", *(arrayMatrix + row * numColumns + column));
//printf("%5.2lf", arrayMatrix[row + numColumns + column]);
}
printf("\n");
}
I need help understanding if this is a correct way to input data into a 2D array and if it is also a correct way to print data from a 2D array. I'm using the example data of for row 1 as {1, 2, 3} and row 2 as {1, 2, 3}; however when printing out the information all I get are 0 for all 6 elements.
I also used this answer as reference (How to use pointer expressions to access elements of a two-dimensional array in C?). Specifically following this line:
int x = *((int *)y + 2 * NUMBER_OF_COLUMNS + 2); // Right!
But I'm using a double pointer instead of an integer, but I don't know if that is causing my issues or if it is something else.
Edit - Updated the code a little but it is still not working at all.
Edit 2: This is the most recent update with the code that I've been trying to get to work. All 3 ways of inputting and printing data from the array result in the same result (0's for all values in the array).
int numRows = 2;
int numColumns = 3;
//double * arrayMatrix = malloc(numRows * numColumns * sizeof(double));
double (*arrayMatrix)[numColumns] = malloc(sizeof(double[numRows][numColumns]));
int row = 0;
int column = 0;
printf("\nPlease enter the elements of your augmented matrix:\n");
for(row = 0; row < numRows; row++)
{
for(column = 0; column < numColumns; column++)
{
printf("A[%d][%d]:", row + 1, column + 1);
scanf("%lf", &arrayElement);
printf("\n");
//*(arrayMatrix + row * numColumns + column) = arrayElement;
//arrayMatrix[row + numColumns + column] = arrayElement;
arrayMatrix[row][column] = arrayElement;
}
}
// TEST PRINT
for(row = 0; row < numRows; row++)
{
for(column = 0; column < numColumns; column++)
{
//printf("%5.2lf", *(arrayMatrix + row * numColumns + column));
//printf("%5.2lf", arrayMatrix[row + numColumns + column]);
printf("%5.2lf", arrayMatrix[row][column]);
}
printf("\n");
}
I think I understand what you are wanting to do. Before we talk code, let's back up and bit and learn a little about the different ways a 2D array can be simulated in C. You have 2 basic approaches. You can statically or dynamically declared an array array[row][col] = {{r0c0, r0c1, r0c2, ...}, {r1c0, r1c1, r1c2, ...} ... }; which will create a single block of memory, with the values stored sequentially r0c0, r0c1, r0c2, ..., r1c0, r1c1, r1c2, ...., or you can create row number of pointers with each pointing to an individual array of col elements. The second method (the row number of pointers each pointing to arrays of col elements) need not be sequential in memory. It can be, but there is no requirement that it is.
The array index notation array[i][j] will take care of handling the offset within a sequential block of memory to provide access to any individual element. The same holds true for access to any element of within the individual col sizes array pointed to by array[i]. But what is actually happening?
Let's look at the notation of a simple 4-element array, say array[4]. To access any element, you could request any element array[0] to array[3] to access all 4 elements. What is array[2] really? You know array is also a pointer. You know that to access the value at the address held by the pointer you need to dereference the pointer. To access array[0], you could simply write *array, but how would you access the 2nd element with pointer notation?
As we discussed earlier, all the elements in an array declared as we have declared this example are stored sequentially in memory. So, to access any element in the array, all you need is the offset from the beginning of the array. Since you know the beginning address of the array is just array, if you wanted the 2nd element, you would need to access the element offset 1 from the beginning, or at *(array + 1) -- try it. In fact you can access all elements at offsets 0-3 from the beginning with *(array + i) where i is a number in 0-3.
Looking back a bit, that also explains why you can access the 1st element in an array by simply using *array. If you wrote the full syntax for the first element you would have *(array + 0) -- and you know the + 0 is doing nothing so that is why you can access the 1st element with *array because *(array + 0) = *array.
OK, what about the 2D case? If array[x] is *(array + x), what is array[x][y]? Break it down. You know you can write array[x] as *(array + x), so array[x][y] can be written *(array + x)[y] (and if we substitute stuff for *(array + x) for the moment, we can write stuff[y]. We know how to write that in pointer notation: *(stuff + y), right? Now just substitute *(array + x) for stuff and you get *(*(array + x) + y). That is your full pointer notation for accessing any element within a sequential block of memory in a simulated 2D array manner and that is what is happening behind the scene when you write array[x][y].
Now let's talk pointer arithmetic. When you declare a pointer, you are declaring a pointer to a specific type (except in the case of void). That type tells the compiler how to handle the arithmetic with that pointer. For example, if you declare:
char array[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
char *p = array;
The compiler knows that each char occupies 1-byte of memory, so when you write *(p + 1), you are asking for the char value 1-byte from the beginning of array. The same holds true if you write p++; then *p. But what happens with:
int array[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int *p = array;
By virtue of knowing the type is int and that an int is 4-bytes (platform dependent), when you write *(p + 1) or p++; *p;, you will get the 2nd element in the array, but the value is 4-bytes from the beginning of the array. The type tells the compiler how to handle pointer arithmetic (i.e. the offset) for any given value.
You can cement that for yourself with a minimal example:
#include <stdio.h>
#define ROWS 2
#define COLS 2
int main (void) {
int a[ROWS][COLS] = {{ 1, 2 }, { 3, 4 }};
int *p = *a;
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++)
printf (" %2d", a[i][j]);
putchar ('\n');
}
/* using a pointer to access the values */
for (i = 0; i < ROWS * COLS; p++, i++)
printf (" %2d", *p);
putchar ('\n');
return 0;
}
Output
$ ./bin/array_min
1 2
3 4
1 2 3 4
Now on to what you actually asked about. Given all we have discussed, what are you declaring when you declare:
double (*arrayMatrix)[NCOLS] = calloc (NROWS, NCOLS * sizeof **arrayMatrix);
You are declaring and allocating space for a pointer to what? A pointer to an array of doubles with NCOLS elements. How many of those do you need to hold the complete array? You will need NROWS number of pointers to arrays holding NCOLS elements each. Note above the use of calloc instead of malloc. There is an important, but subtle difference, in both the syntax and what they do. malloc will allocate memory for you, but that memory is uninitialized and can contain all manner of stuff. calloc also allocates, but then initializes the memory to zero. Which when dealing with numeric arrays is useful to prevent the accidental access of an uninitialized element (resulting in undefined behavior). There is a marginal speed difference between malloc and calloc as the result, but you will be hard pressed to find a measurable difference in anything less than a few million allocations.
With that background, consider again what you are trying to do. With very few tweaks, you would have it make more sense if you did something like:
#include <stdio.h>
#include <stdlib.h>
#define NROWS 2
#define NCOLS 3
int main (void) {
size_t row = 0;
size_t col = 0;
/* allocate NROWS (array of pointers to NCOLS doubles). using
* calloc will allocate and initialize all elements to zero.
*/
double (*arrayMatrix)[NCOLS] = calloc (NROWS, NCOLS * sizeof **arrayMatrix);
/* prompt user for input, validate a proper value is entered */
printf("\nPlease enter the elements of your augmented matrix:\n");
for(row = 0; row < NROWS; row++)
{
for(col = 0; col < NCOLS; col++)
{
while (printf(" A[%zu][%zu]: ", row + 1, col + 1) &&
scanf("%lf", &arrayMatrix[row][col]) != 1)
printf("\n");
}
}
/* printf the array of pointers */
printf ("\n The matrix entered was:\n\n");
for(row = 0; row < NROWS; row++)
{
for(col = 0; col < NCOLS; col++)
{
printf(" %5.2lf", arrayMatrix[row][col]);
}
printf("\n");
}
free (arrayMatrix);
return 0;
}
Output
$ ./bin/arraymatrix
Please enter the elements of your augmented matrix:
A[1][1]: 1
A[1][2]: 2
A[1][3]: 3
A[2][1]: 4
A[2][2]: 5
A[2][3]: 6
The matrix entered was:
1.00 2.00 3.00
4.00 5.00 6.00
Memory Error/Leak Check
In any code your write that dynamically allocates memory, you have 2 responsibilites regarding any block of memory allocated: (1) always preserves a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed. It is imperative that you use a memory error checking program to insure you haven't written beyond/outside your allocated block of memory and to confirm that you have freed all the memory you have allocated. For Linux valgrind is the normal choice. There are so many subtle ways to misuse a block of memory that can cause real problems, there is no excuse not to do it. There are similar memory checkers for every platform. They are all simple to use. Just run your program through it.
$ valgrind ./bin/arraymatrix
==17256== Memcheck, a memory error detector
==17256== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==17256== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==17256== Command: ./bin/arraymatrix
==17256==
Please enter the elements of your augmented matrix:
A[1][1]: 1
A[1][2]: 2
A[1][3]: 3
A[2][1]: 4
A[2][2]: 5
A[2][3]: 6
The matrix entered was:
1.00 2.00 3.00
4.00 5.00 6.00
==17256==
==17256== HEAP SUMMARY:
==17256== in use at exit: 0 bytes in 0 blocks
==17256== total heap usage: 1 allocs, 1 frees, 48 bytes allocated
==17256==
==17256== All heap blocks were freed -- no leaks are possible
==17256==
==17256== For counts of detected and suppressed errors, rerun with: -v
==17256== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Let me know if you have further questions. My fingers are tired. This ended up much longer than I anticipated...
Here is a function that will allocate a contiguous 2d array of doubles:
double* alloc_array_2d(int Width, int Height){
return (double*)malloc(Width * Height * sizeof(double));
}
Here is a function that will get a pointer to an element of the array based on an x and y coordinate:
double* get_element_2d(double* Array, int Width, int X, int Y){
int index = (Width * Y) + X;
return Array[index];
}
With this method a 5 x 3 array could be imagined to look like this:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
In computer memory it actually looks like this:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
The basic idea is that the beginning of one row of values sits beside the end of the previous row of values, so by multiplying the width of the array by the vertical coordinate you offset the index into the correct row. For example to access the third object in the second row (7) we call
get_element_2d(myArray, 5, 2, 1); // 1 * 5 + 2 = 7
Note that each of the coordinates starts at zero just like with all pointer arithmetic, so to access an element in the first row you would use get_element_2d(Array, Width, X, 0)
Your first code sample looks correct, if you had double arrayElement; earlier.
However, if perhaps you had it as int arrayElement; or some other data type instead, it would explain what you are seeing, because %lf can only be used with double.
Modern compilers are able to give a warning for this problem, so you could investigate which compiler switches you are using to make sure you are getting the maximum possible warning level.
To avoid this error you could scan directly into the array:
scanf("%lf", &arrayMatrix[row * numColumns + column]);
NB. You seem to have got alternative variations of each line that accesses the array, where you change from pointer notation to index notation. Generally speaking, index notation is considered easier to read and therefore preferable.

dynamic array with unknown size

I want to write a program in C where the user types in 2 numbers a and b.
0 < a < INT_MAX
a < b < INT_MAX
The program checks how many Prime numbers are in between a and b and saves all of them in a dynamic array.
For the malloc function I need the size of the array, which means I have to first check all numbers if they are prim numbers just to get the size of the array,
then use malloc(),
and then check all numbers again to fill the array.
Is there any possibility to make this run faster and not doing the same thing twice?
for (int i = a; i <= b; i++)
{
if (check_if_prime(i) == 0)
size++;
}
primze_numbers = malloc(size*sizeof(int));
int j = 0;
for (int i = a; i <= b; i++)
{
if(check_if_prime(i) == 0)
{
prime_numbers[j] = i;
j++;
}
}
Since the size is unknown in the beginning, allocating the space for the size of one more element is inefficient.
One possible solution is: reallocate the space(Use realloc) twice the size of the previous size whenever the size is not enough.
Real size - Space size
0 0
1 1
2 2
3 4
4 4
5 8
6 8
7 8
8 8
9 16
10 16
... ...
This way, the times of reallocation is not much, and you don't waste much space.
If you are able to use c++ - you can use std::vector which solves your problem.

Resources