Unwanted array update when updating a variable in C - c

I'm trying to convert an int to char with sprintf.
for(int i=0; i<n; i++){
char buffer[100];
load = group[i];
int num = pow(10, (load-1));
for(int j=(load-2); j>=0; j--){
num+=pow(10, j);
}
sprintf(buffer,"%d",num);
(...)
When I print buffer, everything seems alright, as I just want it to be a string there.
Then, I want to store it inside an array. Specifically here:
typedef struct Unario {
char * bits ;
} Unario ;
But when trying to store buffer inside the next index of the array, all the rest of the variables saved before, update to the new buffer definition.
Here's the full function:
Unario * comprimir_en_unario ( int n, int * grupo ){
int load;
int j = 0;
int SIZE = n*2;
Unario * comprimiendo = malloc(SIZE * sizeof(comprimiendo));
for(int i=0; i<n; i++){
char buffer[100];
load = grupo[i];
printf("\ngrupo[%d] = %d\n", i, load);
int num = pow(10, (load-1));
for(int j=(load-2); j>=0; j--){
num+=pow(10, j);
}
sprintf(buffer,"%d",num);
comprimiendo[j].bits = buffer;
j++;
comprimiendo[j].bits = "0";
j++;
}
for(int i=0; i<SIZE; i++){
printf("in %d = %s\n", i, comprimiendo[i].bits);
}
return comprimiendo;
};
With the following input:
int m[6] = {8,2,8,8,2,3};
and following unwanted output:
in 0 = 111
in 1 = 0
in 2 = 111
in 3 = 0
in 4 = 111
in 5 = 0
in 6 = 111
in 7 = 0
in 8 = 111
in 9 = 0
in 10 = 111
in 11 = 0
and the one I'm trying to get:
in 0 = 11111111
in 1 = 0
in 2 = 11
in 3 = 0
in 4 = 11111111
in 5 = 0
in 6 = 11111111
in 7 = 0
in 8 = 11
in 9 = 0
in 10 = 111
in 11 = 0
Side note: I can't change the struct nor delete it because its a part of a group of structs.

Because your the bits in your struct can not store values, it is only a pointer
So you have to make sure each time you have stored your stirng somewhere
In your used function, each time you use sprintf, the stored value in buffer will be refreshed
In that case, your final output must be the lastest value of buffer
It means, if you changed the array from { 8,2,8,8,2,3 } to { 8,2,8,8,2,4 }, the final output will be all in 1111(the lastest value of buffer)
Here is one way to save it, I used 2d array to store the string
Unario * comprimir_en_unario(int n, int * grupo)
{
int load;
int j = 0;
int SIZE = n * 2;
Unario * comprimiendo = (Unario *)malloc(SIZE * sizeof(Unario));//No need to change.
char buffer[100][100];//Use 2d array to store the string each time
for (int i = 0; i < n; i++)
{
load = grupo[i];
printf("grupo[%d] = %d\n", i, load);
int num = pow(10, (load - 1));
for (int j = (load - 2); j >= 0; j--)
{
num += pow(10, j);
}
sprintf(&buffer[i][0], "%d", num);//Related changes
comprimiendo[j].bits = &buffer[i][0];//Related changes
j++;
comprimiendo[j].bits = "0";
j++;
}
for (int i = 0; i < SIZE; i++)
{
printf("in %d = %s\n", i, comprimiendo[i].bits);
}
return comprimiendo;
}
You may find more solutions after you noticed the problem of your origional function

Related

Printing array as sub blocks

I have array and I am trying to print this array as sub blocks, where each block has size = 5.
the out put of this code not as I expected it just print the first 5 values. How to print the array as sub blocks?
int arr[298] = {some int values};
int in = 0;
int siz = 298;
int ii;
int rang = 5;
for (int i = 0; i < siz; i++) {
if (in <= siz) {
for (ii = in; ii < 5; ii++) {
printf("arr=%d \n", arr[ii]);
}
printf("------------\n");
}
ind = ind + rang;
}
Following your request for clarification in the comment section, there are a few problems with your code, for me the biggest one is that it's needlessly complicated, but the one you are looking for is in this line:
ind = ind + rang;
ind is is not declared in your code but I assume you mean in, the first time the inner loop runs in(ind) is 0 so it all goes well, after that in will be 5, you assign it to ii and the condition ii < 5 will never be true again, the body of the loop will never be executed.
I suppose you could fix it by using in as index for the array and scrap rang since it isn't needed, something like this:
int arr[298] = {some int values};
int in = 0;
int siz = 298;
for (int i = 0; i < siz; i++) {
//if (in < siz) { moving this into the for loop
for (int ii = 0; ii < 5 && in < siz; ii++, in++) {
printf("arr=%d \n", arr[in]);
}
printf("------------\n");
//}
}
Live demo: https://godbolt.org/z/YzG9sno1n
But you don't need a nested loop, there are a few ways you can do this, a simple one is to have a variable that controls the block size:
int arr[298] = {some int values};
int siz = 298;
int count = 5;
for (int i = 0; i < siz; i++) {
printf("arr=%d \n", arr[i]);
count--;
if (count == 0) {
printf("------------\n");
count = 5;
}
}
Live demo: https://godbolt.org/z/b4e8vWfhM
In the above code count serves as the control variable, the value in the index is printed 5 times and when it reaches 0 a separator is printed and it resets and starts the new block.
Another possible option is to use the index itself to separate the blocks, you know the remainder of a division is 0 when the numerator is divisible by the denominator, you can use that to your advantage:
int arr[298] = {some int values};
int siz = 298;
for (int i = 0; i < siz; i++) {
if (i % 5 == 0) { // && i != 0 if you want to skip the initial separator
printf("------------\n");
}
printf("arr=%d \n", arr[i]);
}
Live demo : https://godbolt.org/z/nne3z38rY
Finally you can/should use a constant value for size:
#include <stdio.h>
#define SIZE 298
int main() {
int arr[SIZE] = {some int values};
for (int i = 0; i < SIZE; i++) {
if (i % 5 == 0 && i != 0) { // skipping the initial separator
printf("------------\n");
}
printf("arr=%d \n", arr[i]);
}
}
Live demo: https://godbolt.org/z/Mc4Yh4cav
Instead of several for loops, you can use a single while loop.
int arr[298 ]={Some int Values};
int ind =0;
int siz= 298 ;
printf("------------\n");
while(ind<=siz-1){
printf("arr=%d \n",arr[ind]);
ind++;
if(ind%5==0){
printf("------------\n");
}
}
In this, you print the elements through 0 to 297, with a line of dashes printed if the index is divisible by 5, that is after every fifth element.

variable in for loop has different values in the same loop (C language)

In these loops i has two different values and I don't know why it's that, as I'm not increasing it's size. I'm printing i in both loops, but it has a greater value when printed inside the inner loop and the value it should have in the extern one.
Edit: the description erased, I rewrote it with only relevant information.
Can you tell me why this happens?
int position = 0;
int size = 4;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < position; j++)
{
printf(" i = %d\n", i);
}
position++;
printf("i = %d\n", i);
}
printf("\n");
This is what it prints:
i = 0
i = 1
i = 1
i = 2
i = 2
i = 2
i = 3
i = 3
i = 3
i = 3
While the desired output should be:
i = 0
i = 1
i = 1
i = 2
i = 2
i = 2
i = 3
i = 3
i = 3
i = 3
To get code in a loop executed atleast once, you could use a do-while-loop. I went ahead and changed it for you. Additionally, printing an unindented i before the loop gets you to your desired output.
int position = 0;
int size = 4;
for (int i = 0; i < size; i++)
{
printf("i = %d\n", i);
int j = 0;
do {
printf(" i = %d\n", i);
j++;
} while (j < position);
position++;
}
printf("\n");
Edit: Ah, I see, you have changed your desired output yet again! This makes the condition of executing the code atleast nolonger necessary. A regular while-loop does the trick:
int position = 0;
int size = 4;
for (int i = 0; i < size; i++)
{
printf("i = %d\n", i);
int j = 0;
while (j < position) {
printf(" i = %d\n", i);
j++;
}
position++;
}
printf("\n");
It's because you've created an odd variable loop condition with position. First lap in the i for loop, it skips the inner loop, then increases position by 1 and prints i = 0. Then next lap when i is 1, it executes the inner loop, and so on.
This would be why it is a bad idea to use an ever-changing condition in for loops - it makes the code much harder to understand.
Just place the output of the variable i before the inner loop.
#include <stdio.h>
int main(void)
{
int position = 0;
int size = 4;
for (int i = 0; i < size; i++)
{
printf("i = %d\n", i);
for (int j = 0; j < position; j++)
{
printf(" i = %d\n", i);
}
position++;
}
printf("\n");
return 0;
}
The program output is
i = 0
i = 1
i = 1
i = 2
i = 2
i = 2
i = 3
i = 3
i = 3
i = 3

