Dynamic Allocation Two dimensional array of fixed-length strings - c

In a program, I have to scan from the input
scanf("%s",currWord);
a non-defined number of words, which come in a non-defined number of lines.
I want to put the words in a 2 dimensional array of strings.
Length of the strings is fixed [MAX_WORD_LEN+1]
My idea is:
int row=10 //10 lines for starting
int col=5 //5 words in each line for starting
int i;
typedef char word[MAX_WORD_LEN+1]; //new type of 11char lenght string
word** matrix; //2 dimensional array (pointers) with no memory
matrix = malloc(row*sizeof(word*)); //allocate row number of word* (word pointer) size
for(i=0;i<row;i++)
{
matrix[i] = malloc(col*sizeof(word)); //allocate col number of words to each row
}
So, I have no idea if that is right.
I'll be happy for some help and tips..
EDIT:
When receiving the words from input I have to increase memory ( number of rows and words in each row) if needed, How do I do that? (realloc ?)
I need to do the following:

Without going into details, the easiest way is to use a Matrix as a Linked-List of Linked-Lists ..
struct matrix_field
{
char data [11];
matrix_field * next_field;
};
struct matrix_row
{
matrix_field * first_field;
matrix_row * next_row;
};
struct matrix
{
matrix_node * first_row;
};
Your data will look like this in memory ..
[+]
|
v
[x]-->[a]-->[b]-->[c]-->
|
v
[y]-->[d]-->[e]-->[f]-->
|
v
[z]-->[g]-->[h]-->[i]-->
|
v
---------------
[+] matrix
[x] .. [z] matrix_row
[a] .. [i] matrix_field

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

Check for a word in a dictionary in C

I have a project in which I have a file (.dic) with many words with different sizes. And another file (.pal) with some words. For each word of the .pal file, I have to find its position in a list of words with the same number of words, ordered alphabetically from the .dic file.
For example,
in the .dic file:
car
banana
dog
flower
tar
So the dictionary would be something like:
3 letters: [car->dab->dog->tar]
6 letters: [banana->flower]
in the .pal file:
dog
flower
So the output would be:
dog in position 3
flower in position 2
My question is: What is the best data structure to implement this in C, so that it takes the least memory and time?
I was thinking of having a matrix in which each the first index (index1) corresponds to the number of letters in the word, and the second index (index2) corresponds to the first letter of the word I'm looking for. Each element of that matrix is a list of words with index1 letters and starting in letter index2.
Example:
| A | B | C | .....
_______________
1|list|list|list|
2|list|....|....|
3|...
.
.
So "dog" would be in a list inside matrix[3][D].
Problem 1: the matrix will have hole if there aren't words with all different number of letters or different first letters -> too much memory wasted?
Problem 2: to know the position I asked before I would have to sum up the number of elements of each list before the one I'm using.
Example: "dog" position would be
number of element in list [3][A]+number of element in list [3][B]+number of element in list [3][C]+"dog" position in the list
So when I inserted a word in a list, I would have to update the numbers of elements of the lists in the next matrix elements. -> time consuming?
So what do you think of this method? Do you have better ideas?
What is the best data structure to implement this in C, so that it takes the least memory and time?
It's difficult to get both least memory and least time. If you want to keep memory usages as low as possible, you'll need dynamic memory allocation which is expensive when considering time.
To get low memory usage, you could go for the following data structure:
#define MAX_WORD_LEN 50
char** dic[MAX_WORD_LEN];
You use it like this:
index 0: -----> char*, char*, char*, ... // Words with length 1
| | |
| | ------> string (i.e. char, '\0')
| |
| ------> string (i.e. char, '\0')
|
------> string (i.e. char, '\0')
index 1: -----> char*, char*, ... // Words with length 2
| |
| ------> string (i.e. char, char, '\0')
|
------> string (i.e. char, char, '\0')
This allows you to store a variable number of words for each length and you don't allocate more memory than needed for each string. It is like a matrix but the benefit is that each row can have different number of columns.
You will however need quite some dynamic memory handling, i.e. malloc, realloc and strdup.
To save some execution time you should grow the "char*, char*, char*, ..." array by some N larger than 1 and set the unused entries to NULL. That will save a lot of realloc but you'll need to keep track on the number of allocated elements in each row. That could call for something like:
struct x
{
char** data;
int number_allocated;
}
#define MAX_WORD_LEN 50
struct x dic[MAX_WORD_LEN];
If memory usage is real hot, you can avoid the "char*, char* ..." array and just use one big char array for each word length. Like:
index 0: -----> 'a', '\0', 'I', '\0', ...
index 1: -----> 'b', 'e', '\0', 't', 'o', '\0', ....
You can do this because all words in a char-array has the same length.
In this case you would have something like:
struct x
{
char* data;
int bytes_allocated;
int number_of_words;
}
#define MAX_WORD_LEN 50
struct x dic[MAX_WORD_LEN];

Copying matrix from .txt into array

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.

How should you add elements to a multi dimensional array? (In C)

