sally2000
sally2000

Reputation: 828

How can I copy individual chars from a char** into another char**?

I'm trying to write a program to break down words into segments/syllables if they are entered in a specific format. I want to enter a word in the format:

[d-i-s][c-o-#][v-er-#]

and store it in the format:

syllable[0]=dis
syllable[1]=co
syllable[2]=ver

So far I have managed to break it into syllables using the delimiter ']' and save it as a char** in the format below:

syllable[0]=[d-i-s
syllable[1]=[c-o-#
syllable[2]=[v-er-#

So now I just want to clean it up and strip out the unnecessary characters! I thought I would make a new array and copy over the letters from the old array so long as they aren't [ - #. But for the life of me I cannot work out how to copy the right letters into another array!!

I know that I cant just do:

cleanArray[i][j] = dirtyArray[i][k] 

Because cleanArray[i] is a char* and I can't edit it right? but what can I do?

I've read a lot of similar questions which have suggested strncpy and snprintf (how to copy char array to another char array in C?, strcpy and printf a multidimensional char array C) but I've tried those and I can't make them work. I've even tried putting cleanArray into 3 dimensions in the hope that I would then be able to save the individual letters into cleanArray[i][j] as char*s, which is probably completely wrong.

What is the right way of going about this? Sorry if it's obvious but I've spent hours on it and am now very, very, confused.. I would really appreciate any advice you can give!

Here's my code:

char** cleanStrings (char**dirtyList, int arrayLength)
{
    int i, j, k;
    char** cleanList = (char**)calloc(arrayLength, CHARLEN);

    for (i=0; i<arrayLength; i++)
    {
        k= 0;
        cleanList[i] = (char*)calloc(10,CHARLEN);

        for (j=0; j<strlen(dirtyList[i]+1);j++)
        {

            if (dirtyList[i][j] == '[') continue;
            else if (dirtyList[i][j] == '#') continue;
            else if (dirtyList[i][j] == '-') continue;
            else 
                //i know this is wrong, but what is the right way of doing it?
                cleanList[i][k] = dirtyList[i][j];

                k++;    
        }
    }   
    return cleanList;
}

EDIT

Thanks for all your comments, I've now got it working! Contrary to what I thought, as Barmar points out there is nothing wrong with:

cleanArray[i][j] = dirtyArray[i][k]

My code didn't work because I made a lot of other mistakes like: -casting the return values of calloc -not allocating the memory properly for calloc -incorrect brackets

I also had the code in a header file which I think contained problems of its own.

Upvotes: 0

Views: 192

Answers (2)

simo-r
simo-r

Reputation: 733

Assuming that you are using calloc size parameter wrong. One of these char** cleanList = (char**)calloc(arrayLength, CHARLEN); or cleanList[i] = (char*)calloc(10,CHARLEN); is wrong. You also should not cast the return value of a malloc() / calloc(). For legibility and code flow purposes I also replaced ifs statements. You also wrote for (j=0; j<strlen(dirtyList[i]+1);j++) instead of for (j=0; j<strlen(dirtyList[i])+1;j++) because strlen() calculates the length of the string without \0.Here is the code with few changes.

char** cleanStrings (char**dirtyList, int arrayLength)
{
    int i, j, k;
    char **cleanList = calloc(arrayLength,sizeof * cleanList);

    for (i=0; i<arrayLength; i++)
    {
        k= 0;
        cleanList[i] = calloc(10,sizeof * cleanList[i]);

        for (j=0; j<strlen(dirtyList[i])+1;j++)
        {

            if ((dirtyList[i][j] != '[') && (dirtyList[i][j] != '#') && (dirtyList[i][j] != '-') ){
                cleanList[i][k] = dirtyList[i][j];
                k++;
            }

        }
    }   
    return cleanList;
}

Upvotes: 3

Barmar
Barmar

Reputation: 780889

You're not allocating enough memory for cleanList. I assume CHARLEN is sizeof(char), which is 1 byte. But the elements of cleanList are char*, which is either 4 or 8 bytes, the allocation is much too small. It should be:

char **cleanList = calloc(arrayLength, sizeof(char *));

The general rule when using malloc or calloc is that the multiplier is always sizeof (T), where T is the destination type with one less *. So if you're assigning to char **, it's sizeof(char *).

Upvotes: 2

Related Questions