How can I make a new array, by counting the no.of appearances of value and printing it next to that value?

I should make new array out of existing one (ex. 1 0 4 5 4 3 1) so that the new one contains digits already in existing array and the number of their appearances.
So, the new one would look like this: 1 2 0 1 4 2 5 1 3 1 (1 appears 2 times, 0 appears 1 time.... 3 appears 1 time; the order in which they appear in first array should be kept in new one also); I know how to count no. of times a value appears in an array, but how do I insert the no.of appearances? (C language)
#include <stdio.h>
#define max 100
int main() {
int b, n, s, i, a[max], j, k;
printf("Enter the number of array elements:\n");
scanf("%d", &n);
if ((n > max) || (n <= 0)) exit();
printf("Enter the array:\n");
for (i = 0; i < n; i++)
scanf("%d", a[i]);
for (i = 0; i < n; i++) {
for (j = i + 1; j < n;) {
if (a[j] == a[i]) {
for (k = j; k < n; k++) {
a[k] = a[k + 1];
}}}}
//in the last 5 rows i've tried to compare elements, and if they are same, to increment the counter, and I've stopped here since I realised I don't know how to do that for every digit/integer that appears in array//
If you know that the existing array consists of digits between 0 and 9, then you can use the index of the array to indicate the value that you are incrementing.
int in[12] = {1,5,2,5,6,5,3,2,1,5,6,3};
int out[10] = {0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 12; ++i)
{
++out[ in[i] ];
}
If you provide any code snippet, its easy for the community to help you.
Try this, even you optimize the no.of loops :)
#include <stdio.h>
void func(int in[], int in_length, int *out[], int *out_length) {
int temp[10] = {0}, i = 0, j = 0, value;
//scan the input
for(i=0; i< in_length; ++i) {
value = in[i];
if(value >= 0 && value <= 9) { //hope all the values are single digits
temp[value]++;
}
}
// Find no.of unique digits
int unique_digits = 0;
for(i = 0; i < 10; ++i) {
if(temp[i] > 0)
unique_digits++;
}
// Allocate memory for output
*out_length = 2 * unique_digits ;
printf("digits: %d out_length: %d \n",unique_digits, *out_length );
*out = malloc(2 * unique_digits * sizeof(int));
//Fill the output
for(i = 0, j = 0; i<in_length && j < *out_length; ++i) {
//printf("\n i:%d, j:%d val:%d cout:%d ", i, j, in[i], temp[in[i]] );
if(temp[in[i]] > 0 ) {
(*out)[j] = in[i];
(*out)[j+1] = temp[in[i]];
temp[in[i]] = 0; //Reset the occurrences of this digit, as we already pushed this digit into output
j += 2;
}
}
}
int main(void) {
int input[100] = {1, 0, 4, 5, 4, 3, 1};
int *output = NULL, output_length = 0, i = 0;
func(input, 7, &output, &output_length );
for(i=0; i < output_length; i+=2) {
printf("\n %d : %d ", output[i], output[i+1]);
}
return 0;
}