I'm working on a table football cup program (in C), where I have 16 people facing off to get to the final. I'm having trouble putting elements into the different elements of the array (which has sort of stopped my progress until I figure it out). I've searched on the internet (not extensively) about pointers, but I can't find anything on multi dimensional arrays.
I have 8 games, each with 2 participants, who each play 5 matches against each other. Hopefully that means I define the array as int lastSixteen[8][2][5]. All participants have a unique ID
Assuming I have declared my arrays correctly... On to the main question.
This is what I'm currently doing:
int i;
for(i=0; i<MAX_PLAYERS/2;i++){
roundOne[i] = i;
}
I want to set the first dimension of my array to be the numbers 1 through 8 incl. but I run into 'error: incompatible types in assignment'.
I tried setting the line with the assignment to be roundOne[i][][] = i; but as I expected, that didn't work either.
Later on in the program I need to set the second set of numbers to be the games participants to be the 16 participants (to keep it simple I'm doing it in ascending numerical order) so Game 1 is Player 1 and Player 2, Game 2 is Player 3 and 4 etc.
for(i=0; i<16; i++){
if(i % 2 != 0){
roundOne[(MAX_PLAYERS/2)-1][0] = i; /* puts 1,3,5,7,9,11,13,15 */
}
else{
roundOne[(MAX_PLAYERS/2)-1][1] = i; /* puts 2,4,6,8,10,12,14,16 */
}
}
I'm assuming the second part will be fixed by the answer to the first part since they return the same error, but I included it because I don't know.
A sample of code that has a minimal, Complete, and Verifiable example.
#include <stdio.h>
#define MAX_PLAYERS 16
int main(void){
int i;
int roundOne[8][2][5];
/* seeded in numerical order.*/
for(i=0; i<MAX_PLAYERS/2;i++){
roundOne[i] = i;
}
for(i=0; i<MAX_PLAYERS; i++){
if(i % 2 != 0){
roundOne[(MAX_PLAYERS/2)-1][0] = i;
}
else{
roundOne[(MAX_PLAYERS/2)-1][1] = i;
}
}
return 0;
}
Thanks in Advance,
Rinslep
You can't just use a multi dimensional array - it doesn't do what you want. And here is why: Lets say you have 8 games and 2 players (forget that there are 5 matches for a second) That means your multi dimensional array would have 16 spots:
Player
0 1
+---+---+
0 | | |
+---+---+
1 | | |
+---+---+
2 | | |
G +---+---+
a 3 | | |
m +---+---+
e 4 | | |
+---+---+
5 | | |
+---+---+
6 | | |
+---+---+
7 | | |
+---+---+
Now you want to put the game number in there AND you want to put the unique player IDs in there AND you might want to put other stuff in there (like who won and the score)? How are you going to do that? There are a couple choices:
The game number is the index into the array - not a value you store in the array. Now you can store the palyer IDs for each game in the array. But this still doesn't address storing other stuff (like who won and the score)
If the game number needs to be stored in the array (or other things like who won and the score) you will need to store more than one thing in the array so the array cannot hold ints - you need an array of structures.
It is hard to guess what the right data structure is because it depends on what your program is going to do, but I think I would do this:
typedef struct match
{
int score[2]; /* index 0 is player 1, index 1 is player 2 */
int winner; /* index into the player and score arrays (either 0 or 1) */
};
typedef struct game
{
int players[2]; /* index 0 is player 1, index 1 is player 2 */
match matches[5];
};
game games[8];
Now, the the game number (1-8) is just the index to games plus 1, the match number (1-5) is just the index to matches plus 1 and if you want to make unique player numbers that go from 1-16 you can do this:
i=1;
for(int g=0;g<8;g++)
for(int p=0;p<1;p++)
games[g].player[p]=i++;
You need to initialize the array with dynamic allocation.
How do I work with dynamic multi-dimensional arrays in C?
Think of it this way
A = [
[B],
[C],
[D],
...
]
So lets say we need an array round with 10 rows and each row has 20 columns. They will all be filled with integer values.
Option One - Dynamically Allocating
Define the number of buckets the array will have. We are taking the size of the pointer because each bucket will container a pointer/array that represents the inner array.
int** round;
round = malloc(10 * sizeof(int*))
Now that we have allocated the space for the buckets, go through and give space for the points. This one is just a normal integer so we take the sizeof(int).
for (int i = 0; i < 10; i++) {
round[i] = malloc(20* sizeof(int))
}
Option Two
We can define the size of the multidimensional array in a bit of an easier way. We know the number of rows and the number of columns. So alternatively we can allocate the space like this:
int* round;
round = malloc (10 * 20 * sizeof(int));
Both of these will produce the array round[10][20] with memory allocated for it. With C you can't add elements to an array on the fly if the size of the array is unknown, in my experience linked lists are better for this.
Edit: I see that you updated the question, this code can be used with a 3D array also. You can easily use option two as 3D like round = malloc(x * y * z * sizeof(int)), where x, y, and z are equal to the dimensional values. You can also modify option one to work with this also.

How do you compare dimensions of two 2 dimensional arrays in C?

I have two 2 dimensional arrays:
#define MAXSIZE 10
/* ... */
int A[MAXSIZE][MAXSIZE], B[MAXSIZE][MAXSIZE];
I'm reading in values from a file:
1 1 2
2 2 -6 4 5 6
On each line, the first two numbers are the row and column sizes for the array, after which are enough (arbitrary) values to fill up an array using those sizes. What I want to do is, after assigning those values to the arrays, check if the dimensions of arrays A and B are the same so I can do matrix arithmetic with them (addition, scalar multiplication, etc).
Why don't you store the row/column sizes for each line into their variables?
int Arow, Acol, Brow, Bcol;
Normally, this would work:
int Acol = sizeof(A[0]);
int Arow = sizeof(A) / Acol;
But your arrays are initialized to fixed sizes.
Have you thought about using malloc to dynamically allocated A and B?
If you simply want to know if the two are == sized:
#define MAXSIZE 10
/* ... */
int A[MAXSIZE][MAXSIZE], B[MAXSIZE][MAXSIZE];
int main(void)
{
int sizea = sizeof(A);
int sizeb = sizeof(B);
int result = (sizea == sizeb) ? (1) : (0);
return 0;
}
Even if you do not explicitly write to each location, the matrices, the way you have them defined, will be the same size.

Resources