I am trying to read a Multidimensional String Matrix from a file and store it to a array of Character Arrays like this:
char *A[M][N];
This works fine if I stay inside the main function.
But when i am trying to call a function by reference it doesn't work.
Function Call:
readMatrix(file,A);
Function Header:
int readMatrix(FILE *file,char *matrix[][]);
I also tried this:
int readMatrix(FILE *file,char ***matrix);
which also doesn't work.
I want to manipulate the Array in the function therefore i need to make a reference call.
You must pass N as part of the matrix type to your ReadMatrix function, and since it is not known at compile time, you must pass these as arguments too:
int readMatrix(FILE *file, size_t M, size_t N, char *matrix[][N]);
You could indeed also specify the array argument as char *matrix[M][N], but the first dimension size M is ignored for a function argument as it only receives a pointer to the array.
Here is an example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int readMatrix(FILE *file, size_t rows, size_t cols, char *matrix[][cols]) {
int rc = 0;
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
char buf[80];
if (rc == 0 && fscanf(file, "%79s", buf) == 1) {
matrix[i][j] = strdup(buf);
} else {
matrix[i][j] = NULL;
rc = -1;
}
}
}
return rc;
}
int main(void) {
size_t rows, cols;
if (scanf("%zu %zu", &rows, &cols) != 2)
return 1;
char *mat[rows][cols];
if (readMatrix(stdin, rows, cols, mat) == 0) {
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
printf(" %8s", mat[i][j]);
}
printf("\n");
}
}
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
free(mat[i][j]);
}
}
return 0;
}
You can do it by using this approach:
#include <stdio.h>
#define MAX_WORD_SIZE 10
void readMatrix(FILE*,char****);
int main(void){
FILE* cin = fopen("input.txt","r");
char*** inputMatrix;
readMatrix(cin,&inputMatrix);
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
printf("%s ",*(*(inputMatrix+i)+j));
}
printf("\n");
}
fclose(cin);
return 0;
}
void readMatrix(FILE* cin,char**** matrix){
int rowNum,columnNum;
char buff[10];
int intBuff;
fscanf(cin,"%d",&intBuff);
rowNum = intBuff;
fscanf(cin,"%d",&intBuff);
columnNum = intBuff;
*matrix = malloc(rowNum*sizeof(char**));
for(int i=0;i<rowNum;i++){
*(*matrix+i) = malloc(columnNum*sizeof(char*));
}
for(int i=0;i<rowNum;i++){
for(int j=0;j<columnNum;j++){
*(*(*matrix+i)+j) = malloc(MAX_WORD_SIZE*sizeof(char));
fscanf(cin,"%s",*(*(*matrix+i)+j));
}
}
}
with this input file(input.txt file within same folder), this code is working well on Linux GCC
3 3
ab cd ef
gh ij kl
mn op qr
In the first line of input.txt file, first integer denotes row number, second integer denotes column number.
Related
#include <stdio.h>
int inputNumber();
void printTriangle(int size, char ch[]);
int main()
{
char arr_char[] = {'a','e','i','o','u'};
int number;
number = inputNumber();
printTriangle(number,arr_char);
return 0;
}
int inputNumber()
{
int size;
printf("Input Size: ");
scanf("%d",&size);
printf("===\nTriangle Size is %d\n===\n",size);
return size;
}
void printTriangle(int size, char ch[5])
{
int i,j;
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
if(j <= 4)
{
printf("%s ",ch[j]);
}
if(j > 4 )
{
printf("# ");
}
}
}
}
This is what it supposed to look like. And I'm confused as what I did wrong because it only work with inputNumber but not with printTriangle. a e i o u # # # please go easy on me since I'm kinda new to this.
The segmentation fault is caused by an incorrect format string (%s should be %c). The output format doesn't match expectations as the inner loop condition is wrong and you need a newline after you print each line (after inner loop):
#include <stdio.h>
#define LEN 5
int inputNumber() {
int size;
printf("Input Size: ");
scanf("%d",&size);
printf("===\nTriangle Size is %d\n===\n",size);
return size;
}
void printTriangle(int size, char ch[]) {
for(int i = 0; i < size; i++) {
for(int j = 0; j <= i; j++) {
printf("%c ", j < LEN ? ch[j] : '#');
}
printf("\n");
}
}
int main() {
char arr_char[LEN] = {'a','e','i','o','u'};
int number;
number = inputNumber();
printTriangle(number,arr_char);
return 0;
}
Consider using the type unsigned instead of int as negative size, row (i) and column (j) doesn't make sense.
Here is an alternatively implementation of printTriangle() that does a bit of work upfront to generate the last row, then use a prefix of that last row to print all rows:
void printTriangle(unsigned size, char ch[]) {
// use malloc if size is large (say >4k),
// or you don't want to use a variable length array (VLA)
char str[2 * size];
for(unsigned column = 0; column < size; column++) {
str[2 * column] = column < LEN ? ch[column] : '#';
str[2 * column + 1] = ' ';
}
for(unsigned row = 0; row < size; row++) {
printf("%.*s\n", 2 * row + 1, str);
}
}
Ok I need to write two functions iterative and recursive to count negative elements in an array and then I need to build main. I was only able to write the recursive function but I cannot call it from main, it is an error somewhere. Can someone help me out solve it and help me with the iterative method?
#include <stdio.h>
main()
{
int vektor[100];
int i, madhesia;
/* Input size of array */
printf("Madhesia e vektorit: ");
scanf("%d", &madhesia);
/* Input array elements */
printf("Elementet: ");
for (i = 0; i < madhesia; i++)
{
scanf("%d", &vektor[i]);
}
int ret = numero(vektor, madhesia);
printf("\nTotal negative elements in array = %d", ret);
return 0;
}
int numero(array, size)
{
int count = 0;
for (int j = 0; j < size; j++)
{
if (array[j] < 0)
{
count++;
}
}
return count;
}
A working piece of code is this.You really need to take a look at pointers and the way they work.
Here you can see that I have a pointer ->pointing-< at the start of the array , so by passing the starting address of the array , and the length of the array , your functions knows what it is needed to be done.
#include <stdio.h>
int numero(int* array, int size);
int* recursive_count(int* array, int size , int* counter );
int main()
{
int vektor[100];
int* vekt_ptr = &vektor[0];
int i, madhesia;
int counter;
counter=0;
/* Input size of array */
printf("Madhesia e vektorit: ");
scanf("%d", &madhesia);
/* Input array elements */
printf("Elementet: ");
for (i = 0; i < madhesia; i++)
{
scanf("%d", &vektor[i]);
}
//int ret = numero(vekt_ptr, madhesia);
recursive_count(vekt_ptr, madhesia , &counter );
int ret = counter;
printf("\nTotal negative elements in array = %d", ret);
return 0;
}
int numero(int* array, int size)
{
int count = 0;
int j;
for (j = 0; j < size; j++)
{
if (array[j] < 0)
{
count++;
}
}
return count;
}
int* recursive_count(int* array, int size , int* counter )
{
size--;
if(array[size] < 0 )
{
(*counter)++;
}
if(size==0)
{
return NULL;
}
return recursive_count(array++, size , counter );
}
Let's assume that you want to create dynamically an array of X length.
The compiler is going to have some memory for your array , depending on the length.
You initialize your array , lets say [2][45][1][-5][99]
When you call the function you have to pass where this is stored in memory.
int* vekt_ptr = &vektor[0]; -s going to give as something like 0x56c2e0.
This number is the address of your array , which is the address of the starting point of the array.This is equal with the address of first byte.
So when your function starts , it knows where your array starts and how long it is.
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
Any function used in a program shall be declared before its usage.
This function declaration of the function definition
int numero(array, size)
{
// ...
}
is invalid because the types of the parameters array and size are undefined.
For the size of an array and for the count of elements it is better to use an unsigned integer type like for example size_t or at least unsigned int.
The program can look the following way
#include <stdio.h>
#define N 100
size_t iterative_numero( const int array[], size_t size );
size_t recursive_numero( const int array[], size_t size );
int main( void )
{
int vektor[N];
size_t madhesia = 0;
/* Input size of array */
printf("Madhesia e vektorit: ");
scanf("%zu", &madhesia);
if ( N < madhesia ) madhesia = N;
/* Input array elements */
printf("Elementet: ");
for ( size_t i = 0; i < madhesia; i++ )
{
scanf( "%d", &vektor[i] );
}
size_t ret = iterative_numero(vektor, madhesia );
printf("\nTotal negative elements in array = %zu\n", ret);
ret = recursive_numero(vektor, madhesia );
printf("Total negative elements in array = %zu\n", ret);
return 0;
}
size_t iterative_numero( const int array[], size_t size )
{
size_t count = 0;
for ( size_t i = 0; i < size; i++)
{
if ( array[i] < 0 )
{
count++;
}
}
return count;
}
size_t recursive_numero( const int array[], size_t size )
{
return size == 0 ? 0 : ( array[0] < 0 ) + recursive_numero( array + 1, size - 1 );
}
the program output might look like
Madhesia e vektorit: 10
Elementet: 0 -1 2 -3 4 -5 6 -7 8 -9
Total negative elements in array = 5
Total negative elements in array = 5
First of all what you did is the iterative method, not recursive. Here I have called a recursive function from the main function.
#include <stdio.h>
int main()
{
int vektor[100];
int i, madhesia;
/* Input size of array */
printf("Madhesia e vektorit: ");
scanf("%d", &madhesia);
/* Input array elements */
printf("\nElementet: ");
for (i = 0; i < madhesia; i++)
{
scanf("%d", &vektor[i]);
}
printf("\nno of elements:%d",madhesia);
printf("\n");
for (i = 0; i < madhesia; i++)
{
printf("%d", vektor[i]);
}
printf("\n");
i=0;
int ret = numero(vektor,madhesia,0,i);
printf("\nTotal negative elements in array = %d", ret);
return 0;
}
int numero(int array[],int size,int count,int j)
{
if (j<=size-1)
{
if(array[j]<0)
{
count++;
j++;
numero(array,size,count,j);
}
else
{
j++;
numero(array,size,count,j);
}
}
return count;
}
Put function prototype of numero() before main() to be able to call it. Declare function parameters with type:
int numero(int array[], int size);
int main() {
...
#include<stdio.h>
int numero(int *, int); //Function Prototype (1)
int main() //Return Type (2)
{
int vektor[100];
int i, madhesia;
printf("Madhesia e vektorit: ");
scanf("%d", &madhesia);
printf("Elementet: ");
for (i = 0; i < madhesia; i++)
{
scanf("%d", &vektor[i]);
}
int ret = numero(vektor, madhesia);
printf("\nTotal negative elements in array = %d", ret);
return 0;
}
int numero(int* array,int size) //Parameters Data Type (3)
{
int count = 0;
for (int j = 0; j < size; j++)
{
if (array[j] < 0)
{
count++;
}
}
return count;
}
Errors:
You have declared the function after "main()" so the program doesn't know that there is a function, so you have to give the function prototype before "main()" so that the program knows there is function ahead.
You missed writing the return type of "main()" which is integer.
In the function declaration you forgot to write the data type of the parameters.
NOTE: The array is always passed by reference so it has to taken in an integer pointer instead of a normal integer.
Some possible implementations:
int iterativeCountNegativeIntegers (int *array, int size)
{
int result = 0;
for (int i = 0; i < size; ++ i)
if (array[i] < 0)
result += 1;
return result;
}
int recursiveCountNegativeIntegers (int *array, int size)
{
if (size == 0)
return 0;
int partial = *array < 0;
return partial + recursiveCountNegativeIntegers(array+1, size-1);
}
The same, condensed:
int iterativeCountNegativeIntegers_1 (int *array, int size)
{
int result = 0;
while (--size >= 0)
result += *array++ < 0;
return result;
}
int recursiveCountNegativeIntegers_1 (int *array, int size)
{
return (size == 0) ? 0
: (*array < 0) + recursiveCountNegativeIntegers_1(array+1, size-1);
}
I have to do an exercise where I have a certain numbers of functions and every function do a different thing like sort all the negative numbers from the array.
Moreover I have to create a function display with 3 argument pointers to an array, size of it and a name of a function which receives int and that the issue is int (Function pointer). I try to do this but this don't work and I don't know what to do in order to do correctly this exercise with a function pointer, because I don't understand that.
This is my code
int main (int argc, char **argv)
{
srand (time (NULL));
int arr[MAX_SIZE], second_arr[MAX_SIZE], i;
random_arr (arr);
display (arr, 20, negative_number (arr, second_arr));
system ("PAUSE");
return 0;
}
void random_arr (int *my_arr)
{
int i;
for (i = 0; i < MAX_SIZE; i++) {
*(my_arr + i) = i - 10;
}
}
int negative_number (int *arr, int *sort_arr)
{
int i;
for (i = 0; i < 20; i++) {
if (arr[i] < 0) {
sort_arr[i] = arr[i];
}
}
return sort_arr;
}
void diplay (int *arr, int size, int (*a_function) (int, int))
{
int i = 0;
for (i = 0; i < size; i++) {
printf ("%d\n", a_function);
}
}
It might be different from your intentions because your intentions is not clear.
but I think this would be helpful
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_SIZE 20
void random_arr (int size, int *my_arr);
int negative_number (int size, int *arr, int *sort_arr);
void display (int *arr, int size, int (*filter_function) (int in_size, int *in_array, int *out_array));
int main (void){
int arr[MAX_SIZE], second_arr[MAX_SIZE], i;
srand(time(NULL));
random_arr(MAX_SIZE, arr);
for(i = 0; i < MAX_SIZE; ++i)
printf("%d ", arr[i]);
puts("");
display (arr, MAX_SIZE, negative_number);
system ("PAUSE");
return 0;
}
void random_arr (int size, int *my_arr){
int i;
for (i = 0; i < size; i++) {
my_arr[i] = rand()%MAX_SIZE - MAX_SIZE/2;
}
}
int negative_number (int size, int *arr, int *sort_arr){
int i, j = 0;
for (i = 0; i < size; i++) {
if (arr[i] < 0) {
sort_arr[j++] = arr[i];
}
}
return j;//new array size
}
void display (int *arr, int size, int (*filter)(int in_size, int *in_array, int *out_array)){
int i = 0;
int *out = malloc(size * sizeof(*out));
int out_size = filter(size, arr, out);
for (i = 0; i < out_size; i++) {
printf ("%d\n", out[i]);
}
free(out);
}
I am trying to create a structure that will have two integer values, an array, and two 2-D matrices using my code below. I can initialize the structure with the integers and array just fine, and my 'Gen' function will create the random values I want for the array.
However, when I try adding in the matrix components, I run into a problem. My compiler gives me a warning: "initialization from incompatible pointer type". If I understand what I have read so far, this is because the structure needs to be pointed to an array of pointers that represent each row in the matrix. I don't know the syntax for that.
A quick note: the other topics I've seen that are related to this issue all initialize the structure in a function other than the main() function, so I haven't found those solutions helpful.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <string.h>
// Define structure
typedef struct {
int row;
int col;
int *arr;
int **mat1;
int **mat2;
}container;
// Function headers
void Gen(container Thing);
int main() {
int row = 5;
int col = 6;
int A[row];
int M1[row][col];
int M2[row][col+1];
// Initialize structure
container Object = {row, col, A, M1, M2};
// Run "Gen" function
Gen(Object);
int i, j; // Index variables
// Display the array
for(i = 0; i < row; i++)
{
printf("%i ", Object.arr[i]);
}
printf("\n\n");
// Display the numbers from the matrices
for(j = 0; j < Object.row; j++)
{
for(i = 0; i < Object.col; i++)
{
printf("%i ", Object.mat1[j][i]);
}
printf("\n");
}
printf("\n");
for(j = 0; j < Object.row; j++)
{
for(i = 0; i < Object.col; i++)
{
printf("%i ", Object.mat2[j][i]);
}
printf("\n");
}
return (EXIT_SUCCESS);
}
// Function to generate random values in the array & matrices
void Gen(container Thing)
{
int i, j;
srand(time(NULL));
// Generate random values for the array
for(i = 0; i < Thing.row; i++)
{
Thing.arr[i] = rand() % 5;
}
// Generate random values for the matrix
for(j = 0; j < Thing.row; j++)
{
for(i = 0; i < Thing.col; i++)
{
Thing.mat1[j][i] = rand() % 5;
Thing.mat2[j][i] = rand() % 5;
}
}
} // End of "Gen" function
container Object = {row, col, A, M1, M2};
is wrong since the type of M1 is int[row][col], which can decay to int (*)[col] but not to int**. You have the same problem with M2.
You'll need to rethink your strategy for generating a container.
For example:
int main() {
int row = 5;
int col = 6;
int A[row];
int* M1[row];
int* M2[row];
for ( int i = 0; i < row; ++i )
{
M1[i] = malloc(sizeof(M1[i][0])*col);
M2[i] = malloc(sizeof(M1[i][0])*(col+1));
}
// Initialize structure
container Object = {row, col, A, M1, M2};
...
for ( int i = 0; i < row; ++i )
{
free(M1[i]);
free(M2[i]);
}
return (EXIT_SUCCESS);
}
I have a pointer to a pointer ("paths") and I want to reallocate each pointer (each "path"). But I get a crash. Generally I am trying to find all possible powers of a number, which one can compute for some amount of operations (e.g for two operations we can get power of three and four (one operation for square of a number, then another one either for power of three or four)). I figured out how to do it on paper, now I am trying to implement it in code. Here is my try:
#include <stdio.h>
#include <stdlib.h>
void print_path(const int *path, int path_length);
int main(void)
{
fputs("Enter number of operations? ", stdout);
int operations;
scanf("%i", &operations);
int **paths, *path, npaths, npath;
npaths = npath = 2;
path = (int*)malloc(npath * sizeof(int));
paths = (int**)malloc(npaths * sizeof(path));
int i;
for (i = 0; i < npaths; ++i) // paths initialization
{
int j;
for (j = 0; j < npath; ++j)
paths[i][j] = j+1;
}
for (i = 0; i < npaths; ++i) // prints the paths, all of them are displayed correctly
print_path(paths[i], npath);
for (i = 1; i < operations; ++i)
{
int j;
for (j = 0; j < npaths; ++j) // here I am trying to do it
{
puts("trying to reallocate");
int *ptemp = (int*)realloc(paths[j], (npath + 1) * sizeof(int));
puts("reallocated"); // tried to write paths[j] = (int*)realloc...
paths[j] = ptemp; // then tried to make it with temp pointer
}
puts("memory reallocated");
++npath;
npaths *= npath; // not sure about the end of the loop
paths = (int**)realloc(paths, npaths * sizeof(path));
for (j = 0; j < npaths; ++j)
paths[j][npath-1] = paths[j][npath-2] + paths[j][j];
for (j = 0; j < npaths; ++j)
print_path(paths[j], npath);
puts("\n");
}
int c;
puts("Enter e to continue");
while ((c = getchar()) != 'e');
return 0;
}
void print_path(const int *p, int pl)
{
int i;
for (i = 0; i < pl; ++i)
printf(" A^%i -> ", p[i]);
puts(" over");
}
I am not sure the problem resides with the call to realloc(), rather you are attempting to write to locations for which you have not created space...
Although you create memory for the pointers, no space is created (allocate memory) for the actual storage locations.
Here is an example of a function to allocate memory for a 2D array of int:
int ** Create2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = calloc(space, sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
void free2DInt(int **arr, int cols)
{
int i;
for(i=0;i<cols; i++)
if(arr[i]) free(arr[i]);
free(arr);
}
Use example:
#include <ansi_c.h>
int main(void)
{
int **array=0, i, j;
array = Create2D(array, 5, 4);
for(i=0;i<5;i++)
for(j=0;j<4;j++)
array[i][j]=i*j; //example values for illustration
free2DInt(array, 5);
return 0;
}
Another point here is that it is rarely a good idea to cast the return of [m][c][re]alloc() functions
EDIT
This illustration shows my run of your code, just as you have presented it:
At the time of error, i==0 & j==0. The pointer at location paths[0][0] is uninitialized.
EDIT 2
To reallocate a 2 dimension array of int, you could use something like:
int ** Realloc2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = realloc(arr, space*sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
And here is a test function demonstrating how it works:
#include <stdio.h>
#include <stdlib.h>
int ** Create2D(int **arr, int cols, int rows);
void free2DInt(int **arr, int cols);
int ** Realloc2D(int **arr, int cols, int rows);
int main(void)
{
int **paths = {0};
int i, j;
int col = 5;
int row = 8;
paths = Create2D(paths, col, row);
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
//reallocation:
col = 20;
row = 25;
paths = Realloc2D(paths, col, row);
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
free2DInt(paths, col);
getchar();
return 0;
}
The realloc() does not fail. What fails is that you haven't allocated memory for the new pointers between paths[previous_npaths] and paths[new_npaths-1], before writing to these arrays in the loop for (j = 0; j < npaths; ++j).