function returning days of the week

S

ssylee

I need to write a function that would read in a byte that would return
a number between 1 to 7, 1 being Sunday, 2 being Monday, etc. I want
to return an actual string that says "Sunday", or "Monday", etc.
corresponding to the number. I know that the best method to implement
a lookup conversion table would be using switch(variable ) ... case
x: .... structure. However, I may need to pass an array as one of the
parameters in order to access the text itself. Is there anything
inefficient in passing a character array as a parameter based on
memory consumption on an embedded microprocessor system? Thanks.
 
R

Richard Bos

ssylee said:
I need to write a function that would read in a byte that would return
a number between 1 to 7, 1 being Sunday, 2 being Monday, etc. I want
to return an actual string that says "Sunday", or "Monday", etc.
corresponding to the number. I know that the best method to implement
a lookup conversion table would be using switch(variable ) ... case
x: .... structure. However, I may need to pass an array as one of the
parameters in order to access the text itself. Is there anything
inefficient in passing a character array as a parameter based on
memory consumption on an embedded microprocessor system? Thanks.

You can't pass arrays in C (unless you're being willfully counter-
productive by stuffing it inside a struct); what you will be passing is
a pointer to the first element. And no, that is not inefficient.

Richard
 
M

Martin Ambuhl

ssylee said:
I need to write a function that would read in a byte that would return
a number between 1 to 7, 1 being Sunday, 2 being Monday, etc. I want
to return an actual string that says "Sunday", or "Monday", etc.
corresponding to the number. I know that the best method to implement
a lookup conversion table would be using switch(variable ) ... case
x: .... structure.

How do you "know" this? I think it is just flat wrong. Check the
following code:

#include <stdio.h>

char *day_byte_to_str(int x)
{
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
return (x < 1 || x > 7) ? day[0] : day[x];
}

int main(void)
{
int which;
printf("Test of day_byte_to_str()\n");
for (which = 0; which < 9; which++)
printf("%d -> %s\n", which, day_byte_to_str(which));
return 0;
}

[Output]
Test of day_byte_to_str()
0 -> Error
1 -> Sunday
2 -> Monday
3 -> Tuesday
4 -> Wednesday
5 -> Thursday
6 -> Friday
7 -> Saturday
8 -> Error
However, I may need to pass an array as one of the
parameters in order to access the text itself. Is there anything
inefficient in passing a character array as a parameter based on
memory consumption on an embedded microprocessor system? Thanks.

You pass the address of the array, not the array. This is basic stuff.
That is cheap. Copying a string literal into the array may have some
small cost, but I can't believe that it is anything significant. If
this is the greatest inefficiency in your program (and I doubt that
considering what you "know"), then you have a very tight program indeed.
 
U

user923005

I need to write a function that would read in a byte that would return
a number between 1 to 7, 1 being Sunday, 2 being Monday, etc. I want
to return an actual string that says "Sunday", or "Monday", etc.
corresponding to the number. I know that the best method to implement
a lookup conversion table would be using switch(variable ) ... case
x: .... structure. However, I may need to pass an array as one of the
parameters in order to access the text itself. Is there anything
inefficient in passing a character array as a parameter based on
memory consumption on an embedded microprocessor system? Thanks.

There is a C FAQ on Zeller's congruence.
It is trivial to add 1 and do a table lookup.

From the C-FAQ:
20.31: How can I find the day of the week given the date?

A: Use mktime() or localtime() (see questions 13.13 and 13.14,
but
beware of DST adjustments if tm_hour is 0), or Zeller's
congruence (see the sci.math FAQ list), or this elegant code
by
Tomohiko Sakamoto:

int dayofweek(int y, int m, int d) /* 0 = Sunday
*/
{
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4,
6, 2, 4};
y -= m < 3;
return (y + y/4 - y/100 + y/400 + t[m-1] + d)
% 7;
}

See also questions 13.14 and 20.32.

References: ISO Sec. 7.12.2.3.

I'll leave the obvious bit for you.
 
S

ssylee

Thanks for all the replies. I'll reply to each suggestion
individually:

