Strcat не добавляет символ

char* oledScreen::getCurrentTime(){
   char* hour = malloc(16);
   snprintf(hour, 16, "%d", getHour());

   char* minute = malloc(16);
   snprintf(minute, 16, "%d", getMinute());

   char* firstPart = strcat(getHour() < 10 ? strcat("0",hour) : hour, ":");
   const char* secondPart = getMinute() < 10 ? strcat("0",minute) : minute;

   return strcat(firstPart, secondPart);
};

Я пытаюсь добавить два целых числа, которые я могу получить, используя getHour() и getMinute(). Однако мне нужно проверить, меньше ли одно из этих двух значений 10: если это так, мне нужно добавить 0, чтобы вывод был таким: 0X, где X — это getHour() или getMinute().

Моя проблема в том, что он не добавляет символ :. Например, если getHour() = 9 и getMinute() = 15. Результатом getCurrentTime() является 0915, а не 09:15. У вас есть идеи, почему это так?

У вас также есть утечки памяти, кто будет free выделять память для hour и minute?

Some programmer dude 11.11.2022 09:19
snprintf(buffer, buffer_size, "%02d:%02d", getHour(), getMinute())
Paul Hankin 11.11.2022 09:20

Кстати, ваш код не C, это C++. Поэтому вам не следует использовать массивы char или snprintf для начала.

Some programmer dude 11.11.2022 09:22

@Someprogrammerdude или malloc...

Paul Hankin 11.11.2022 09:22
strcat("0",hour) добавляет все, что находится в hour, к строковому литералу "0". Вы не можете добавить что-то к строковому литералу. должен предупредить вас: godbolt.org/z/a48x3bnYo
mch 11.11.2022 09:24

@Armin Montigny Пожалуйста, обратите особое внимание на весь исходный код, прежде чем принять решение об редактировании языковых тегов, особенно когда ответы публикуются на одном языке, после чего уже слишком поздно менять теги. Руководство по использованию тегов см. в вики-сайтах по тегам C и C++.

Lundin 11.11.2022 09:41
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
6
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Начнем с того, что strcat("0",hour) приведет к неопределенному поведению, когда вы попытаетесь изменить литеральную строку "0", что не разрешено.

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

Использование snprintf также упростит добавление нулевого префикса к значению часа.

Возможно что-то вроде этого:

// Allocate memory, and actually create the string
// 2 for hour, 2 for minutes, 1 for colon, 1 for terminator
char *result = malloc(6);

snprintf(result, 6, "%02d:%02d", getHour(), getMinute());

return result;

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

[Note that the above is a pure C solution, it's not even valid in C++. I wrote it before noticing that the code in the question is really C++.]


Учитывая, что вы действительно программируете на C++, а не на C, то решение с использованием строковых потоков и std::string будет более подходящим:

std::string oledScreen::getCurrentTime(){
    std::ostringstream oss;

    oss << std::setw(2) << std::setfill('0') << getHour() << ':'
        << std::setw(2) << std::setfill('0') << getMinute();

    return oss.str();
}

Вероятно, даже лучше, если вызывающая сторона проходит через буфер (и размер), потому что я предполагаю, что в основном вызывающая сторона может использовать буфер на основе стека, избегая выделения кучи.

Paul Hankin 11.11.2022 09:27

Кроме того, использование malloc/free в C++ крайне проблематично и не рекомендуется, поскольку конструкторы/деструкторы по умолчанию не вызываются.

Lundin 11.11.2022 09:43

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