Vertus
Vertus

Reputation: 112

Copying a char** into another char** (C)

I have a

char **content;

that contains lines of text, and in order to change some lines I create a

char **temp;

and copy (with strncpy) whatever I need from content to temp. so when it's ok I have a char **content that has the old content, and a char **temp that has the new content and I want to replace my char **content by temp.

I tried a naive content=temp; without results of course...

I tried to free each element of my char **content and then content=temp; but nothing changed, and I can't free content itself.

I tried

void swappointers(char ***content,char ***temp){
    char **t = *content;
    *content = *temp;
    *temp = t;
}
swappointers(&content,&temp);

without success.

How to swap them?

EDIT: Minimal code:

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

#define MAXLINES 7
#define MAXLENGTH 255


void print(char **content){
    int countline=0;
    while(content[countline]!=NULL){
        printf("%s\n",content[countline]);  
        countline++;
    }
}

void swappointers(char ***content,char ***tempcontent){
    char **temp = *content;
    *content = *tempcontent;
    *tempcontent = temp;
}

void addline(char **content,char *texttoadd,int linetoinsert){
    char **tempcontent=(char**)malloc(sizeof(char*)*MAXLINES);

    int countline=0;
    int contentline=0;
    while(content[contentline]!=NULL){
        if(countline==linetoinsert){
            //add our text
            tempcontent[countline] = malloc(MAXLENGTH);
            strncpy(tempcontent[countline],texttoadd,MAXLENGTH);

            //add \0 (string end character)
            int linelength=strlen(tempcontent[countline])-1;
            for (int countchar=linelength;countchar>=0;countchar--){
                if(tempcontent[countline][countchar]=='\r'||tempcontent[countline][countchar]=='\n'){
                    //end line char
                    tempcontent[countline][countchar+1]='\0';
                }
            }
        }
        else{
            //copy from content
            tempcontent[countline]=content[contentline];
            contentline++;
        }
        countline++;
    }
    tempcontent[countline]=NULL;
    printf("tempcontent:\n");
    print(tempcontent);
    swappointers(&content,&tempcontent);
}

int main(){
    //allocate memory for our future content
    char **content = (char**)malloc(sizeof(char*)*MAXLINES);

    content[0] = malloc(MAXLENGTH);
    strncpy(content[0],"line 0",MAXLENGTH);
    content[1] = malloc(MAXLENGTH);
    strncpy(content[1],"line 2",MAXLENGTH);
    content[2] = malloc(MAXLENGTH);
    strncpy(content[2],"line 3",MAXLENGTH);
    content[3] = NULL;

    printf("________FILE BEFORE________\n");
    print(content);

    addline(content,"line 1",1);

    printf("________FILE AFTER________\n");
    print(content);
}

Output:

________FILE BEFORE________
line 0
line 2
line 3
tempcontent:
line 0
line 1
line 2
line 3
________FILE AFTER________
line 0
line 2
line 3

Upvotes: 0

Views: 1053

Answers (1)

Paul Ogilvie
Paul Ogilvie

Reputation: 25286

If char **content has "lines of text" then content points to an array where each element has a pointer to a string (line of text).

Suppose you have 10 lines. Then you allocate content as:

content= malloc(10*sizeof(char *));

Suppose each line has no more than 80 characters, then you allocate the first line as:

content[0]= malloc(80+1);  //add one for the terminating \0
strcpy(content[0], myline);

Now, from this example, you can figure out how to allocate the other lines, allocate temp, copy lines to temp and do whatever you need to do.

When you are done, don't forget to release the memory:

free(content[0]); //...and free the other lines as well
free(content);


EDIT:

You added code and asked me to look at it. I have the following comments:

  1. After strncpy ALWAYS place a null character in the last position! strncpy doesn't do that for you and any memory allocated with malloc is not zero initialized:

    strncpy(content[0],"line 0",MAXLENGTH);
    content[0][MAXLENGTH-1]= '\0';
    
  2. For addline to work, i.e. swapping the pointers, you must pass it the address of content in main and swap must be then be called in addline as follows:

    addline(char ***content, etc);       // prototype
    swappointers(content,&tempcontent);  // call in addline
    addline(&content,"line 1",1);        // call in main
    
  3. After swappointers you must free tempcontent

Upvotes: 1

Related Questions