printing 2 characters and keeping them through dynamically allocated 2d array - arrays

Hello I am trying to print something like this with 2d array.
Note that when user enters the same number, character should be printed above existing char.
EXPECTED RESULTS:
Input 1: 3 //user1 inputs 3
****
****
**x*
Input 2: 1 //user2 inputs 1
****
****
y*x*
Input 3: 1 //user1 inputs 1
****
x***
y*x*
current results:
enter first: 3
3***
***
**x
enter second: 1
1******
******
xx****
enter first: 2
2*********
*********
***xxx***
But keeping printed values on its previous places.
The problem is that they don't get printed in right order. And also it seems that I haven't done the best job with 2d array which is dynamically allocated.
Here is something what I've tried:
#include <stdio.h>
#include <stdlib.h>
int num(int term)
{
int number1;
int number2;
if(term==1)
{
scanf("%d", &number1);
return number1;
}
if (term==2)
{
scanf("%d", &number2);
return number2;
}
return 0;
}
void function(int a, int b, int result[], int size)
{
int i = 0;
int j = 0;
int desired_num = 0;
int count = 0;
int *arr[a];
for (i = 0; i < a; i++)
arr[i] = (int *)malloc(a * sizeof(int));
for (i = 0; i < a; i++)
for (j = 0; j < b; j++)
arr[i][j] = ++count;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (int counter = 0; counter < size; counter++)
{
if (arr[i][j] == arr[a - 1][result[counter] - 1])
{
arr[i][j] = desired_num;
}
if (arr[i][j] == desired_num)
{
printf("%s", "x");
}
else
{
printf("*");
}
}
}
printf("\n");
}
}
int main()
{
int counter = 1;
int i = 0;
int given_number;
int array[20];
for (;;)
{
if (counter % 2 != 0)
{
printf("enter first: ");
given_number = num(1);
printf("%d", given_number);
}
else
{
printf("enter second: ");
given_number = num(2);
printf("%d", given_number);
}
array[i] = given_number;
function(3, 3, array, counter);
counter++;
}
return 0;
}

array[i] = given_number;
i is never changed from the value of 0. You are only ever overwriting the first element of array each iteration. The other 19 elements remain in an indeterminate state.
counter and array are passed to function, as size and result respectively:
This means as size is incremented, it is used as a bounds for accessing elements of result; elements that contain indeterminate values.
for (int counter = 0; counter < size; counter++)
{
if (arr[i][j] == arr[a - 1][result[counter] - 1])
This will surely lead to Undefined Behaviour as those indeterminate values are used to index arr, effectively accessing random memory offsets. This fact alone makes it hard to reason about the output you are seeing, as really anything is valid.
While perfectly valid, the variable-length array of dynamic allocations is a somewhat perplexing choice, especially considering you fail to free the memory allocated by malloc when you are done with it.
int *arr[a];
for (i = 0; i < a; i++)
arr[i] = (int *)malloc(a * sizeof(int));
int arr[a][b]; would work, given a and b are not stack-crushingly large values (or non-positive). You are, or would be, bounded by the size of array in main anyway.
The triply nested loop is confused at best. There is only logic for printing the x and * characters, so you obviously will never see a y.
For each element of arr, you iterate through each element of result. If the current element of arr equals the value of the column selected by the current value of result ([result[counter] - 1]) in the last row (arr[a - 1]) you print x, otherwise *.
Again UB from utilizing indeterminate values of result, but you can see you are printing a * b * size characters, plus newlines, each iteration.
This is severely flawed.
Some other things of note:
The two branches of the if .. else statement in the num function do the exact same thing, just with different identifiers.
The two branches of the if .. else statement in main are identical, other than the first printf in each, and the integer value passed to num, which have the same effect.
This means the only thing that needs to branch is the printf argument.
A generic function for getting an integer would work fine
int get_num(void)
{
int n;
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Could not read input.\n");
exit(EXIT_FAILURE);
}
return n;
}
for use inside main
if (counter % 2 == 0)
printf("enter first: ");
else
printf("enter second: ");
given_number = get_num();
A small issue: printf("%d", given_number); is muddling the output slightly.
There is no reason to repeatedly generate the array. Initialize an array in main to serve as the state of the program. Over time, fill it with the users' selections, and simply print the array each iteration.
Make sure to always check the return value of scanf is the expected number of conversions, and ensure the integers provided by the users will not access invalid memory.
Here is a cursory example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EMPTY '*'
#define PLAYER_ONE 'X'
#define PLAYER_TWO 'O'
int get_num(void)
{
int n;
if (1 != scanf("%d", &n)) {
fprintf(stderr, "Could not read input.\n");
exit(EXIT_FAILURE);
}
return n;
}
int main(void)
{
const size_t rows = 6;
const size_t cols = 7;
char board[rows][cols + 1];
memset(board, EMPTY, sizeof board);
/* our rows are now strings */
for (size_t i = 0; i < rows; i++) {
board[i][cols] = '\0';
puts(board[i]);
}
unsigned char turn = 1;
while (1) {
printf("Player %s, Enter column #(1-%zu): ",
turn & 1 ? "One" : "Two", rows);
int input = get_num();
if (1 > input || input > cols) {
printf("Invalid column [%d]. Try again...\n", input);
continue;
}
size_t sel = input - 1;
if (board[0][sel] != EMPTY) {
printf("Column [%d] is full! Try again...\n", input);
continue;
}
size_t n = rows;
while (n--) {
if (board[n][sel] == EMPTY) {
board[n][sel] = turn & 1 ? PLAYER_ONE : PLAYER_TWO;
break;
}
}
for (size_t i = 0; i < rows; i++)
puts(board[i]);
turn ^= 1
}
}

