User avatar
PeterO
Posts: 4939
Joined: Sun Jul 22, 2012 4:14 pm

How would you ...... in C ? (+ other C discussions)

Tue Oct 18, 2016 8:28 am

I often see the phrase "The Pythonic way" use to describe a python code fragment... Perl on the other hand is know for the phrase "Ther's more than one way to do it" which was on the front of an O'rilley Perl book.
But there seems to be no similar concepts for C. So , for a bit of fun, how about posting your favourite C idioms to solve some simple problems ?

So.... Given an integer "hours" which is guaranteed to have a value in the range 0 to 23, how would you print it in the form "12 AM", or " 1 PM".

GO !

PeterO

PS Updates the title to better reflect latest content.
Last edited by PeterO on Thu May 25, 2017 6:54 am, edited 2 times in total.
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
JAVE
Posts: 36
Joined: Thu Sep 19, 2013 11:08 am

Re: How would you ...... in C ?

Tue Oct 18, 2016 8:35 am

Why would you mangle a perfectly good hour notation into the AM/PM abomination? :-P

User avatar
PeterO
Posts: 4939
Joined: Sun Jul 22, 2012 4:14 pm

Re: How would you ...... in C ?

Tue Oct 18, 2016 8:40 am

JAVE wrote:Why would you mangle a perfectly good hour notation into the AM/PM abomination? :-P
I can only assume that since you didn't provide an answer then problem too hard for you ?
PeterO
Last edited by PeterO on Wed Oct 19, 2016 1:42 pm, edited 1 time in total.
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
B.Goode
Posts: 8225
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: How would you ...... in C ?

Tue Oct 18, 2016 8:58 am

JAVE wrote:Why would you mangle a perfectly good hour notation into the AM/PM abomination? :-P
Because in the Real World 'Users' or their representatives in the project management process sometimes mandate solutions that we as developers think are sub-optimal. And the User is always right...

Also, without some other signifier to make it clear what representation is being employed an Hour field of, say, "11" is itself ambiguous.

And finally, it is just an exercise: I don't think Peter is trying to enforce a particular standard for displaying dates. The general class of problem of transforming data from an internal representation to something for display to a user is well worth study. Eg Master's courses in HCI and Design Patterns. It might be a useful 'kata' for Test Driven Design or Behaviour Driven Design.
Last edited by B.Goode on Tue Oct 18, 2016 9:22 am, edited 1 time in total.

User avatar
jeanleflambeur
Posts: 157
Joined: Mon Jun 16, 2014 6:07 am
Contact: Website

Re: How would you ...... in C ?

Tue Oct 18, 2016 9:10 am

Code: Select all

tm time_data;
time_data.tm_hour = 21;
char buffer[10];
strftime(buffer, sizeof(buffer), "%I%p", &time_data);

gregeric
Posts: 1509
Joined: Mon Nov 28, 2011 10:08 am

Re: How would you ...... in C ?

Tue Oct 18, 2016 9:14 am

Code: Select all

if (hours==0) hours=24;
printf("%d %s\n", hours%12==0?12:hours%12, hours>12?"PM":"AM");
if (hours==24) hours=0;

PiGraham
Posts: 3571
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: How would you ...... in C ?

Tue Oct 18, 2016 9:31 am

One way to do it in one line using I-line if ()?...:...:

Code: Select all

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
	for (int hours=0;hours<24;hours++)
		printf ("%2d %s\n",(hours>12)?(hours-12):(hours==0)?12:hours,(hours>=12)?"PM":"AM");

	return 0;
}

Last edited by PiGraham on Tue Oct 18, 2016 11:27 am, edited 3 times in total.

User avatar
PeterO
Posts: 4939
Joined: Sun Jul 22, 2012 4:14 pm

Re: How would you ...... in C ?

Tue Oct 18, 2016 10:01 am

I would suggest you at least make sure your answer compiles and does what the specification asked for ! :roll: And you indicate any required header files/libraries.
PeterO

I must resist temptation to "mark the homework" ..
I must resist temptation to "mark the homework" ..
I must resist temptation to "mark the homework" ..
I must resist temptation to "mark the homework" ..
:lol: :lol: :lol: :lol: :lol:
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: How would you ...... in C ?

Tue Oct 18, 2016 10:12 am

Code: Select all

if (h == 12)
    printf("%d pm", h);
else if (h >= 12 && h < 24)
    printf("%d pm", h-12);
else if (h == 0)
    printf("%d am", h+12);
else if (h >= 0 && h < 12)
    printf("%d am", h);
else
    printf ("invalid time: %d", h);
Because maintainability is always better than concise code.

OK, you twisted my arm.

Code: Select all

