Comments please

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}
 
G

gabriel

Christopher said:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

Maybe i'm in the minority here, but isn;t that code waay more complicated
than it needs to be? If you have input guaranteed to be in a certain
format, why do you need all that complex code?

To me it seems like the programmer is trying to show how smart he is.
 
J

Jeremy Yallop

Christopher said:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

/*
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:
*/
void printdate(const char *date)
{
printf( "New date is %s-%.2s-%.2s\n", strrchr(date, '/') + 1, date, strchr(date, '/') + 1);
}

Jeremy.
 
A

Arthur J. O'Dwyer

This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

Jeremy Yallop has hit the nail on the head w.r.t. the unnecessary
complexity of this code. However, I'd just like to point out...
void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {

....that you've given a weird name to the obviously-correct magic
number (10, as in base-10), but kept in the "arbitrary" magic numbers
6 and 5, of which I can't even tell what they're supposed to be.
[And in fact, you're *not* using the 10 to mean base-10, as I
assumed upon seeing you mod'ing things by it. It's a hard-coded
string length, I think. That's just silly.]
if( !(i%mod) )

if (i%10 == 0)
*(cp++)='-';

Personally, I would not add the redundant parenthesization on
'*cp++', but perhaps some expert's MMV for some obscure reason of
which I am unaware.
*cp=date[i%mod];
}
*cp=0;

I am of the camp that believes in making the null character
visually distinct from the integer zero. *cp = '\0'. YMMV.
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

And naturally it's kind of weird to be doing I/O in a string
parsing function. Bad modularization. Even if it is only an
example, and even if you'd spawn discussions about how many ways
C has to return strings, otherwise. ;-)

HTH,
-Arthur
 
M

Martin Dickopp

Christopher Benson-Manica said:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;

`tdate' is not large enough for the destination string (including the
terminating '\0' character).

Martin
 
C

Christopher Benson-Manica

Arthur J. O'Dwyer said:
if (i%10 == 0)

Well, besides the fact that Jeremy so succinctly proved that this is
totally unnecessary anyway, isn't this a style issue? Or is what I
wrote actually incorrect?
 
C

Christopher Benson-Manica

Martin Dickopp said:
`tdate' is not large enough for the destination string (including the
terminating '\0' character).

*gape* So it isn't... thanks!!
 
S

Sean Kenwrick

Jeremy Yallop said:
Christopher said:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

/*
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:
*/
void printdate(const char *date)
{
printf( "New date is %s-%.2s-%.2s\n", strrchr(date, '/') + 1, date, strchr(date, '/') + 1);
}

Jeremy.

I like this - very clever - but it relies on 'C' calling convention of
passing arguments to functions in reverse order (but so what).

Here's my solution in the spirit of the OP's clever but obfuscated 'C'
solution:

void printdate(const char * date)
{
int mod=0xa,i;
printf("New date is ");
for(i=1+(mod>>1);i%mod!=(mod>>1);i++){
if(!(i%mod) || !(i%mod-2) && ++i) {
putchar((mod<<2)+(mod>>1));
}
putchar(*(date+i%mod));
}
}

It works... try it!

Sean
 
C

Christopher Benson-Manica

Jeremy Yallop said:
printf( "New date is %s-%.2s-%.2s\n", strrchr(date, '/') + 1, date, strchr(date, '/') + 1);

Where should I mail the check? Or is the satisfaction of coming up
with such an improvement over my "code" payment enough? ;)

(seriously, thanks!!)
 
P

pete

Sean said:
Jeremy Yallop said:
Christopher said:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

/*
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:
*/
void printdate(const char *date)
{
printf( "New date is %s-%.2s-%.2s\n",
strrchr(date, '/') + 1, date, strchr(date, '/') + 1);
}

Jeremy.

I like this - very clever - but it relies on 'C' calling convention of
passing arguments to functions in reverse order (but so what).

Since none of the arguments have side effects,
how does it rely on passing order ?
 
