2

With the example found in a website, I'm trying to convert a char* to a SYSTEMTIME structure :

SYSTEMTIME st;
char *dateHeure = (char*)calloc(30,1);
strcpy(dateHeure, "18/02/2016 15:02:05");
sscanf(dateHeure, "%d/%d/%d %d:%d:%d", (int*)&st.wDay, (int*)&st.wMonth, (int*)&st.wYear, (int*)&st.wHour, (int*)&st.wMinute, (int*)&st.wSecond);

It works for all st's members BUT st.wMonth : it does not receive any value. What's wrong ?

Thank you for your help !

Finelizzyx
  • 101
  • 1
  • 7
  • 3
    Your casts invoke undefined behaviour. **Only cast iff** 1) they are absolutely necessary, 2) you know about **all** implications and 3) accept them. Instead use the correct type specifies in the format string. – too honest for this site Feb 18 '16 at 21:00
  • [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Feb 18 '16 at 21:00

2 Answers2

2

The structure SYSTEMTIME contains members whose types are WORD. That is a 16 bit unsigned integer.

Your code is passing the address of those members and casting them to int*. This is undefined behavior.

According to Microsoft, WORD is defined as an unsigned short.
This means the correct specifier for scanf() is %hu, and the casts should be removed.

2501
  • 25,460
  • 4
  • 47
  • 87
1

Get rid of the type-casts, they are wrong. SYSTEMTIME uses WORD for its fields. WORD is a typedef for unsigned short, so you can use %hu instead of %d:

sscanf(dateHeure, "%hu/%hu/%hu %hu:%hu:%hu",
    &st.wDay, &st.wMonth, &st.wYear,
    &st.wHour, &st.wMinute, &st.wSecond);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770