printf ("%d %s", (h+11)%12+1, h < 12 ? "am" : "pm");
That demonstrates classic C-style perfectly: it's concise, elegant, there's no error checking and it's incomprehensible.

PiGraham
Posts: 3571
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: How would you ...... in C ?

Tue Oct 18, 2016 10:28 am

[quote="PeterO"]I would suggest you at least make sure your answer compiles and does what the specification asked for ! :roll: And you indicate any required header files/libraries.
PeterO

Mine compiles in a console project in MSVC and outputs the required 12,1,2,3,4,5,6,7,8,9,10,11 AM, then PM.
.
I have added the include and a main() wrapper. The library could vary with system. MS default is vcrt.lib
Do you really want full boilerplate included?

I expected complaints about the poor readability of a single line, but sometime the in-line if can be useful. Not here though. Don't do that at home kids.
Last edited by PiGraham on Tue Oct 18, 2016 10:31 am, edited 1 time in total.

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: How would you ...... in C ?

Tue Oct 18, 2016 10:35 am

PiGraham wrote:
PeterO wrote:I would suggest you at least make sure your answer compiles and does what the specification asked for ! :roll: And you indicate any required header files/libraries.
PeterO

Mine compiles in a console project in MSVC and outputs the required 12,1,2,3,4,5,6,7,8,9,10,11 AM, then PM.
12 prints as 12AM ;)

PiGraham
Posts: 3571
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: How would you ...... in C ?

Tue Oct 18, 2016 10:42 am

rurwin wrote:
PiGraham wrote:
PeterO wrote:I would suggest you at least make sure your answer compiles and does what the specification asked for ! :roll: And you indicate any required header files/libraries.
PeterO

Mine compiles in a console project in MSVC and outputs the required 12,1,2,3,4,5,6,7,8,9,10,11 AM, then PM.
12 prints as 12AM ;)
Yep, I missed an = from ">=12".

As you say, "classic c style" and incomprehensible (not really, once you know the operators). I suppose PeterO is really asking for best practice rather than "classic" style, but contrasts can be interesting.

User avatar
topguy
Posts: 5668
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: How would you ...... in C ?

Tue Oct 18, 2016 10:44 am

And 0 prints as ??

PiGraham
Posts: 3571
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: How would you ...... in C ?

Tue Oct 18, 2016 10:47 am

Is use of library functions preferred?

PiGraham
Posts: 3571
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: How would you ...... in C ?

Tue Oct 18, 2016 10:48 am

topguy wrote:And 0 prints as ??
12 AM

Here's the output for 0 to 23

Code: Select all

12 AM
 1 AM
 2 AM
 3 AM
 4 AM
 5 AM
 6 AM
 7 AM
 8 AM
 9 AM
10 AM
11 AM
12 PM
 1 PM
 2 PM
 3 PM
 4 PM
 5 PM
 6 PM
 7 PM
 8 PM
 9 PM
10 PM
11 PM

User avatar
PeterO
Posts: 4939
Joined: Sun Jul 22, 2012 4:14 pm

Re: How would you ...... in C ?

Tue Oct 18, 2016 11:00 am

PiGraham wrote:
PeterO wrote:I would suggest you at least make sure your answer compiles and does what the specification asked for ! :roll: And you indicate any required header files/libraries.
PeterO
Mine compiles in a console project in MSVC and outputs the required 12,1,2,3,4,5,6,7,8,9,10,11 AM, then PM.
Don't worry, the comment wasn't aimed at you Graham.... I'll leave it to you to work out who's code dosen't compile :-)
I have added the include and a main() wrapper. The library could vary with system. MS default is vcrt.lib
Do you really want full boilerplate included?
Your's was fine, I just dropped it into my test harness and it worked, but your new version dosen't compile ! Did you try it before posting it :roll:

I expected complaints about the poor readability of a single line, but sometime the in-line if can be useful. Not here though. Don't do that at home kids.
See later comments
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

jahboater
Posts: 4596
Joined: Wed Feb 04, 2015 6:38 pm

Re: How would you ...... in C ?

Tue Oct 18, 2016 11:00 am

rurwin wrote:

Code: Select all

if (h == 12)
    printf("%d pm", h);
else if (h >= 12 && h < 24)
    printf("%d pm", h-12);
else if (h == 0)
    printf("%d am", h+12);
else if (h >= 0 && h < 12)
    printf("%d am", h);
else
    printf ("invalid time: %d", h);
Because maintainability is always better than concise code.

OK, you twisted my arm.

Code: Select all

printf ("%d %s", (h+11)%12+1, h < 12 ? "am" : "pm");
That demonstrates classic C-style perfectly: it's concise, elegant, there's no error checking and it's incomprehensible.
No error checking is needed see the question:
Given an integer "hours" which is guaranteed to have a value in the range 0 to 23
Given that, I quite like your short version. I don't normally like terse, "clever" code, but in this case its quite simple and I think there is less chance of bugs appearing in it than in your long code above. And you had to change the long version a couple of times.