Richard Bos: What I meant passing arrays in C is passing by reference.
Martin Ambuhl: The compiler is complaining about "Too many
initializer" whenever I tried compiling lines like:
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };
user923005: I would love to use mktime() or localtime() but I'm afraid
that the development suite that I'm using is so stripped down that
they aren't supported either.
 
M

Martin Ambuhl

ssylee said:
Martin Ambuhl: The compiler is complaining about "Too many
initializer" whenever I tried compiling lines like:
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };

I'm afraid your compiler is broken. In that case, it is impossible to
offer any useful advice.
 
U

user923005

user923005: I would love to use mktime() or localtime() but I'm afraid
that the development suite that I'm using is so stripped down that
they aren't supported either.

If you can't get ahold of mktime() or localtime() how are you going to
know what the time zone is or if daylight savings time is active or
what the daylight savings time shift is or any of those other sorts of
essential things.

You can use Zeller's congruence on the raw y, m, d but it may not do
what you want if you are missing information.
 
S

ssylee

I would have to reset the clock one hour ahead or scale back one hour
manually on the real time clock that I'm programming. I forgot to
mention that this is on a microcontroller system, so a lot of the
standard C libraries are not associated with the development suite
that I'm using. It sucks, but I don't have time to start over again on
the tasks that I'm doing.
 
S

ssylee

Below shows the code so far after some thinking and collaborations on
getting around my problem.

// This function converts day of the week in number to string
void access_day(unsigned char number, char dayString[])
{
// Declaration and Initialization of Days of the Week string
char sundayArray[] = { 'S', 'u', 'n', 'd', 'a', 'y'};
char mondayArray[] = { 'M', 'o', 'n', 'd', 'a', 'y'};
char tuesdayArray[] = { 'T', 'u', 'e', 's', 'd', 'a', 'y'};
char wednesdayArray[] = { 'W', 'e', 'd', 'n', 'e', 's', 'd', 'a',
'y'};
char thursdayArray[] = { 'T', 'h', 'u', 'r', 's', 'd', 'a', 'y'};
char fridayArray[] = { 'F', 'r', 'i', 'd', 'a', 'y'};
char saturdayArray[] = { 'S', 'a', 't', 'u', 'r', 'd', 'a', 'y'};

// index lookup table of the day strings
/*uint indexArray[] = {&sundayArray, &mondayArray, &tuesdayArray,
&wednesdayArray, &thursdayArray,
&fridayArray,
&saturdayArray};
char* pDay = (char*) indexArray[0];*/

char* pIndexArray[] = {&sundayArray, &mondayArray, &tuesdayArray,
&wednesdayArray, &thursdayArray,
&fridayArray,
&saturdayArray};
char* pDay = pIndexArray[number-1];


}

However, I'm wondering if I should make dayString a pointer instead of
a char array and do this:

dayString = pIndexArray[number-1];

instead of:

char* pDay = pIndexArray[number-1];

to return the string of the actual day of the week rather than the
number. Thanks!
 
D

Default User

ssylee said:
I would have to reset the clock one hour ahead

Please quote the previous message, with the quoted material trimmed
down to the minimum necessary for reply. See the vast majority of other
posts in the newsgroup, or the Google Groups help page on the subject.




Brian
 
M

Martin Ambuhl

ssylee said:
Below shows the code so far after some thinking and collaborations on
getting around my problem.

// This function converts day of the week in number to string
void access_day(unsigned char number, char dayString[])
{
// Declaration and Initialization of Days of the Week string
char sundayArray[] = { 'S', 'u', 'n', 'd', 'a', 'y'};
etc.
These are not strings.
If you want strings, just use
char sunday[] = "Sunday";
etc.
If your compiler barfs on this, or if you are correct in your earlier
claim that
The compiler is complaining about "Too many
initializer" whenever I tried compiling lines like:
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };
then you are not using a C compiler and the language you are writing is
not C. Perhaps someone in the embedded programming newsgroup or on some
newsgroup or mailing list for the not-C compiler you are using can help you.
 
S

ssylee