Unexpected output at a particular row for a dynamic 2D array

I was solving a programing question for displaying Pascal triangle. In the code, I have set the last element of every row equal to zero. Still, the 6th row produces the output as 50 for the last element. I'm unable to figure out the reason for this. Kindly help. The code is attached.
int ** generate(int A, int *number_of_rows) {
*number_of_rows = A;
int i,j,nc=0;
int **result = (int**)malloc(A * sizeof(int *));
for(i=0;i<A;i++)
{
nc=i+1;
result[i]=(int)malloc(nc*sizeof(int));
result[i][0]=nc;
result[i][1] = 1;
for(j=2;j<nc;j++)
{
result[i][j]=result[i-1][j]+result[i-1][j-1];
}
}
return result;
}
Edit:
The first element of every row displays the number of columns in that row.
#include <stdio.h>
#include <stdlib.h>
int ** generate(int A, int *number_of_cols) {
int **result = malloc(A * sizeof(int *));
int nc;//number of columns
for(int i = 0; i < A; ++i){
number_of_cols[i] = nc = i + 1;
result[i] = malloc(nc * sizeof(int));
result[i][0] = result[i][nc-1] = 1;
if(i > 1)
for(int j = 1; j < nc -1; ++j){
result[i][j] = result[i-1][j-1] + result[i-1][j];
}
}
return result;
}
int main(void){
int n;
scanf("%d", &n);
int *number_of_cols = malloc(n * sizeof(int));
int **pascal_triangle = generate(n, number_of_cols);
for(int i = 0; i < n; ++i){
printf("%*s", 2 * (n-i-1), "");
for(int j = 0; j < number_of_cols[i]; ++j){
printf("%4d", pascal_triangle[i][j]);
}
puts("");
free(pascal_triangle[i]);
}
free(pascal_triangle);
free(number_of_cols);
return 0;
}
I can't understand the purpose of passing the *number_of_row just to assign it the other parameter address. However, I'd split your main for loop in 2:
one to allocate all memory and another to fill it.
for(i=0;i<A;i++)
result[i]=(int)malloc((i+1)*sizeof(int));
result[0][0]=1; //in your code, result[i-1] was accessed with i=0
for(i=1;i<A;i++) {
result[i][0] = i+1;
result[i][1] = 1;
for(j=2;j<i;j++)
result[i][j] = result[i-1][j] + result[i-1][j-1]; //when j reaches the last value,
//[i-1][j] won't work! So put j<i instead.
result[i][j] = 1;
}
The rest of code was OK, check if this is what you wanted. The resulting triangle shoud be:
1
2 1
3 1 1
4 1 2 1
5 1 3 3 1
6 1 4 6 4 1 etc.