Related

Finding Prime and Composite Elements in an array. Print primes in ascending order and composite in descending order

I am successful in identifying prime and composite from an array. But my qsort function seem to not have any effect when I print the output. I need the primes to be ascending and composite to be descending. When I run the code, it does not sort the output, though it identifies primes and composites.
#include <stdio.h>
#include <stdlib.h>
int compare_Asc(const void *a_void, const void *b_void) {
int a = *(int *)a_void;
int b = *(int *)b_void;
return a - b;
}
int compare_Desc(const void *a_void, const void *b_void) {
int a = *(int *)a_void;
int b = *(int *)b_void;
return b - a;
}
int main() {
int i = 0, n, x, p, c, z, w, j = 0, k = 0, cmpst, null;
int prm;
int prime[50], composite[50], input[50];
printf("How many inputs are you be working with?\nNote: 50 Maximum Inputs\n");
scanf("%d", &n);
printf("Enter the numbers.\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &input[i]);;
}
for (i = 0; i < n; i++) {
if (input[i] % 2 != 0) {
prime[p++] = input[i];
prm = p;
} else
if (input[i] >= 2 && input[i] % 2 == 0) {
composite[c++] = input[i];
cmpst = c;
}
}
printf("Prime Numbers:");
qsort(prime, prm, sizeof(int), compare_Asc);
for (i = 0; i < p; i++) {
printf("%d", prime[p]);
}
printf("Composite Numbers:");
qsort(composite, cmpst, sizeof(int), compare_Desc);
for (i = 0; i < c; i++) {
printf("%d", composite[c]);
}
return 0;
}
There are some major issues, in the posted code, worth mentioning.
Variables
Declaring all the variables at the beginning of the scope, instead of just before where they are used, can hide bugs.
Uninitialized variables, are an even worse source of errors, because their values are indeterminated.
int i=0, n, x, p, c, z, w, j=0, k=0, cmpst, null;
// ^ ^ ^^^^ ?
// ... Later, in the code:
prime[p++] = input[i];
// ^^^ What value is incremented?
// Where is [p++]? Is it inside the prime array?
A correct initialization would prevent undefined behavior.
int p = 0, c = 0;
int composite[50], input[50];
for(int i = 0; i < n ; ++i) {
if ( is_prime(input[i]) ) { // <-- More on this, later.
prime[p++] = input[i];
}
else {
composite[c++] = input[i];
}
}
Loops
This happens a couple of times, just because the code itself is duplicated (another code smell):
for(i=0;i<p;i++){
// ^^^^^^^^^^^ We want to iterate over [0, p).
printf("%d",prime[p]);
// ^ But this always prints the element one past the end
}
Even if it's just a simple loop, it could be a good idea to write a (testable and reusable) function
void print_arr(size_t n, int arr[n])
{
for (size_t i = 0; i < n; ++i) {
printf("%d ", arr[i]);
} // ^
putchar('\n');
}
// ... Later, in main:
print_arr(p, prime);
print_arr(c, composite);
Primes or composite
I am successful in identifying prime and composite from an array
Well, no. Not with this code, I'm sorry.
if (input[i]%2 != 0) { // Those are ALL the ODD numbers!
prime[p++]=input[i];
}
else if(input[i]>=2 && input[i]%2==0){ // Those are the EVEN numbers greater than 0
composite[c++]=input[i];
}
// What about 0 and the even numbers less than 0?
Not all the odd numbers are prime number (it's a little more complicated than that) and 2 itself is a prime, not a composite.
It's unclear to me if this is a terminology issue or if the snippet is only a placeholder for a proper algorithm. In any case, there are multiple examples of primality test functions in SE sites (I'm quite confident some are posted almost every day).
Overflow risk
See chux - Reinstate Monica's comment:
return a-b; risks overflow when a, b are large int values.
Consider return (a > b) - (a < b); for a full range solution.
Single letter variables names are to be avoided... except for i, j and k used in for() loops only.
You're not updating the index of the arrays c and p as the numbers are being printed out. The arrays are being sorted fine.
In the code below I also remove redundant variables, and rename n to input_count, c to compo_count and p to prime_count.
#include <stdio.h>
#include <stdlib.h>
int compare_Asc(const void *a_void, const void *b_void)
{
int a = *(int *) a_void;
int b = *(int *) b_void;
return a - b;
}
int compare_Desc(const void *a_void, const void *b_void)
{
int a = *(int *) a_void;
int b = *(int *) b_void;
return b - a;
}
int main ()
{
int i = 0;
int input_count = 0;
int prime_count = 0;
int compo_count = 0;
int prime[50];
int composite[50];
int input[50];
printf("How many inputs are you be working with?\nNote: 50 Maximum Inputs\n");
scanf("%d", &input_count);
printf("Enter the %d numbers.\n", input_count);
for (i = 0; i < input_count; i++)
{
scanf("%d", &input[i]);
}
for (i = 0; i < input_count; i++)
{
if (input[i] % 2 != 0)
{
prime[prime_count] = input[i];
prime_count += 1;
}
else if (input[i] >= 2 && input[i] % 2 == 0)
{
composite[compo_count] = input[i];
compo_count += 1;
}
}
printf("Prime Numbers:");
qsort(prime, prime_count, sizeof(int), compare_Asc);
for (i = 0; i < prime_count; i++)
{
printf("%d ", prime[i]); // <<-- HERE, not [p]
}
printf( "\n" );
printf ("Composite Numbers:");
qsort(composite, compo_count, sizeof(int), compare_Desc);
for (i = 0; i < compo_count; i++)
{
printf("%d", composite[i]); // <<-- HERE, not [c]
}
printf( "\n" );
return 0;
}

