Reputation: 1529
I am trying to copy contents of a larger array to two smaller arrays of an unequal size each (of which size may change according to the program). I have four arrays at the simplified code below:
#define size 20
double bigArray[size]={14.553,13.653,9.555,8.564..and so on...9.324,11.123};
/*IndicatorArray is associated to bigArray as follows:
if bigArray[i]<10 then indicatorArray[i]=10 else =20 */
int indicatorArray[size]={20,20,10,10,..and so on..};
double array10[count10], array20[count20]; /*count10 and count20 are
counters from indicatorArray passed as a size of each array
in earlier function not shown here*/
for (i=0;i<size;i++){
if (indicatorArray[i]==10) {
arr10[i]=bigArray[i];
// printf("%lf ",arr10[i]); /*this shows me correct results*/
}
else {
arr20[i]=bigArray[i];
}
}
for (i=0;i<count10;i++){
printf("%lf ",arr10[i]);
}
printf("\n \n");
for (i=0;i<count20;i++){
printf("%lf ",arr20[i]);
}
The result is something like
00.0000 00.0000 9.555 8.564 11.123 14.666 ....
14.553 13.653 00.000......00.000
but I don't want zeros to appear or have such disrupted results but something like
9.55 8.564 ...... 7.123 and 14.533 13.653 .....11.123
Why does this happen and how to do it in the right way?
Upvotes: 1
Views: 154
Reputation: 23218
As mentioned in comments, when splitting the contents of an array, recognize each element is located in a specific addressable place in memory, making this a perfect job for memcpy(). Here is a simple illustration using that concept:
int main(void)
{
double source[] = {3.4,5.6,2.3,4.5,6.7,8.9,10.1,11.1,12.3,4.5};
double split1[3];
double split2[7];
memcpy(split1, &source[0], 3*sizeof(double));
memcpy(split2, &source[3], 7*sizeof(double));
return 0;
}
If your project has well defined and static parameters that are known at runtime, then using a few common macros, and some additional variables, this could be made a little more general.
The following example does essentially the same as the illustration above, but in a loop, potentially a more adaptable construct.
#define SPLIT_CNT 3
int main(void)
{
double source[] = {3.4,5.6,2.3,4.5,6.7,8.9,10.1,11.1,12.3,4.5,8.5,9.5};
double split1[3]; // arrays if differing sizes
double split2[7];
double split3[2];
size_t start_pos; //position accumulator
size_t cpy_len[SPLIT_CNT] = {3,7,2}; //known array sections
double *split[] = {split1,split2,split3}; //enables looping on arrays of differing sizes
start_pos = 0;
for(int i=0;i<SPLIT_CNT;i++)
{
if(i > 0)start_pos += cpy_len[i-1]; //move the start postition
memcpy(split[i], &source[start_pos], sizeof(double)*cpy_len[i]);
}
return 0;
}
Upvotes: 3
Reputation: 368
As someprogrammerdude commented, you should look into using memcpy when copying data. If you still want to use your implementation instead, the problem lies with how you use i
in the for loop. Remember that in this instance, i
will be the position in the big array that the number you want to copy appears. If you want the first element you copy from the big array to be in position 0 of one of the smaller arrays, there's no way that will happen for both if you use arr10[i]
and arr20[i]
. Instead you can use a counter for each smaller array and increment each time an element goes into it. Here's a quick example I did with an online compiler after hard coding some values:
int arr10Count = 0;
int arr20Count = 0;
int i;
for (i=0;i<size;i++){
if (indicatorArray[i]==10) {
arr10[arr10Count]=bigArray[i];
arr10Count++;
// printf("%lf ",arr10[i]); /*this shows me correct results*/
}
else {
arr20[arr20Count]=bigArray[i];
arr20Count++;
}
}
Upvotes: 1
Reputation: 9855
Use separate counters for the index in array10
and array20
.
#define size 20
double bigArray[size]={14.553,13.653,9.555,8.564..and so on...9.324,11.123};
/*IndicatorArray is associated to bigArray as follows:
if bigArray[i]<10 then indicatorArray[i]=10 else =20 */
int indicatorArray[size]={20,20,10,10,..and so on..};
double array10[count10], array20[count20]; /*count10 and count20 are
counters from indicatorArray passed as a size of each array
in earlier function not shown here*/
size_t i10; /* index for array10 *** */
size_t i20; /* index for array20 *** */
for (i=0, i10=0, i20=0; i<size; i++){
if (indicatorArray[i]==10) {
if(i10 < count10) { /* prevent array index out of range *** */
arr10[i10++]=bigArray[i];
}
}
else {
if(i20 < count20) { /* prevent array index out of range *** */
arr20[i20++]=bigArray[i];
}
}
}
for (i=0;i<count10;i++){
printf("%lf ",arr10[i]);
}
printf("\n \n");
for (i=0;i<count20;i++){
printf("%lf ",arr20[i]);
}
Upvotes: 0