инициализация массивов символов, в некотором роде подобных инициализации строковых литералов

Предположим, что у меня есть следующая инициализация массива символов:

char charArray[]={'h','e','l','l','o',' ','w','o','r','l','d'};

и у меня также есть следующая инициализация строкового литерала:

char stringLiteral[]="hello world";

Единственная разница между содержанием первого массива и второй строки - то, что вторая строка имеет нулевой символ в своем конце.

Когда это - вопрос инициализации массива символов, есть ли макрос или что-то, что позволяет нам помещать наш текст инициализации между двумя двойными кавычками, но где массив не получает дополнительный пустой оконечный знак?

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

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

Я благодарен за Ваши ответы.

6
задан Pooria 17 July 2010 в 17:54
поделиться

5 ответов

Я мог бы найти способ делать то, что хочу, хотя это не совсем то, что я хотел, но, вероятно, имел бы тот же эффект.
Сначала рассмотрим два следующих класса:

template <size_t size>
class Cont{
 public:
  char charArray[size];
};
template <size_t size>
class ArrayToUse{
 public:
  Cont<size> container;
  inline ArrayToUse(const Cont<size+1> & input):container(reinterpret_cast<const Cont<size> &>(input)){}
};

Прежде чем продолжить, вы можете перейти сюда и взглянуть на конструкторы константных выражений и типы инициализации.
Теперь посмотрим на следующий код:

const Cont<12> container={"hello world"};
ArrayToUse<11> temp(container);
char (&charArray)[11]=temp.container.charArray;

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

0
ответ дан 9 December 2019 в 22:28
поделиться

Нет никакого способа делать то, что вы хотите. Первый способ инициализации массива задает отдельные инициализаторы для каждого символа, что позволяет явно оставить '0'. Во-вторых, инициализация массива символов из символьной строки, которая в C/C++ всегда завершается пустым символом.

ПРАВКА: исправлено: 'указатель символов' --> 'массив символов'

3
ответ дан 9 December 2019 в 22:28
поделиться

В C разрешено объявлять массив следующим образом, что инициализирует его без копирования завершающего '\ 0'

char c[3] = "foo";

. Но это незаконно в C ++. Я не знаю трюка, который позволил бы это сделать для C ++.Стандарт C ++ далее говорит

Обоснование : когда этими неограниченными массивами манипулируют с помощью стандартных строковых подпрограмм, существует вероятность серьезной катастрофы.
Влияние на исходную функцию : Удаление семантически четко определенной функции.
Сложность преобразования : семантическое преобразование. Массивы должны быть объявлены на один элемент больше, чтобы содержать завершающую строку ’\ 0’.
Насколько широко используется : Редко. Такой стиль инициализации массива считается плохим стилем кодирования.

7
ответ дан 9 December 2019 в 22:28
поделиться

litb имеет технически правильный ответ .

Что касается мнения - я говорю, просто живите с «расточительством» лишних «\ 0». Так много ошибок является результатом того, что код ожидает завершающего нуля, а его нет (этот совет может показаться прямо противоречащим другим советам, которые я дал всего день или два назад, о том, чтобы не беспокоить обнуление всего буфера. Я утверждаю, что нет противоречие - я все еще выступал за завершение строки в буфере нулем).

Если вы действительно не можете жить с терминатором '\ 0' из-за некоторой семантики в структуре данных, с которой вы имеете дело, например, он может быть частью какой-то более крупной упакованной структуры, вы всегда можете инициализировать массив самостоятельно (что, я думаю, должно быть не менее эффективным, чем то, что компилятор мог бы сделать для вас):

#define MY_STRING_LITERAL "hello world"

char stringLiteral[sizeof(MY_STRING_LITERAL) - 1];

memcpy( stringLiteral, MY_STRING_LITERAL, sizeof(stringLiteral));
1
ответ дан 9 December 2019 в 22:28
поделиться

Основной ответ заключается в том, что подавляющее большинство массивов char являются строками - в C строки имеют нулевое окончание. C++ унаследовал это соглашение. Даже когда этот нуль не нужен, в большинстве случаев не проблема просто оставить его там в любом случае.

Макросы недостаточно мощны, чтобы сделать то, что вы хотите. Шаблоны могли бы, но они не имеют никакой компилятивной обработки строк.

Обычно, когда люди хотят смешать числовые байты и строковые литералы в одной последовательности char-массива, они используют строковый литерал, но используют шестнадцатеричные символы, такие как \xFF.

0
ответ дан 9 December 2019 в 22:28
поделиться
Другие вопросы по тегам:

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