How to move one element to the left of a fixed array

int array[10] = {1,2,3,4,5}
from my understanding, the rest of the indexes that haven't been assign a value will be 0. If I want to move every element to the left (I am wanting to remove the first value i.e. index 0). How do I do this without causing duplicate values for the last index with a integer assigned?
For example:
current array
output: 1234500000
+1 to the left:
output: 2345500000
I tried the following code:
void order_array(int size, int array[])
{
for (int i = 0; i < size-1; i++)
{
if (array[i] == 0)
{
array[i-1] = 0;
}
array[i] = array[i+1];
}
}
expected output after method execution:
output: 2345000000
Also before someone says this is a duplicate, I have looked around and no thread explains with fixed arrays, i.e. with 0's as default values.
Appreciate your response.
if (array[i] == 0)
{
array[i-1] = 0;
}
I don't understand why this block is there. It's not possible to get inside the if statement.
With your expected output and given this is an array of ints, I suspect the solution is to only output four values in your print statement, but if the last element of the array should be zero, you can just do this after your for loop:
array[size-1] = 0;
If you don't want rotation then:
int arr[]; //initialize it
int siz=sizeof(arr)/sizeof(arr[0]);
int index=0;
while(index<siz-1)
{
arr[index]=arr[index+1];
index++;
}
arr[index]=0; //0 default value at the end of the array
This will work fine
You just need to manually set the last value to zero at the end. I'd also consider using the built-in memmove function which is designed for moving around data where the source and destination overlap.
void order_array(int size, int array[]){
memmove(array, array+1, (size-1) * sizeof(array[0]));
array[size-1] = 0;
}
#include <stdio.h>
#define ARRAY_SIZE 10
void order_array(int size, int* array) {
for (int i = 0; i < size; i++) {
if (!array[i]) {
continue;
}
if (i + 1 < size)
array[i] = array[i + 1];
}
}
int main() {
int array[ARRAY_SIZE] = {1, 2, 3, 4, 5};
printf("intput: ");
for (int i = 0; i < ARRAY_SIZE; i++) {
printf("%d", array[i]);
}
printf("\n");
order_array(ARRAY_SIZE, array);
printf("output: ");
for (int i = 0; i < ARRAY_SIZE; i++) {
printf("%d", array[i]);
}
printf("\n");
return 0;
}
Maybe you should consider the last value that not equal to default value 0.
Execute in shell:
gcc -o a.out a.c && ./a.out
intput: 1234500000
output: 2345000000