Why are my array elements getting overridden?

I stared at this code for at least 4 hours.
I'm not sure what I'm doing wrong.
I'm updating the array hand[5][2] with a simple for loop.
The values stored in hand[0][2], hand[0][3] and hand[0][4] keep getting overwritten.
I used the debugger to go slowly through every single line but I still don't
understand why I'm getting different values.
This is the output I'm getting
hand[0][0] = 0
hand[0][1] = 1
hand[0][2] = 2
hand[0][3] = 3
hand[0][4] = 4
hand[1][0] = 0
hand[1][1] = 1
hand[1][2] = 2
hand[1][3] = 3
hand[1][4] = 4
0 1 0 1 2 // WHY ARE hand[0][2],hand[0][3],hand[0][4] not the same????
0 1 2 3 4
Code:
int main() {
//tests();
int hand[5][2];
int a[5], b[5];
char line[100];
int player = 0;
int card = 0;
for (int i = 0; i < 10; i++) {
hand[player][card] = card;
printf("hand[%d][%d] = %d\n", player, card, hand[player][card]);
card++;
if (card == 5) { player++; card = 0; }
}
// print first hand
for (int j = 0; j < 5; j++) {
printf("%d ", hand[0][j]);
}
printf("\n");
// print second hand
for (int j = 0; j < 5; j++) {
printf("%d ", hand[1][j]);
}
printf("\n");
return 0;
}
int hand[5][2]; should be int hand[2][5];

Resources