странности со sprintf

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
void setup() 
{         
  Serial.begin(9600);  
}

void loop() 
{
  unsigned long sec = millis() / 1000;
  char msg[10];
  sprintf(msg, "%d:%02d:%02d", (sec / 3600) % 24, (sec / 60 ) % 60, sec % 60);
  Serial.println(msg);
  delay (1000);
}

Почему-то в третьей позиции вместо секунд выводятся минуты.

Хотя если написать 

sprintf(msg, "%02d", sec % 60);

то секунды выводятся корректно.

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016
void setup() 
{         
  Serial.begin(9600);  
}

void loop() 
{
  unsigned long sec = millis() / 1000;
  char msg[10];
  sprintf(msg, "%ld:%l02d:%l02d", (sec / 3600) % 24, (sec / 60 ) % 60, sec % 60);
  Serial.println(msg);
  delay (1000);
}

 

Том, уважаемый! История функции printf() и клонов восходит к первому С, еще от Кернигана и Ричи.

Описывается она в самом первом стандарте, как функция с переменным числом аргументов, примерно как main().

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

Вы обманули sprintf(), пообещав ему три двубайтовых целых, а положили три 4-х байтовых. Вас наказали за обман ;).

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

я не жадный, могу и больше дать.

Ваш код выводит только два символа:

0:

Наверное подавился :)

Но направление теперь понятно. Если в первом примере заменить long на int, то работает.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

void setup() 
{         
  Serial.begin(9600);  
}

void loop() 
{
  unsigned long sec = millis() / 1000;
  char msg[10];
  sprintf(msg, "%lu:%02lu:%02lu", (sec / 3600) % 24, (sec / 60 ) % 60, sec % 60);
  Serial.println(msg);
  delay (1000);
}

Работает!

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

Сорри! В двух последних модификатор ПЕРЕД "d".    Все, блин, спешка моя!!

Мои извинения!!!

void setup() 
{         
  Serial.begin(9600);  
}

void loop() 
{
  unsigned long sec = millis() / 1000;
  char msg[10];
  sprintf(msg, "%ld:%02ld:%02ld", (sec / 3600) % 24, (sec / 60 ) % 60, sec % 60);
  Serial.println(msg);
  delay (1000);
}

 

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

Вы опередили мои правки, сорри. отходил по делам

"u" необязательно, но полезно. ГЛАВНОЕ указать printf() размер аргумента в стеке. Это делает модификатор.

Я поставил перед d в первом формате, а дальше руки сами ввели Вас в заблуждение! Сорри еще раз!