Скрытый байт в беззнаковом char[]

unsigned char blind[32] = "and my kingdom too for a blinder";

Это дает ошибку:

a value of type "const char [33]" cannot be used to initialize an entity of type "unsigned char [32]"C/C++(144)

Я не понимаю, почему это дает ошибку.

Я пытаюсь использовать библиотеку C в проекте C++ и хотел отправить тип, который запрашивала библиотека C.

"and my kingdom too for a blinder" — это сокращение от {'a', 'n', 'd', '...', 'd', 'e', 'r', '\0'}.
CompuChip 17.05.2022 10:29

Я думаю, что было бы проще начать с более коротких строк: sizeof("") == 1 (единственный символ — это скрытый '\0', sizeof("a") == 2 (это 'a', за которым следует '\0').

Krzysiek Karbowiak 17.05.2022 10:47

Почему был удален тег C++? Сообщение об ошибке является ошибкой C++, а не ошибкой C

Gerhardh 17.05.2022 12:50
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
3
71
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Строки C не сохраняют свою длину, поэтому для обозначения конца строки используется «нулевой терминатор» (символ \0). Это добавляет один дополнительный байт к строке. Поскольку вы инициализируете строковый литерал, он игнорирует [32] и использует длину вашей фактической строки, которая включает скрытый терминатор.

Спасибо, когда я изменился на: ``` {'a','n','d',' ','m','y',' ','k','i','n',' g','d','o','m',' ','t','o','o',' ','f','o','r',' ','a ',' ','b','l','i','n','d','e','r'}, ``` это сработало.

lukas 17.05.2022 10:31

@lukas важен нулевой терминатор. Вы должны сохранить это

Raildex 17.05.2022 10:38

@lukas обратите внимание, что с вашим решением у вас больше нет действительной строки

Ingo Leonhardt 17.05.2022 10:39

@lukas Будьте осторожны с решением, которое вы разместили в комментарии. Если функция C ожидает строку в стиле C, вы делаете это неправильно. Но мы не можем сказать наверняка, так как вы никогда не говорили, для чего будут использоваться данные....

Support Ukraine 17.05.2022 10:40

[32] не игнорируется.

user253751 17.05.2022 10:41

О да, нулевой терминатор очень важен. Спасибо!

lukas 17.05.2022 10:55

@Raildex Массив символов C не содержит \0?

lukas 17.05.2022 10:56

@lukas "and my kingdom too for a blinder" — строковый литерал. Он содержит 32 «видимых» символа и невидимый нулевой терминатор — следовательно, это массив из 33 символов. Что вам нужно сделать, это изменить количество символов вашей переменной: unsigned char blind[33] = "and my kingdom too for a blinder";

Raildex 17.05.2022 11:01

@Raildex Да, теперь я понимаю свою проблему, спасибо. Но строка с ошибкой в ​​C++ успешно скомпилирована в C. Я полагаю, что C автоматически не добавляет терминатор NULL? C и C++ по-разному обрабатывают строку, что является основной причиной?

lukas 17.05.2022 13:52

Нет необходимости использовать unsigned char [], если вы будете работать только с символами, символами и числами, поскольку все эти данные находятся в диапазоне простого char (который в основном представляет собой 8-битный тип данных в дополнении 2).

Во-вторых, если вы хотите быстро инициализировать char [], вы можете использовать библиотеку string.h, которая является стандартной и действительно полезной библиотекой, просто включите ее. Затем просто скопируйте свою строку в переменную, учитывая, что вы должны оставить место для конечного символа '\0', который неявно помещается в строки (char []), чтобы библиотека string.h могла определить конец строки (char[ ]).

char blind[33];
strcpy(blind,"and my kingdom too for a blinder");
printf("%s", blind);

вывод: и мое королевство тоже для шоры

char blind[33] = "and my kingdom too for a blinder"; достаточно
Support Ukraine 17.05.2022 10:38

Использование strcpy таким образом означает, что если вы ошибетесь с длиной, вместо ошибки компилятора вы получите переполнение буфера. Плохая идея.

user2357112 17.05.2022 10:40

@ user2357112, затем проверьте длину перед ее использованием, но назначение строки в объявлении не является универсальным. Если вы хотите объявить постоянную строку, например, сообщение об ошибке, то следует использовать макрос #define, а не char [], это пустая трата памяти.

LexFerrinson 17.05.2022 10:45

Кроме того, использование strcpy — это назначение во время выполнения, а не инициализация. Это всегда медленнее, чем инициализация, поэтому все, что вы получили, это код помедленнее.

Lundin 17.05.2022 10:59

И если вы беспокоитесь о пустой трате памяти, объявите массив как const char[] на случай, если его не следует изменять.

Lundin 17.05.2022 11:00

const char[] продолжает использовать ту же память, что и char[], просто не изменяемая

LexFerrinson 17.05.2022 11:11

@LexFerrinson Это зависит от системы. Во встроенных системах вы обычно заметите значительную разницу, поскольку переменная только для чтения перемещается из ОЗУ во флэш-память.

Lundin 17.05.2022 12:57
Ответ принят как подходящий

проблема состоит в том, что "and my kingdom too for a blinder" является строковый литерал типа const char[33], а не const char[32]. Последний символ — нулевой символ '\0'. Это означает, что строковый литерал "and my kingdom too for a blinder" эквивалентен:

{'a', 'n', 'd', ' ', 'm', 'y', ' ', 'k','i','n','g','d','o','m',' ','t','o','o',' ','f','o', 'r', ' ', 'a', ' ', 'b', 'l', 'i', 'n', 'd', 'e', 'r', '\0'}

Обратите внимание, что в приведенном выше const char эквивалентном массиве есть 33 символы, включая нулевой символ '\0'.

Для решить просто измените размер целевого массива, как показано ниже:

//---------vv------------------------------------------->changed to 33
char blind[33] = "and my kingdom too for a blinder";

Другие вопросы по теме