Alessandro Aguilar
Alessandro Aguilar

Reputation: 401

Slice variable length char array

I have a variable string, that I need to slice into smaller strings, the main string should be treated as a bidimensional array with a certain width and height MxM, and the smaller strings should be cut in blocks of NxN size. So for example, if I have the following string, char source[17] = "ABCDEFGHIJKLMNS0" and his bidimensional size is 4x4, and the size of the smaller blocks are 2x2, the smaller blocks should be ABEF, CDGH, IJMN, KLSO.

In other words, the string should be seeing as

ABCD
EFGH
IJKL
MNSO

and NxN should be cut from it, like:

AB
EF

Always with the constraint that these blocks should be linear arrays as the main string.

I have tried with 3 nested for, with the following code, but I didn't know how to calc the index of the main array in order to cut the blocks that way

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


int main()
{
    char pixelsSource[17] = "ABCDEFGHIJKLMNS0";
    char pixelsTarget[4][5];

    int Y = 0;
    int X = 0;
    for (int block = 0; block < 4; block++)
    {
        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                pixelsTarget[block][(i * 2) + j] = pixelsSource[(i * 2) + j];
                printf("[%d][%d] = [%d] \n", block, (i * 2) + j, (i * 2));
            }
        }
    }

    for (int block = 0; block < 4; block++)
    {
        printf("%s\n", pixelsTarget[block]);
    }
}
 

Upvotes: 1

Views: 246

Answers (1)

Carl Norum
Carl Norum

Reputation: 225242

I broke this down into a more piece-by-piece way and generalized it for M & N. Here's the code, with inline comments:

#include <stdio.h>

#define M 4
#define N 2

int main(void)
{
    // source data is an M * M string(plus null terminator)
    char pixelsSource[M * M + 1] = "ABCDEFGHIJKLMNSO";

    // destination is an array of N*N strings; there are M*M/N*N of them
    char pixelsTarget[(M*M)/(N*N)][N*N + 1];

    // iterate over the source array; blockX and blockY are the coordinate of the top-left corner
    // of the sub-block to be extracted
    for (int blockX = 0; blockX < M; blockX += N)
    {
        for (int blockY = 0; blockY < M; blockY += N)
        {
            int dstWord = blockX/N + blockY;

            // for each letter in the sub-block, copy that letter over to the destination array
            for (int y = 0; y < N; y++)
            {
                for (int x = 0; x < N; x++)
                {
                    int dstIndex = y*N + x;
                    int srcIndex = (blockY + y)*M + blockX + x;
                    printf("[%d][%d] = [%d]\n", dstWord, dstIndex, srcIndex);
                    pixelsTarget[dstWord][dstIndex] = pixelsSource[srcIndex];
                }
            }

            // null-terminate destination word
            pixelsTarget[dstWord][N*N] = '\0';
        }
    }

    // output
    for (int block = 0; block < (M * M) / (N * N); block++)
    {
        printf("%s\n", pixelsTarget[block]);
    }
}

Upvotes: 2

Related Questions