ssylee said:
Below shows the code so far after some thinking and collaborations on
getting around my problem.
// This function converts day of the week in number to string
void access_day(unsigned char number, char dayString[])
{
// Declaration and Initialization of Days of the Week string
char sundayArray[] = { 'S', 'u', 'n', 'd', 'a', 'y'};

etc.
These are not strings.
If you want strings, just use
char sunday[] = "Sunday";
etc.
If your compiler barfs on this, or if you are correct in your earlier
claim that> The compiler is complaining about "Too many
initializer" whenever I tried compiling lines like:
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };

then you are not using a C compiler and the language you are writing is
not C. Perhaps someone in the embedded programming newsgroup or on some
newsgroup or mailing list for the not-C compiler you are using can help you.

Sorry for forgetting to quote the lines. I initially thought the
readers may be reading the previous messages on the thread. In the
meantime, I have posted a question on mikroC forums and hopefully will
get some help soon. Thanks for all your help.
 
P

Paul Heininger

ssylee said:
Below shows the code so far after some thinking and collaborations on
getting around my problem.

// This function converts day of the week in number to string
void access_day(unsigned char number, char dayString[])
{
// Declaration and Initialization of Days of the Week string
char sundayArray[] = { 'S', 'u', 'n', 'd', 'a', 'y'};
char mondayArray[] = { 'M', 'o', 'n', 'd', 'a', 'y'};
char tuesdayArray[] = { 'T', 'u', 'e', 's', 'd', 'a', 'y'};
char wednesdayArray[] = { 'W', 'e', 'd', 'n', 'e', 's', 'd', 'a',
'y'};
char thursdayArray[] = { 'T', 'h', 'u', 'r', 's', 'd', 'a', 'y'};
char fridayArray[] = { 'F', 'r', 'i', 'd', 'a', 'y'};
char saturdayArray[] = { 'S', 'a', 't', 'u', 'r', 'd', 'a', 'y'};

// index lookup table of the day strings
/*uint indexArray[] = {&sundayArray, &mondayArray, &tuesdayArray,
&wednesdayArray, &thursdayArray,
&fridayArray,
&saturdayArray};
char* pDay = (char*) indexArray[0];*/

char* pIndexArray[] = {&sundayArray, &mondayArray, &tuesdayArray,
&wednesdayArray, &thursdayArray,
&fridayArray,
&saturdayArray};
char* pDay = pIndexArray[number-1];


}

However, I'm wondering if I should make dayString a pointer instead of
a char array and do this:

dayString = pIndexArray[number-1];

instead of:

char* pDay = pIndexArray[number-1];

to return the string of the actual day of the week rather than the
number. Thanks!

How does your function know how many chars can fit into the passed-in
dayString buffer?
How does your function know how many chars to copy from the
pIndexArray[number-1] arrays?
How does your function return the number of chars that it filled into the
dayString?

I would use the advice that you have already been given about using pointers
to strings (character arrays that are nul char terminated). This is not
the only solution, but you have been given good advice.

Paul
 
K

Keith Thompson

ssylee said:
Martin Ambuhl: The compiler is complaining about "Too many
initializer" whenever I tried compiling lines like:
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };
[...]

Really? When I compile a source file containing just that exact
declaration, I don't get any complaints (except "warning: `day'
defined but not used" with some options). As others have said, if
your compiler rejects it, then it's not a conforming C compiler.

Normally the size of the array is inferred from the number of elements
in the initializer. If your (non-conforming) compiler doesn't do
this, changing "char *day[]" to "char *day[8]" might be a workaround;
the resulting code would still be valid C. Consult your compiler's
documentation.
 
M

merl the perl

Martin Ambuhl said:
ssylee said:
I need to write a function that would read in a byte that would return
a number between 1 to 7, 1 being Sunday, 2 being Monday, etc. I want
to return an actual string that says "Sunday", or "Monday", etc.
corresponding to the number. I know that the best method to implement
a lookup conversion table would be using switch(variable ) ... case
x: .... structure.

How do you "know" this? I think it is just flat wrong. Check the
following code:

#include <stdio.h>

char *day_byte_to_str(int x)
{
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
return (x < 1 || x > 7) ? day[0] : day[x];
}

int main(void)
{
int which;
printf("Test of day_byte_to_str()\n");
for (which = 0; which < 9; which++)
printf("%d -> %s\n", which, day_byte_to_str(which));
return 0;
}

