[Techtalk] getting the time as a string in c

John Stoneham lyric.techtalk at lyrically.net
Thu Sep 29 07:00:16 EST 2005


I don't know the c time functions very well, but I can explain your error
message. Let me go through each line and give semantics.

>     int timestrsize = 10;       /* max length of time string */

Declares an int named timestrsize with value 10.

>     char *timestring;

Declares a pointer to a character (or array of characters) named timestring,
without initializing the value (this probably should say char *timestring =
NULL;).

>     char timeformat[2] = "%c";  /* format for time string */

Declares a 2-element array of characters named timeformat, with value "%c".
Note that strings in c are null-terminated; the literal "%c" requires 3
characters to store properly - %, c, and null, so this should be char
timeformat[3], or even better (since it's a string literal) char *timeformat
= "%c";.

>     const struct tm *timeptr;

Declares a pointer named timeptr, which points to a "struct tm" (i.e. an
instance of the structure named "tm"). The const here means that the
structure values can't be changed, but the pointer can. (If the pointer was
unchangeable but NOT the structure, it'd be "struct tm *const timeptr;". If
both were unchangeable, it'd be "const struct tm *const timeptr;".) Again,
this doesn't initialize the value, usually a bad sign.

>     size_t strftime(timestring, timestrsize, timeformat, timeptr);

This one's causing your error message. Your c compiler thinks this is a
function signature declaration, not a function call. The syntax of a
declaration is returnType returnName(argType argName,argType argName,...).
Which is what the above looks like, except it looks like you forgot the
'argType' bits, so the compiler complained about you forgetting the types.

> program.c:38: warning: parameter names (without types) in function
> declaration

I think what you wanted to do was:

size_t foo = strftime(timestring,timestrsize,timeformat,timeptr);

which declares a variable foo and assigns it the return value of a call to
the function. The difference is that there's a variable name and an
assignment operator.

> I think before I had "char timestring[10];" instead of "char *timestring;".
> When that was the case, gcc didn't complain and the program compiled, but
> running it produced a segmentation fault.

There's actually three things in the program that could segfault. The "char
*timestring;" you had previously declares a pointer - a placeholder which you
can point to a real string, but doesn't actually declare any memory, merely a
placeholder that can point to that memory. Declaring an actual array reserves
10 char-sized slots of memory for you. The null-terminated string issue I
mentioned above could have caused it. The most likely reason you're
segfaulting, however, is that you need to actually pass a time value for it
to convert. You declared a pointer with "const struct tm *timeptr;" but it's
never been pointed to a real value. (The reason it's marked const in the
function signature is the function declaring that it will not modify that
structure, and thus it's safe to pass a constant structure that can't be
changed.)

I think the program you are looking for is:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc,char** argv) {
   /* get time of day as a struct timeval */
   struct timeval timevalStruct;
   int iRetVal = gettimeofday(&timevalStruct,NULL);
   if(iRetVal != 0) {
      printf("Bad return value from gettimeofday\n");
      exit(1);
   }

   /* convert it to a struct tm */
   struct tm tmStruct;
   struct tm *tRetVal = localtime_r(&timevalStruct.tv_sec,&tmStruct);
   if(tRetVal == NULL) {
      printf("Bad return value from localtime_r\n");
      exit(1);
   }

   /* call strftime with the struct tm */
   const int timestrsize = 50;
   char timestring[timestrsize];
   char *timeformat = "%c";
   size_t sRetVal = strftime(timestring,timestrsize,timeformat,&tmStruct);
   if(sRetVal == 0) {
      printf("Bad return value from strftime\n");
      exit(1);
   }

   printf("%s\n",timestring);
}



More information about the Techtalk mailing list