Govind Parmar
Govind Parmar

Reputation: 21532

Why is sscanf not reading the first argument in the format string?

In the following program, everything but the first value (the month) in the format string is being read into the SYSTEMTIME structure. Can anyone help me figure this one out?

#include <Windows.h>
#include <stdio.h>

int main()
{
    SYSTEMTIME st;
    char buf[50];
    strcpy(buf, "6/23/2015 12:00:00");
    sscanf(buf, "%d/%d/%d %d:%d:%d", &st.wMonth, &st.wDay, &st.wYear, &st.wHour, &st.wMinute, &st.wSecond);
    printf("%d %d %d %d %d %d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    return 0;
}

The output of the program is:

2015 0 23 12 0 0

It should be:

2015 6 23 12 0 0

Upvotes: 1

Views: 801

Answers (1)

Spikatrix
Spikatrix

Reputation: 20244

You are using the wrong format specifier. %d is used for ints. Is st.* an int? No.

As per the documentation, the SYSTEMTIME structure is defined as

typedef struct _SYSTEMTIME {
  WORD wYear;
  WORD wMonth;
  WORD wDayOfWeek;
  WORD wDay;
  WORD wHour;
  WORD wMinute;
  WORD wSecond;
  WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;

Now, What's WORD?

Quoting from here,

WORD

A 16-bit unsigned integer. The range is 0 through 65535 decimal.

This type is declared in WinDef.h as follows:

typedef unsigned short WORD;

So, WORD(st.*) is an unsigned short. The correct format specifier for an unsigned short is %hu. Using the wrong format specifier leads to Undefined Behavior as per the standard (n1570):

7.21.6.2 The fscanf function

[...]

  1. If a conversion specification is invalid, the behavior is undefined. 287)

Upvotes: 4

Related Questions