[Output]
Test of day_byte_to_str()
0 -> Error
1 -> Sunday
2 -> Monday
3 -> Tuesday
4 -> Wednesday
5 -> Thursday
6 -> Friday
7 -> Saturday
8 -> Error
snip
Huh? The kid's asking for the real time.

Maybe the above might be a way to shoe-horn it into C. C can't find time
with both hands. If I had to write something sensitive in this respect I
would pass it to C by virtue of a language that is on a first-name basis
with computers who function as clocks.

I am also unschur of what a switch(variable ) ... caseis.
 
A

Army1987

ssylee said:
I need to write a function that would read in a byte that would return
a number between 1 to 7, 1 being Sunday, 2 being Monday, etc. I want
to return an actual string that says "Sunday", or "Monday", etc.
corresponding to the number. I know that the best method to implement
a lookup conversion table would be using switch(variable ) ... case
x: .... structure. However, I may need to pass an array as one of the
parameters in order to access the text itself. Is there anything
inefficient in passing a character array as a parameter based on
memory consumption on an embedded microprocessor system? Thanks.

You don't even need a function.
const char *wdays = { NULL, "Sunday", "Monday" /*etc.*/ }
and you can use wdays. Or even, throw away the NULL and use wdays[i-1].
 
M

Martin Ambuhl

[my reply snipped, being irrelevant to "merl the perl"'s response]
snip
Huh? The kid's asking for the real time.

There is nothing in the question about "real time". It is about a
function that will return a string representing the name of a day of the
week given a number in the range [1 ... 7]. If you cannot read
specifications better than that, go back to selling shoes.
Maybe the above might be a way to shoe-horn it into C. C can't find time
with both hands.

The above is, of course, uninformed flame-bait. Go back to selling shoes.
If I had to write something sensitive in this respect I
would pass it to C by virtue of a language that is on a first-name basis
with computers who function as clocks.

And that's not even English. Maybe you can't sell shoes, either.
 
M

Martin Ambuhl

Army1987 said:
You don't even need a function.
const char *wdays = { NULL, "Sunday", "Monday" /*etc.*/ }
and you can use wdays. Or even, throw away the NULL and use wdays[i-1].


That's wrong. And the correct declaration
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
when suggested by me three days ago was met with the reply
Martin Ambuhl: The compiler is complaining about "Too many
initializer" whenever I tried compiling lines like:
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };
 
K

Keith Thompson

Martin Ambuhl said:
Army1987 said:
You don't even need a function.
const char *wdays = { NULL, "Sunday", "Monday" /*etc.*/ }
and you can use wdays. Or even, throw away the NULL and use wdays[i-1].


That's wrong. And the correct declaration


Yes, it needs to be "const char *wdays[]".
And the correct declaration
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"

It's *a* correct declaration. Once the "[]" is added, I fail to see
why your declaration is more correct. In fact, I'd declare it as

const char *const wdays[] = ...

Whether it should be static or not depends on how it's used. Using
NULL rather than the string "Error" as an error marker seems
reasonable.
when suggested by me three days ago was met with the reply
Martin Ambuhl: The compiler is complaining about "Too many
initializer" whenever I tried compiling lines like:
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" };

Which is probably a flaw in the OP's compiler; I suggested changing
"[]" to "[8]" as a possible workaround.
 
M

Martin Ambuhl

Keith said:
Martin Ambuhl said:
Army1987 said:
You don't even need a function.
const char *wdays = { NULL, "Sunday", "Monday" /*etc.*/ }
and you can use wdays. Or even, throw away the NULL and use wdays[i-1].

That's wrong. And the correct declaration


Yes, it needs to be "const char *wdays[]".
And the correct declaration
static char *day[] =
{ "Error", "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"

It's *a* correct declaration. Once the "[]" is added, I fail to see
why your declaration is more correct.


You yourself have noted that "const char *wdays" is wrong and "const
char *wdays[]" is correct. I fail to see how in the world you can be
obtuse enough not to see that mine is more correct than Army1987's.

A more interesting question is why Army1987 would post such an obvious
error three days after more correct (despite your inconsistent claim
that you can't see why it is) answer had been posted.
 

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

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top