M

Martin Dickopp

Jeremy Yallop said:
Christopher said:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

/*
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:
*/
void printdate(const char *date)
{
printf( "New date is %s-%.2s-%.2s\n", strrchr(date, '/') + 1, date, strchr(date, '/') + 1);
}

Since the input format is predetermined, why not replace
`strrchr(date, '/') + 1' and `strchr(date, '/') + 1)' with `date + 6' and
`date + 3', respectively?

Martin
 
M

Martin Dickopp

Sean Kenwrick said:
Jeremy Yallop said:
Christopher said:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

/*
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:
*/
void printdate(const char *date)
{
printf( "New date is %s-%.2s-%.2s\n", strrchr(date, '/') + 1, date,
strchr(date, '/') + 1);
}

Jeremy.

I like this - very clever - but it relies on 'C' calling convention of
passing arguments to functions in reverse order (but so what).

There is no such convention in C, and the code doesn't make the assumption
that there is.

Martin
 
E

Eirik WS

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

(test4.c contains your function and the following main function:
int main(void) {
printdate("04-14-1989");
return 0;
}
)
$ gcc test4.c -o test4
test4.c: In function 'printdate':
test4.c:16: invalid type argument of 'unary *'
$ gcc test4.c -o test4 -Wall -W -ansi -pedantic
test4.c: In function 'printdate':
test4.c:16: warning: implicit declaration of function 'strchr'
test4.c:16: invalid type argument of 'unary *'
$ uname -a
Linux burk 2.4.18-bf2.4 #1 Son Apr 14 09:53:28 CEST 2002 i686 unknown
$ gcc --version
2.95.4
This is what I did:

void printdate( const char *date )
{
char tdate[10], *cp, *character;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
if ((character = (char *) strchr(tdate, '/')) != NULL)
*character = '-';
printf( "New date is %s\n", tdate );
}
 
D

Dan Pop

In said:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

Jeremy has shown a clever solution. Here is a trivial solution:

void printdate(const char *date)
{
char y[5], m[3], d[3];
sscanf(date, "%2s/%2s/%4s", m, d, y);
printf("New date is %s-%s-%s\n", y, m, d);
}

Dan
 
A

Arthur J. O'Dwyer

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

(test4.c contains your function and the following main function:
int main(void) {
printdate("04-14-1989");
return 0;
}
)
$ gcc test4.c -o test4
test4.c: In function 'printdate':
test4.c:16: invalid type argument of 'unary *'
$ gcc test4.c -o test4 -Wall -W -ansi -pedantic
test4.c: In function 'printdate':
test4.c:16: warning: implicit declaration of function 'strchr'
test4.c:16: invalid type argument of 'unary *'
$ uname -a
Linux burk 2.4.18-bf2.4 #1 Son Apr 14 09:53:28 CEST 2002 i686 unknown
$ gcc --version
2.95.4

When the compiler gives you an error message, you need to look at
the lines surrounding that error in the program, figure out what went
wrong, and fix it. In this case, the compiler is complaining that
it doesn't know the type of 'strchr', and the fix is to include a
prototype for that function (e.g. said:
This is what I did:

void printdate( const char *date )
{
char tdate[10], *cp, *character;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
if ((character = (char *) strchr(tdate, '/')) != NULL)

Here, by adding a cast without thinking, you have introduced
a serious bug in the function. Remove the cast. You may as well
keep the extra error-checking, though... it's not necessary
since we are told that 'date' is correctly formatted, but more
error checking usually can't hurt.
*character = '-';
printf( "New date is %s\n", tdate );
}

HTH,
-Arthur
 
S

Sean Kenwrick

Martin Dickopp said:
Sean Kenwrick said:
Jeremy Yallop said:
Christopher Benson-Manica wrote:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

/*
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:
*/
void printdate(const char *date)
{
printf( "New date is %s-%.2s-%.2s\n", strrchr(date, '/') + 1, date,
strchr(date, '/') + 1);
}

Jeremy.

I like this - very clever - but it relies on 'C' calling convention of
passing arguments to functions in reverse order (but so what).

There is no such convention in C, and the code doesn't make the assumption
that there is.

Martin

Doh! Of course your right, I missed the fact that the first call was to
strrchr() rather than strchr() and so I couldn;t quite figure out the logic
until my brain suggested that the calls must be going in the reverse order
(which still wouldn't work (damn this stupid brain!)).

Sean
 
S

Sean Kenwrick

Sean Kenwrick said:
Martin Dickopp said:
Sean Kenwrick said:
Christopher Benson-Manica wrote:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

/*
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:
*/
void printdate(const char *date)
{
printf( "New date is %s-%.2s-%.2s\n", strrchr(date, '/') + 1, date,
strchr(date, '/') + 1);
}

Jeremy.

I like this - very clever - but it relies on 'C' calling convention of
passing arguments to functions in reverse order (but so what).

There is no such convention in C, and the code doesn't make the assumption
that there is.

Martin

Doh! Of course your right, I missed the fact that the first call was to
strrchr() rather than strchr() and so I couldn;t quite figure out the logic
until my brain suggested that the calls must be going in the reverse order
(which still wouldn't work (damn this stupid brain!)).

Sean

Actually, I just thought about this again and realised I was right the first
time about the C calling convention. Check out this code:


#include <stdio.h>

void myfunc(int, int);

int main(){
int i=0;
myfunc(++i,i+=8);
}

void myfunc(int a,int b){
printf("a=%d b=%d\n",a,b);
}

Do you think it will print out a=1, b=9 or a=9, b=8 ???

Its the latter, so I should trust my brain a little more !!! (although I
agree his solution didn't rely on this calling convention)

Sean
 
S

Sean Kenwrick

Sean Kenwrick said:
Sean Kenwrick said:
Martin Dickopp said:
Christopher Benson-Manica wrote:
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:

void printdate( const char *date )
{
char tdate[10], *cp;
int mod=10, i;

cp=tdate;
for( i=6 ; i%mod != 5 ; ++i, ++cp ) {
if( !(i%mod) )
*(cp++)='-';
*cp=date[i%mod];
}
*cp=0;
*strchr( tdate, '/' )='-';
printf( "New date is %s\n", tdate );
}

/*
This function is intended to print a string guaranteed to be in the
form MM/DD/YYYY (assume <stdio.h> and <string.h> are included) as
YYYY-MM-DD:
*/
void printdate(const char *date)
{
printf( "New date is %s-%.2s-%.2s\n", strrchr(date, '/') + 1, date,
strchr(date, '/') + 1);
}

Jeremy.

I like this - very clever - but it relies on 'C' calling convention of
passing arguments to functions in reverse order (but so what).

There is no such convention in C, and the code doesn't make the assumption
that there is.

Martin

Doh! Of course your right, I missed the fact that the first call was to
strrchr() rather than strchr() and so I couldn;t quite figure out the logic
until my brain suggested that the calls must be going in the reverse order
(which still wouldn't work (damn this stupid brain!)).

Sean

Actually, I just thought about this again and realised I was right the first
time about the C calling convention. Check out this code:


#include <stdio.h>

void myfunc(int, int);

int main(){
int i=0;
myfunc(++i,i+=8);
}

void myfunc(int a,int b){
printf("a=%d b=%d\n",a,b);
}

Do you think it will print out a=1, b=9 or a=9, b=8 ???

Its the latter, so I should trust my brain a little more !!! (although I
agree his solution didn't rely on this calling convention)

Sean
To illustrate this point some more here is another version that relies on
this C calling convention of
passing arguments in reverse order:

void printdate(char *date)
{
printf( "New date is %s-%s-%s\n",
strtok(NULL,"/"),strtok(NULL,"/")-3,strtok(date,"/")+3);
}

try it, it works!

Sean
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top