Неправильные значения печати при повторении массива 2d char

Я пытаюсь запустить этот код в Arduino IDE. Он печатает неправильные значения.

char daysOfTheWeek[7][4] = {"Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"};

for(int i=0;i<7;i++) {
    Serial.print(daysOfTheWeek[i]);
    Serial.print(" ");
}

Serial.println();

Печатные значения

Sun Mon TuesWed Wed ThurFri Fri Sat

Я вижу, что это можно исправить, изменив распределение массива следующим образом.

char *daysOfTheWeek[7] = {"Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"};

Я довольно новичок в С++. Может ли кто-нибудь помочь мне понять, почему это происходит?

Вы вообще знакомы с тем, как пользоваться отладчиком? Они позволяют вам установить точку останова, и при ее попадании вы можете проверить данные.

Jonathan Wood 17.05.2022 06:01
char daysOfTheWeek[7][5] тоже исправит. У вас должно быть достаточно места для строковых данных и завершающего 0.
Retired Ninja 17.05.2022 06:06

@JonathanWood Этот фрагмент кода кажется мне простым. У меня такое ощущение, что это происходит на уровне памяти. Что-то вроде переполнения буфера, но во время чтения. Не уверен, что отладчик может это выбрать.

r005t3r 17.05.2022 06:09

@RetiredNinja Ожидается ли, что в нем будет дополнительное пространство для завершения 0?

r005t3r 17.05.2022 06:12

Интересно, почему бы не использовать современные контейнеры C++? Как std::vector, std::array и std::string.

Hải Phạm Lê 17.05.2022 06:22

@HảiPhạmLê в моем случае требуется char[]. Я пытаюсь напечатать текст на жидкокристаллическом дисплее. Библиотека, которую я использую, требует char[]

r005t3r 17.05.2022 06:42

В качестве краткой информации, приведенный выше код не компилируется при использовании Visual Studio (компилятор: MSVC). Это связано с тем, что максимальный размер const char, который может быть сохранен в массиве, здесь равен 4 (из-за [7][4]), а "Tues" и "Thur" имеют 5 символов. Изменение [4] на [5] сработало для меня, и VS успешно скомпилировал и распечатал дни.

Solved Games 17.05.2022 06:49
Формы 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
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
7
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Все строковые литералы имеют в конце неявный нуль-терминатор. Итак, самые большие из ваших, "Tues" и "Thur", на самом деле содержат символы 5, например: "Tues\0" и "Thur\0".

Таким образом, вам нужно либо увеличить размерность массива символов до [5] (что приведет к char daysOfTheWeek[7][5]), либо вместо этого вам нужно использовать "Tue" и "Thu" в качестве инициализаторов.

Для вас может быть наглядным использовать тот факт, что Serial.print()возвращает количество записанных байтов, когда вы пытаетесь распечатать содержимое daysOfTheWeek таким образом.

Между тем, например, в компиляторе g++ ваш код должен выдать ошибку: error: initializer-string for array of chars is too long, указывающую на два проблемных строковых литерала, упомянутых выше.

Что касается части Arduino, вы можете рассмотреть возможность использования типа библиотеки Нить.

Спасибо @rawrex за ответ. daysOfTheWeek[7][5] решает эту проблему.

r005t3r 17.05.2022 06:46

Это происходит потому, что второе измерение массива короче самого длинного слова.

Код устанавливает второе измерение равным 4. Таким образом, каждый оператор печати будет печатать до 4 символов. Нулевой символ, который добавляется к каждому слову, считается за единицу. Поэтому некоторые слова, такие как "Mon", будут печататься правильно (3 символа для слова + 1 символ для нуля). Более длинные слова, такие как «Чт», будут напечатаны без нулевых символов, поэтому вы увидите «Чт» и «Пт» подряд, как в «ЧтПт». Чтобы исправить эту ситуацию, увеличьте второе измерение массива!

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

Есть и другие способы сделать это, о которых вы можете прочитать здесь: https://www.geeksforgeeks.org/массив-строки-c-3-разные-способы-создать/

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