Code: Select all

printf ("%d %cM", (h+11)%12+1, h < 12 ? 'A' : 'P');

User avatar
PeterO
Posts: 4939
Joined: Sun Jul 22, 2012 4:14 pm

Re: How would you ...... in C ?

Tue Oct 18, 2016 11:05 am

PiGraham wrote: As you say, "classic c style" and incomprehensible (not really, once you know the operators). I suppose PeterO is really asking for best practice rather than "classic" style, but contrasts can be interesting.
I'm more interested in the contrasts actually ! I was thinking about an example to use for explaining the "?:" operator, so my answer would have been a one liner like yours and rurwin's. But the more contrasting styles the merrier. There are no right or wrong answers , only those that work and those that don't compile :D :lol: :roll:
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

PiGraham
Posts: 3571
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: How would you ...... in C ?

Tue Oct 18, 2016 11:57 am

On the basis that reinventing the wheel is rarely time efficient here is a version using library function strftime

Code: Select all

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

void main()
{
struct tm TimeValue;

        for (TimeValue.tm_hour = 0; TimeValue.tm_hour<24;TimeValue.tm_hour++)
        {
                const size_t  maxsize=100;    // Lazy allocation of plenty of storage for the output string
                char TimeString[maxsize];
                size_t len;
                // strftime formats a tm structure representing a time
                // %I is hour in 12H format and %p is an AM, PM indicator
                len = strftime(TimeString, maxsize, "Time is : %I %p\n", &TimeValue);
                // len is length of the output string, or 0 if the buffer is too small
                if(len==0)
                    puts("Time string buffer too small\n");
                else
                    puts(TimeString);
        }
}


Last edited by PiGraham on Tue Oct 18, 2016 12:14 pm, edited 1 time in total.

User avatar
PeterO
Posts: 4939
Joined: Sun Jul 22, 2012 4:14 pm

Re: How would you ...... in C ?

Tue Oct 18, 2016 12:07 pm

PiGraham wrote:On the basis that reinventing the wheel is rarely time efficient here is a version using library function strftime
Some "cut and paste" errors had crept in there, now fixed
PeterO
Last edited by PeterO on Tue Oct 18, 2016 12:21 pm, edited 1 time in total.
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
Paeryn
Posts: 2633
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: How would you ...... in C ?

Tue Oct 18, 2016 12:16 pm

Not a nice example, but without using ?:

Code: Select all

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>

char *hour_str(int hour) {
  char *str;
  asprintf(&str, "%d %cm", hour-12*((hour>12)-(hour==0)), 'a'+(hour>11)*('p'-'a'));
  return str;
}

int main()
{
  int h;
  for(h = 0; h < 24; h++) {
    char *hstr = hour_str(h);
    printf("Hour = %d, string = %s\n", h, hstr);
    free(hstr);
  }
  return 0;
}
She who travels light — forgot something.

PiGraham
Posts: 3571
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: How would you ...... in C ?

Tue Oct 18, 2016 12:18 pm

PeterO wrote:
PiGraham wrote:On the basis that reinventing the wheel is rarely time efficient here is a version using library function strftime
Some "cut and paste" errors have crept in there.
PeterO
That's annoying. Cut and past between Edge and nano via putty doesn't work properly in either direction.
I have corrected the test in my previous post and it reads ok now, but copy and paste it back to the Pi and it gives lots of gcc errors. Maybe it's a Unicode thing.

gregeric
Posts: 1509
Joined: Mon Nov 28, 2011 10:08 am

Re: How would you ...... in C ?

Tue Oct 18, 2016 12:24 pm

If your flight lands at either midday or midnight, you would be ill-advised to arrange for me to pick you up & quote me the time as 12AM or 12PM.

User avatar
PeterO
Posts: 4939
Joined: Sun Jul 22, 2012 4:14 pm

Re: How would you ...... in C ?

Tue Oct 18, 2016 12:28 pm

Paeryn wrote:Not a nice example, but without using ?:

Code: Select all

#define _GNU_SOURCE
It works so it must be allowed but I think because (to quote the man page) "These functions are GNU extensions, not in C or POSIX. " you must lose a point or two ;)
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
PeterO
Posts: 4939
Joined: Sun Jul 22, 2012 4:14 pm

Re: How would you ...... in C ?

Tue Oct 18, 2016 12:29 pm

gregeric wrote:If your flight lands at either midday or midnight, you would be ill-advised to arrange for me to pick you up & quote me the time as 12AM or 12PM.
Reported as "Off Topic" !
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

Return to “C/C++”