Stuck in a for loop entering values to an array in C language

I am trying to practice with C by making a bubble sort program. The problem until now seems to be that the for loop that is giving values to the cells of the array is stuck after the condition is no longer fulfilled but it doesn't seem to be executing the commands in the loop. I don't know what is happening exactly and I have added some extra lines to see what is happening an these were my conclusions. Here is the code:
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int *sort(int *array)
{
int finish = 1;
while (finish = 1)
{
finish = 0;
for (int i = 0; i <= sizeof(array); i++)
{
if ((array + i) > (array + i + 1))
{
swap(array + i, array + i + 1);
finish = 1;
}
}
}
return array;
}
int main()
{
int s, res;
printf("Give me the size of the array being sorted(larger than 1) : ");
do
{
res = scanf("%d", &s);
if (res != 1)
{
printf("Wrong Input!\n");
exit(1);
}
if (s < 2)
printf("Only numbers equal or larger than 2\n");
} while (s < 2);
int array[s];
for (int i = 0; i < s; i += 1)
{
scanf("%d", array + i);
printf("%d %d %d\n\n", *(array + i), i, i < s); // I used this to check if my values were ok
}
printf("end of reading the array"); //I added this line to see if I would exit the for loop. I am not seeing this message
sort(array);
printf("\n");
for (int i = 0; i < sizeof(array); i++)
printf("%d\n\n", array + i);
printf("Array has been sorted! Have a nice day!\n\n************************************************************");
return 0;
}
See the annotations in the code:
#include <stddef.h> // size_t 1)
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int *sort(int *array, size_t size) // needs an extra parameter to know the size of the array
{
int finish = 1;
while (finish /* = 1 * you don't want assignment, you want comparison: */ == 1)
{
finish = 0;
for (int i = 0; i /* <= sizeof(array) */ < size - 1; i++) // i should be of type size_t
{
// if ((array + i) > (array + i + 1)) you are not dereferencing:
if(array[i] > array[i + 1])
{
// swap(array + i, array + i + 1); // easier to read imho:
swap(&array[i], &array[i + 1]);
finish = 1;
}
}
}
return array; // why does this function return anything? it is never used.
}
int main()
{
int s; /* , res; no need for an extra variable res */
printf("Give me the size of the array being sorted(larger than 1) : ");
do
{
// res = scanf("%d", &s);
// if (res != 1)
if (scanf("%d", &s) != 1)
{
printf("Wrong Input!\n");
// exit(1); // should be EXIT_FAILURE. Use return instead of exit() when in main().
return EXIT_FAILURE;
}
if (s < 2)
printf("Only numbers equal or larger than 2\n");
} while (s < 2);
int array[s];
for (int i = 0; i < s; /* i += 1* idiomatic: */ ++i) // size_t would be the correct type for s and i.
{
scanf("%d", /* array + i use indexes: */ &array[i]);
printf("%d %d %d\n\n", array[i], i, i < s); // again: indexes. i < s is allready ensured by the condition of the for-loop
}
printf("end of reading the array");
// sort(array); // sort will have no idea about the size of array use
sort(array, s); // instead.
printf("\n");
for (int i = 0; i < /* sizeof(array) 2) */ s; i++)
printf("%d\n\n", /* array + i * again you don't dereference */ array[i]);
printf("Array has been sorted! Have a nice day!\n\n************************************************************");
return 0;
}
1) size_t is the type that is guaranteed to be big enough to hold all sizes of objects in memory and indexes into them. The conversion specifier for scanf() is "%zu".
2) sizeof(array) in main() will yield the number of bytes in array, but you want the number of elements so you'd have to use sizeof(array) / sizeof(*array). But thats not needed since you already know its size. It is s.
This line
printf("end of reading the array");
has no line feed at the end of the string. This is a problem because printf is part of the family of functions called "buffered IO". The C library maintains a buffer of the things you want to print and only sends them to the terminal if the buffer gets full or it encounters \n in the stream of characters. You will not see, end of reading the array on your screen until after you have printed a line feed. You only do this after calling sort(). So all you know is your program is getting into an infinite loop at some point before the end of sort.
So there are actually three loops that could be infinite: the for loop you identified, the while loop in sort and the for loop inside the while loop. As the other answers point out, you have made the classic mistake of using assignment in the while conditional
while (finish = 1)
// ^ not enough equals signs
Unless your C compiler is really old, it is probably outputting a warning on that line. You should heed warnings.
Also, you should learn to use a debugger sooner rather than later. Believe me, it will save you a lot of time finding bugs.
In the sort function sizeof(array) returns the size of the pointer. (you can check it by yourself using printf("%d", sizeof(array).
The solution is to change your function to:
int sort(int* array, size_t size) { ... }
and call it with the correct array size:
sort(array, s);

Void function: removing elements from an array?

I want to make a function that removes elements from an array.
I attempted making the function myself, however, not fully successful:
void remove_element(int* array, int number, int array_length)
{
int i, j;
for (i = 0; i < array_length; i++){
if (array[i] == number) {
for (j = i; j < array_length; j++)
array[j] = array[j+1];
array_length--;
}
}
}
first thing I noticed is after function is called in main, array_lenght is not changed, therefore length of an array remains the same after removing element(s).
So the first question is how to change length of an array inside the void function?
Second thing which doesn't work properly is if in an array are two or more same numbers next to each other, for example if array contains 1,1,3,4,5,6 and user wants to remove 1 function will remove only one element.
Example of my output (wrong):
1,1,3,4,5,6 after fucntion 1,3,4,5,6
Thanks
In the current signature you cannot modify the array, as returning the new array you also need to return the new length.
There are many ways to do it, here is a way with a single loop:
void
remove_element(int* array, int number, int *array_length)
{
int i, j;
for (i = 0, j=0; i < *array_length; i++) {
if (array[i] != number)
array[j++] = array[i];
}
*array_length = j;
}
Doing so, this will mutate both the initial array and the variable keeping its length in the caller and you must pass the value of array_length by reference, somthing like
int* some_array, some_array_length, n;
remove_element(some_array, n, &some_array_length)
Other method would be to return the new length and mutate the array or allocate a new array in the heap and return both the allocated array and the new length.
The other answers to your question aside, if you're likely to do more than one removal on average (or more than one per call ever, actually), it's better not to shift all the subsequent values again and again. Try this:
void remove_element(int *array, int number, int *array_length) {
for(int iRead = 0, iWrite = 0; iRead < *array_length; iRead++) {
if(array[iRead] == number)
continue; /* skip without increasing iWrite */
if(iWrite < iRead) /* it works without this line, too, what's better depends */
array[iWrite] = array[iRead];
iWrite++;
}
*array_length = iWrite;
}
How this works, e.g., with array = {1,1,2,2,3} and number = 2:
1 1 2 2 3
^ iRead
^ iWrite
(increases both, writes nothing)
1 1 2 2 3
^ iRead
^ iWrite
(increases both, writes nothing)
1 1 2 2 3
^ iRead
^ iWrite
(continue happens: increases only iRead)
1 1 2 2 3
^ iRead
^ iWrite
(continue happens: increases only iRead)
1 1 2 2 3
^ iRead
^ iWrite
(writes 3 to iWrite, increases both)
1 1 3 2 3
^ iRead = 5
^ iWrite = 3
(iRead is no longer < *array_length, loop stops, 3 == iWrite is the new length)
Based now on your Comments, I'll do it like this:
#include <stdio.h>
void remove_element(int number, int *arr, size_t *size);
int main(void){
int arr[] = {1,1,3,4,5,6};
long unsigned int arrSize;
int number = 1;
arrSize = sizeof arr / sizeof arr[0];
printf("Before:\n");
for ( size_t i = 0 ; i < arrSize ; i++ ){
printf("%d ", arr[i]);
}
printf("\nAfter:\n");
remove_element( number, arr, &arrSize );
for ( size_t j = 0 ; j < arrSize ; j++ ){
printf("%d ", arr[j]);
}
printf("\n");
}
void remove_element(int number, int *arr, size_t *size){
int arrTemp[*size];
long unsigned int j = 0,c;
for ( size_t i = 0 ; i < *size ; i++ ){
if ( arr[i] == number ){
continue;
}else{
arrTemp[j] = arr[i];
j++;
}
}
for ( size_t k = 0 ; k < j ; k++ ){
arr[k] = arrTemp[k];
}
c = j;
while ( *size > c ){
arr[c] = 0;
c++;
}
*size = j;
}
Output:
Before:
1 1 3 4 5 6
After:
3 4 5 6
By the way in your Question you said:
Examples of output:
1,1,3,4,5,6 after fucntion 1,3,4,5,6
And in your Comment you said:
It doesn't matter how many same numbers there are, in that case above if user wants to remove 1, all 1 's should be removed.
Please make up your mind.
Because array_length is not passed as pointer you're having copy of it on stack, so after you're getting outside of this function you're still having old value. You could use here memmove or memcpy instead of iteration over whole array after you find the same number. The reason why you didn't delete the next 1 in your array is, because when you're on i = 0 -> array[0] == 1, but when you move all of the numbers back then you move second 1 to array[0], without checking it afterwards because after you finished iteration you just increment i, without checking if what you moved to current value of array[i] is the same as previous one.
void remove_element(int *array, int number, int *array_length){
int sameValues = 0;
for(int i = 0; i < *array_length; i++){
while(array[i] == number){
*array_length--;
sameValues++;
}
if(sameValues > 0){
if(i < *array_length){
memmove(&array[i], &array[i + sameValues], (*array_length - i) * sizeof(int));
}
sameValues = 0;
}
}
}
To make it even more dynamic you could use realloc (and actually resize the space occupied by your array after you remove members, but then either you need to return new pointer or you need to point to pointer on your stack from where you call the function:
void remove_element(int **array, int number, int *array_length){
int sameValues = 0;
for(int i = 0; i < *array_length; i++){
while((*array)[i] == number){
*array_length--;
sameValues++;
}
if(sameValues > 0){
if(i < *array_length){
memmove(&(*array)[i], &(*array)[i + sameValues], (*array_length - i) * sizeof(int));
}
realloc(*array, *array_length);
sameValues = 0;
}
}
}
P.S. To use memmove you need to include string.h
When you declare an array the compiler will affect an amount of memory, and with array structure you can't change it. There is 2 solutions, change your array length but you still could access to the last "box" or redefine an array with the size wanted.
1st case :
void remove_element(int* array, int number, int * array_length){
int i = 0,j = 0;
while( i < *(array_length)-1){
if(array[i] == number && !find){
i++; //we step over
find = 1; //we find 1 element stop remove
}
array[j] = array[i];
i++;
j++;
}
*(array_length)--;
}
The int * array_length is a pointer to the memory, so your changes are keep when you go back in main. In your example, before remove_element array_length is equal to 6, and after it's 5. But you still could do array[5] (6th element cause notation 0 to 5 in c).
2nd case
int * remove_element(int * array, int number, int * array_length){
int * new_array = malloc((array_length -1) * sizeof(int)); // len - 1 cause we want to delet only 1 element
int i = 0;
int j = i;
int find = 0;
while( i < *(array_length)-1){
if(array[i] == number && !find){
i++; //we step over
find = 1; //we find 1 element stop remove
}
new_array[j] = array[i];
i++;
j++;
}
if (array[array_length] != number && !find){ //if we didn't find att all the element return array
return array;
} else {
*(array_length)--;
return new_array;
}
}
Here you have to return the new_array because int array[6] in your main is a constant : you can't change it with array = new_array.
Edit : yes of course when you don't need anymore your array you have to free it with free(array) (or it's automatically done at the end of the processus, but it's not proper code)
There is also a shorter method with addtion of pointers but it seems quite too complicated with your c lvl :)

How do I fill the contents of a 2-dimensional array, whose dimensions are input by the user, with the contents of another 2-dimensional array?

In the following homework assignment:
Create an array of 100 random numbers in the range of 1…999, write a function for each of the following processes. In building the array, if 3 or 7 evenly divide the random number, store it as a negative number.
a. Print the array ten values to a line. Make sure that the values are aligned in rows.
b. Return a count of the number of even values
c. Return the sum of all values in the array
Create a two dimensional array (size 10 X 10). Fill this two dimensional array with the values from the above single dimensional array. Determine the maximum value in each row. Display the two-dimensional array and the maximum of each row.
3. Repeat number 2 above but this time instead of 10 X 10 array, prompt the user for the size of the row and column, allow user to fill in the values and display the array.(Hint: Use pointers and dynamic memory allocation )
I'm stuck on number 3. I'm not sure how to correctly use the dynamic memory allocation and pointers to make room for the number of rows and columns the user inputs.
int main(void)
{
int hundred[100];
cien(hundred);
even(hundred);
total(hundred);
two_dim(hundred, table);
hi_row(table);
cust_arr(hundred,table);
system("pause");
return 0;
}
void cien(int hundred[])
{
int i = 0;
int range = (999 - 1) + 1;
for (i = 0; i < 100; i++)
{
hundred[i] = rand() % range + 1;
if (hundred[i] % 3 == 0 || hundred[i] % 7 == 0)
{
hundred[i] = hundred[i] * -1;
printf("%d\t", hundred[i]);
}
else
{
printf("%d\t", hundred[i]);
}
}
return;
}
int two_dim(int hundred[], int arr[][10])
{
int x;
int y;
int i = 0;
int table[10][10];
while (i != 100)
{
for (x = 0; x <10; x++)
{
for (y = 0; y < 10; y++)
{
arr[x][y] = hundred[i];
printf("%d\t", arr[x][y]);
i++;
}
}
}
return **table;
}
void** cust_arr(int hundred[], int table[][10])
{
int x, y, i, j, k=0;
int **arr;
printf("input the number of rows.\n" );
scanf_s("%d", &x);
i = (int*)calloc(x, sizeof(int*));
printf("input the number of columns.\n");
scanf_s("%d", &y);
j = (int*)calloc(y, sizeof(int*));
while (k != 100)
{
for (i = 0; i <= x; i++)
{
for (j = 0; j <= y; j++)
{
hundred[k] = table[10][10];
table[10][10] = **arr[i][j];
}
}
printf("%d\n", **arr[i][j]);
k++;
}
}
Since the prompt says to repeat number 2, I have tried to make similar loops in my cust_arr() function
malloc will return a pointer the the memory region allocated. You can use brackets on pointers to specify an index just like static arrays. Since you need a 2d array, you need a pointer pointing to an array of pointers i.e. the columns point to the rows, the rows point to the values.
int ** dynamicPointer = malloc(sizeof(int*)*columns);
for(int i = 0; i < columns; i++)
dynamicPointer[i] = malloc(sizeof(int)*rows);
//address of final column and row
dynamicPointer[columns- 1][rows - 1] = 3;
print("%d\n", dynamicPointer[columns- 1][rows - 1]);
For 10x10 array I would suggest using variable length arrays. If you want to use dynamic allocation then use malloc function.
int x, y;
int **table;
scanf("%d %d", &x, &y);
table = malloc(x*sizeof(int *));
for(int i = 0; i < x; i++)
table[i] = malloc(y*sizeof(int));
Beside this, the code shown has many flaws and need to be fixed. Better to put all the function declaration and definition outside the function with specifying their return type and parameters.

Resources