Я пытаюсь запустить этот код в 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"};
Я довольно новичок в С++. Может ли кто-нибудь помочь мне понять, почему это происходит?
char daysOfTheWeek[7][5]
тоже исправит. У вас должно быть достаточно места для строковых данных и завершающего 0.
@JonathanWood Этот фрагмент кода кажется мне простым. У меня такое ощущение, что это происходит на уровне памяти. Что-то вроде переполнения буфера, но во время чтения. Не уверен, что отладчик может это выбрать.
@RetiredNinja Ожидается ли, что в нем будет дополнительное пространство для завершения 0?
Интересно, почему бы не использовать современные контейнеры C++? Как std::vector
, std::array
и std::string
.
@HảiPhạmLê в моем случае требуется char[]. Я пытаюсь напечатать текст на жидкокристаллическом дисплее. Библиотека, которую я использую, требует char[]
В качестве краткой информации, приведенный выше код не компилируется при использовании Visual Studio (компилятор: MSVC). Это связано с тем, что максимальный размер const char
, который может быть сохранен в массиве, здесь равен 4
(из-за [7][4]
), а "Tues"
и "Thur"
имеют 5 символов. Изменение [4]
на [5]
сработало для меня, и VS успешно скомпилировал и распечатал дни.
Все строковые литералы имеют в конце неявный нуль-терминатор. Итак, самые большие из ваших, "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] решает эту проблему.
Это происходит потому, что второе измерение массива короче самого длинного слова.
Код устанавливает второе измерение равным 4. Таким образом, каждый оператор печати будет печатать до 4 символов. Нулевой символ, который добавляется к каждому слову, считается за единицу. Поэтому некоторые слова, такие как "Mon", будут печататься правильно (3 символа для слова + 1 символ для нуля). Более длинные слова, такие как «Чт», будут напечатаны без нулевых символов, поэтому вы увидите «Чт» и «Пт» подряд, как в «ЧтПт». Чтобы исправить эту ситуацию, увеличьте второе измерение массива!
Второй вариант использует указатели, для которых компилятор автоматически знает длину слова, а значит, вывод будет правильным.
Есть и другие способы сделать это, о которых вы можете прочитать здесь: https://www.geeksforgeeks.org/массив-строки-c-3-разные-способы-создать/
Вы вообще знакомы с тем, как пользоваться отладчиком? Они позволяют вам установить точку останова, и при ее попадании вы можете проверить данные.