Thread: Function converting from 1-7 for days of the week to actual strings

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    222

    Function converting from 1-7 for days of the week to actual strings

    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.

  2. #2
    Registered User
    Join Date
    Nov 2007
    Location
    Bangalore, India
    Posts
    24
    How about indexing the character array conatining day strings with the values [1...7] returned in the byte.
    Code:
    char days[7][]={ "Sunday", "Monday",... "Saturday" }; // You could keep this global in .text or .rodata
    
    uByte i = ... // The byte value that you read in, assuming returns 1 to 7.
    And you return
    Code:
    return days[i - 1];

  3. #3
    Registered User
    Join Date
    Nov 2007
    Location
    Bangalore, India
    Posts
    24
    Is there anything
    inefficient in passing a character array as a parameter based on
    memory consumption on an embedded microprocessor system?
    Array would be passed as the address of location where the array starts. As long as you have a stack it wouldn't be anymore expensive than a funtion call and a parameter push.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by pankaj401 View Post
    How about indexing the character array conatining day strings with the values [1...7] returned in the byte.
    Code:
    char days[7][]={ "Sunday", "Monday",... "Saturday" }; // You could keep this global in .text or .rodata
    
    uByte i = ... // The byte value that you read in, assuming returns 1 to 7.
    And you return
    Code:
    return days[i - 1];
    That only works if days is a global variable; otherwise you're returning the address of a local variable, assuming that a function is returning that information.
    In which case, it would be more efficient to make the function take a buffer and size, do a switch and copy the appropriate string into the buffer.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Elysia View Post
    That only works if days is a global variable; otherwise you're returning the address of a local variable, assuming that a function is returning that information.
    In which case, it would be more efficient to make the function take a buffer and size, do a switch and copy the appropriate string into the buffer.
    Well it would be fine if this was the C++ forum, because the return type would then probably be std::string. However being C there's still nothing stopping us from doing it the preferred way, using a lookup table.
    Code:
    // Preconditions:
    // inDayIndex is between 1 and 7
    // outDayName points to a buffer big enough to hold at least 10 characters
    void getDayOfWeekName(int inDayIndex, char *outDayName)
    {
        static const char days[7][] =
            { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
        strcpy(outDayName, days[inDayIndex - 1]);
    }
    Don't use a switch where an explicit lookup table will work.
    A switch is not more efficient. It is at best just as efficient, provided it happens to optimise down to a jump table. You're better off implementing it directly as a table on your own.
    Last edited by iMalc; 12-31-2007 at 01:34 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Do you actually recommend the usage of static variables so that the strings won't be created everytime the function is called?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Elysia View Post
    Do you actually recommend the usage of static variables so that the strings won't be created everytime the function is called?
    Yeah something like that. It removes the need to initialise the 'days' array upon each call. See below.

    Actually I've realised that I copied a mistake from pankaj401's post. It should be:
    Code:
    void getDayOfWeekName(int inDayIndex, char *outDayName)
    {
        assert(1 <= inDayIndex && inDayIndex <= 7);
        assert(outDayName != NULL);
        static const char* const days[] =
            { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
        strcpy(outDayName, days[inDayIndex - 1]);
    }
    I even threw in a few asserts for good measure.

    If you omit the static keyword then the following additional assembly code appears in the function, in a release build:
    Code:
    00418EA3  mov         dword ptr [esp],offset string "Sunday" (426808h) 
    00418EAA  mov         dword ptr [esp+4],offset string "Monday" (426ED8h) 
    00418EB2  mov         dword ptr [esp+8],offset string "Tuesday" (426800h) 
    00418EBA  mov         dword ptr [esp+0Ch],offset string "Wednesday" (426EE0h) 
    00418EC2  mov         dword ptr [esp+10h],offset string "Thursday" (4267F4h) 
    00418ECA  mov         dword ptr [esp+14h],offset string "Friday" (4267ECh) 
    00418ED2  mov         dword ptr [esp+18h],offset string "Saturday" (426EECh)
    Last edited by iMalc; 12-31-2007 at 07:03 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  8. #8
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Thanks for all your responses. I may have been overthinking too much about using switch whereas a normal array lookup table while keeping track of the index would do.

  9. #9
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    have you considered using strftime?

    http://www.cplusplus.com/reference/c.../strftime.html

  10. #10
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    I would love to use strftime but I'm afraid it's not supported in the C programming development suite that I'm using. I would have to find a way that works well enough right now.

  11. #11
    Registered User
    Join Date
    Oct 2004
    Posts
    151
    Quote Originally Posted by stanlvw View Post
    I would love to use strftime but I'm afraid it's not supported in the C programming development suite that I'm using.
    Your development suite doesn't support ISO standardized functions. So god only knows what else it's deficient in.


    Probably a good idea to get a better development environment.

  12. #12
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    That's very likely what I'm doing for my next development project as I don't have time to start over again.

  13. #13
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Below shows the code so far after some thinking and collaborations on getting around my problem.

    Code:
    // 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:
    Code:
    dayString = pIndexArray[number-1];
    instead of:
    Code:
    char* pDay = pIndexArray[number-1];
    to return the string of the actual day of the week rather than the number.

  14. #14
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    You're not allowed to return a pointer to a local non-static variable (they'll be destroyed when the function is returned).

    You're over complicating this way too much,

    Code:
    /* returns 0 on success, else non-zero */
    int accessDay(size_t n, char * day, size_t maxLen)
    {
        const char days[7][] = {    "Sunday"
                                    "Monday",
                                    "Tuesday",
                                    "Wednesday",
                                    "Thursday",
                                    "Friday",
                                    "Saturday"
                                };
                                
        /* adjust n, since it's 1 based */
        --n;
                                
        /* error day is out of bounds */
        if(n > (sizeof(days) / sizeof(days[0])))
            return 2;
        
        strncpy(day, days[n], maxLen);
        
        /* etc */
        
        return 0;
    }
    Of course, you'll still need to add error checking -- and it's not perfect either.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by iMalc View Post
    Yeah something like that. It removes the need to initialise the 'days' array upon each call. See below.

    Actually I've realised that I copied a mistake from pankaj401's post. It should be:
    Code:
    void getDayOfWeekName(int inDayIndex, char *outDayName)
    {
        assert(1 <= inDayIndex && inDayIndex <= 7);
        assert(outDayName != NULL);
        static const char* const days[] =
            { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
        strcpy(outDayName, days[inDayIndex - 1]);
    }
    I even threw in a few asserts for good measure.
    But in case the data is static, you could just do:
    Code:
    void getDayOfWeekName(int inDayIndex, const char** outDayName)
    {
        //assert(1 <= inDayIndex && inDayIndex <= 7);
        //assert(outDayName != NULL);
        static const char* const days[] = 
            { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
    	*outDayName = days[inDayIndex - 1];
        //strcpy(outDayName, days[inDayIndex - 1]);
    }
    
    int main()
    {
    	const char* strTemp;
    	getDayOfWeekName(1, &strTemp);
    	return 0;
    }
    I can't get the asserts to work, though. If I don't comment them out, the compiler will cry out syntax error.
    The only problem is that it's read-only, but aside from that...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  3. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  4. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  5. Programming using strings
    By jlu0418 in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2006, 08:07 PM