Как вы перебираете массив массивов символов в c? - PullRequest
5 голосов
/ 28 января 2012

Нужно ли вручную циклически проходить по массиву один раз и получать счетчик strlen каждого символьного массива, суммировать его, назначать место назначения с суммированным значением и затем снова циклически повторять массив?Вы нашли размер массива, который содержит массивы символов, чтобы вы могли перебирать их?

Ответы [ 4 ]

7 голосов
/ 28 января 2012

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

Есть два способа:

  1. Запишите количество строк в массиве при выделении его в переменной.
  2. Выделите дополнительный char* в конце массива и сохраните в нем нулевой указатель как сторож, аналогично тому, каксимвол NUL используется для завершения строки.

Другими словами, при распределении массива вы должны вести свой собственный учет, потому что C не даст вам нужную информацию.Если вы последуете второму предложению, вы можете получить общее количество символов в массиве строк с помощью

size_t sum_of_lengths(char const **a)
{
    size_t i, total;
    for (i = total = 0; a[i] != NULL; i++)
        total += strlen(a[i]);
    return total;
 }

Не забудьте зарезервировать место для '\0' при выполнении фактической конкатенации.

1 голос
/ 28 января 2012

Я предполагаю, что вы пытаетесь создать строку, которая является объединением всех строк в массиве.

Есть 2 способа сделать это:

  1. Сделайте 2 прохода, как вы предлагаете, суммируя длины в первом проходе, выделяя строку назначения, а затем добавляя строки во втором проходе

  2. Сделайте 1 проход. Начните с выделения буфера до некоторого размера. Добавить строки, отслеживая общий размер. Если у вас недостаточно места для строки, перераспределите буфер с помощью realloc(). Наиболее эффективным методом перераспределения будет каждый раз удваивать размер буфера.

0 голосов
/ 28 января 2012
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *nstrdup(char **args);
int main (int argc, char **argv)
{
char * this;

this = nstrdup(argv+1);
printf("[%s]\n", this );

return 0;
}

char *nstrdup(char **args)
{
size_t len, pos;
char **pp, *result;

len = 0;
for (pp = args; *pp; pp++) {
        len += strlen (*pp);
        }
result = malloc (1+len);

pos = 0;
for (pp = args; *pp; pp++) {
        len = strlen (*pp);
        memcpy(result+pos, *pp, len);
        pos += len;
        }
result[pos] = 0;
return result;
}
0 голосов
/ 28 января 2012

Я думаю, что вы хотите объединить строки.Если да, то да.Вы должны знать, сколько места вам нужно, прежде чем выделять его.

На самом деле вы можете использовать realloc, но на самом деле это просто копировать предыдущую строку каждый раз и гораздо менее эффективно.

Некоторый код: (при условии char *s[] и int n)

int i,l=1;
for (i=0;i<n;i++) l+=strlen(s[i]);
char *r=malloc(l);
r[0]=0;
for (i=0;i<n;i++) strcat(r,s[i]);

Редактировать: Как некоторые комментарии, strcat неэффективен, когда вы знаете длину.(Я все еще предпочитаю это, поскольку он выделяет память за один раз.) Более эффективный код:

int i,l=1;
for (i=0;i<n;i++) l+=strlen(s[i]);
char *r=malloc(l);
char *d=r;
for (i=0;i<n;i++) {
 srtcpy(d,s[i]);
 d+=strlen(s[i]);
}
...