Копировать строку в указатель на указатель - PullRequest
1 голос
/ 19 декабря 2008

Я использую этот пример:

char *myData[][2] =
{{"John", "j@usa.net"},
 {"Erik", "erik@usa.net"},
 {"Peter","peter@algonet.se"},
 {"Rikard","rikard@algonet.se"},
 {"Anders","anders@algonet.se"}};   

char **tableData[6];
tableData[0] = myData[0];
tableData[1] = myData[1];
tableData[2] = myData[2];
tableData[3] = myData[3];
tableData[4] = myData[4];
tableData[5] = NULL;//null terminated array

и вместо этого хочу разместить свои собственные строки для имени и электронной почты. (пытается поместить строку xyz в myData, затем tableData) strcpy с myData не будет работать. Я перепробовал все комбинации указателей и ссылок, но похоже, что строка не копируется. Есть предложения?

             ok--> strncpy(xyz, argv[i], strlen(argv[i]));
             ok--> strcpy(xyz + strlen(argv[i]), "\0");
run time stops here--> strncpy(myData[i][0], xyz, strlen(xyz));  
                   tableData[i] = myData[i];

Ответы [ 2 ]

3 голосов
/ 19 декабря 2008

Указатели в myData[][] при инициализации указывают на буквенные строки. Эта память не может быть записана в.

Вы можете выделить новую память для новых строк и поместить указатели на новые строки в myData. Или для того, что вы делаете, просто сохраните указатели на строки argv [] (если вы не планируете изменять строки позже).

Кроме того, убедитесь, что блок памяти, в который вы копируете строки, достаточно велик для размещения новой строки.

Software Monkey Edit: включая терминатор \ 0; и убедитесь, что вы освобождаете память при необходимости.

0 голосов
/ 19 декабря 2008

Создайте собственную локальную копию данных и измените указатель в списке:

char **newentry = malloc(sizeof(char*) * 2);
newentry[0] = strdup(myNewName);
newentry[1] = strdup(myNewEmail);
tableData[i] = newentry;

Это легкая часть. Трудная часть освобождает память, когда вы закончите. Если это всего лишь небольшая одноразовая программа на C, вы, вероятно, можете обойтись без освобождения памяти, поскольку операционная система автоматически освободит ее при выходе из приложения.

Но если вы хотите сделать это правильно с заглавной буквой 'P', я бы сделал пару небольших функций для копирования и освобождения элементов таблицы:

void tableFreeItem(int i)
{
    if(tableData[i] != 0)
    {
       free(tableData[i][0]);
       free(tableData[i][1]);
       free(tableData[i]);
    }
}

void tableSetItem(int i, char *name, char *email)
{
    tableFreeItem(i);

    tableData[i] = malloc(sizeof(char *) * 2);
    tableData[i][0] = strdup(name);
    tableData[i][1] = strdup(email);
}

Теперь мы можем заменить элементы в списке по желанию и легко освободить память, вызвав функцию tableFreeItem (). Вот пример того, как вы можете использовать эти функции:

#define TABLE_SIZE 5

char **tableData[TABLE_SIZE + 1]; /* +1 to make room for NULL terminator */

/* Clear out the table. This also sets up the NULL terminator at the end. */
    memset(tableData, 0, sizeof(tableData));

/* Copy the original data into the table */
    for(i = 0; i < TABLE_SIZE; i++)
        tableSetItem(i, mydata[i][0], myData[i][1]);

/* Change a data item */
    tableSetItem(3, "Adam Pierce", "adam@doctort.org");

/* Free memory when we have finished */
    for(i = 0; i < TABLE_SIZE; i++)
        tableFreeItem(i);

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не пытался скомпилировать или запустить этот код, я просто ударил его по макушке. Это, вероятно, будет работать.

...