Скрытый байт в беззнаковом 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
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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";

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