Как я создаю массив строк в C?

В C++ можно использовать оператор потоковой передачи для упрощения вещей:

#if defined _DEBUG

class Trace
{
public:
   static Trace &GetTrace () { static Trace trace; return trace; }
   Trace &operator << (int value) { /* output int */ return *this; }
   Trace &operator << (short value) { /* output short */ return *this; }
   Trace &operator << (Trace &(*function)(Trace &trace)) { return function (*this); }
   static Trace &Endl (Trace &trace) { /* write newline and flush output */ return trace; }
   // and so on
};

#define TRACE(message) Trace::GetTrace () << message << Trace::Endl

#else
#define TRACE(message)
#endif

и использование это как:

void Function (int param1, short param2)
{
   TRACE ("param1 = " << param1 << ", param2 = " << param2);
}

можно тогда реализовать настроенный вывод трассировки для классов почти таким же способом, которым Вы сделали бы это для вывода к std::cout.

240
задан 22 August 2018 в 08:39
поделиться

7 ответов

Если вы не хотите изменять строки, вы можете просто сделать

const char *a[2];
a[0] = "blah";
a[1] = "hmm";

. Когда вы сделаете это так, вы выделите массив из двух указателей на const char . Затем эти указатели будут установлены на адреса статических строк «бла» и «хмм» .

Если вы действительно хотите иметь возможность изменять фактическое содержимое строки, вам нужно сделать что-то вроде

char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");

. Это выделит два последовательных массива по 14 char s каждый, после чего содержимое статических строк будет скопировано в них.

215
ответ дан 23 November 2019 в 03:17
поделиться

Ваш код создает массив указателей на функции. Попробуйте вместо этого

char* a[size];

или

char a[size1][size2];

.

См. Вики-книги для массивов и указателей

3
ответ дан 23 November 2019 в 03:17
поделиться

Строковые литералы имеют вид const char * s.

И вы используете круглые скобки странно. Вы, вероятно, имеете в виду

const char *a[2] = {"blah", "hmm"};

, который объявляет массив из двух указателей на постоянные символы и инициализирует их так, чтобы они указывали на две жестко заданные строковые константы.

9
ответ дан 23 November 2019 в 03:17
поделиться

В ANSI C:

char* strings[3];
strings[0] = "foo";
strings[1] = "bar";
strings[2] = "baz";
10
ответ дан 23 November 2019 в 03:17
поделиться

Вот некоторые из ваших вариантов:

char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" };  // only since you brought up the syntax -

printf(a1[0]); // prints blah
printf(a2[0]); // prints blah
printf(*a3[0]); // prints blah

Преимущество a2 заключается в том, что затем вы можете сделать следующее с строковые литералы

a2[0] = "hmm";
a2[1] = "blah";

А для a3 вы можете сделать следующее:

a3[0] = &"hmm";
a3[1] = &"blah";

Для a1 вам нужно будет использовать strcpy () (еще лучше ] strncpy () ) даже при назначении строковых литералов. Причина в том, что a2 и a3 являются массивами указателей, и вы можете сделать так, чтобы их элементы (то есть указатели) указывали на любое хранилище, тогда как a1 - это массив из 'массива символов'

14
ответ дан 23 November 2019 в 03:17
поделиться

Есть несколько способов создать массив строк в C. Если все строки будут одинаковой длины (или, по крайней мере, иметь одинаковую максимальную длину), вы просто объявляете 2 -d массив символов и присвоить при необходимости:

char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");

Вы также можете добавить список инициализаторов:

char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};

Это предполагает, что размер и количество строк в инициализаторе совпадают с размерами вашего массива. В этом случае содержимое каждого строкового литерала (который сам является массивом символов с завершающим нулем) копируется в память, выделенную для strs. Проблема с этим подходом - возможность внутренней фрагментации; если у вас 99 строк длиной 5 или менее символов, но 1 строка длиной 20 символов, 99 строк будут содержать не менее 15 неиспользуемых символов; это пустая трата места.

Вместо использования двумерного массива символов, вы можете сохранить одномерный массив указателей на char:

char *strs[NUMBER_OF_STRINGS];

Обратите внимание, что в этом случае вы выделили только память для хранения указателей на строки; память для самих строк должна быть выделена в другом месте (либо в виде статических массивов, либо с помощью malloc () или calloc () ). Вы можете использовать список инициализаторов, как в предыдущем примере:

char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};

Вместо копирования содержимого строковых констант вы просто сохраняете на них указатели. Обратите внимание, что строковые константы могут быть недоступны для записи; вы можете переназначить указатель, например:

strs[i] = "bar";
strs[i] = "foo"; 

Но вы не сможете изменить содержимое строки; т.е.

strs[i] = "bar";
strcpy(strs[i], "foo");

не может быть разрешено.

Вы можете использовать malloc () для динамического выделения буфера для каждой строки и копирования в этот буфер:

strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");

Кстати,

char (*a[2])[14];

Объявляет как 2-элементный массив указателей на 14-элементные массивы char.

167
ответ дан 23 November 2019 в 03:17
поделиться

Верно! Постоянные строки:

const char *strings[] = {"one","two","three"};

Если я правильно помню.

О, и вы хотите использовать strcpy для присваивания, а не оператор =. strcpy_s безопаснее, но его нет ни в стандартах C89, ни в стандартах C99.

char arr[MAX_NUMBER_STRINGS][MAX_STRING_SIZE]; 
strcpy(arr[0], "blah");

Обновление: Томас говорит, что strlcpy - это правильный путь.

89
ответ дан 23 November 2019 в 03:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: