Thread: converting unsigned char to char* for concatenation

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    204

    converting unsigned char to char* for concatenation

    Hi I have a function that finds my mac address, I am trying to store it in a char * variable.
    This is my function to display it:
    Code:
    void PrintMACaddress (unsigned char *addr)
    {
        int i;
        unsigned char * macaddress;
        char temp[80];
       for (i = 0; i < 6; i++)
       {
        printf("%x:", *addr);
        sprintf(temp[i], "%x", *addr++);
          //strcat(macaddress, *addr);
       }
       printf("%s\n", temp);
    
    }
    So I can roll through the 6 parts of the mac address just fine, using the printf statement and outputting it in the hex format, however I cant get it to sprintf properly, and my attempt at using strcat crashes the console. I would like to return a char * if possible.

    Any help greatly appreciated.
    Thanks

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    There are lots of problems, but mainly you need to keep track of how many characters were printed, so that you can fix temp for the next iteration.

    Code:
    char temp[80];
    char *cs = temp;
    int used = 0;
    int i;
    for (i = 0; i < 6; i++) {
       sprintf(cs, "%x%n", *addr++, &used);
       cs += used;
    }
    Last edited by whiteflags; 11-18-2013 at 03:49 PM. Reason: Actually it would be a bad idea to use temp directly

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    why not to check return value of sprintf? %n usage in this case is overkill IMHO
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    Hi Sorry for my confusion, I have changed the code to:

    Code:
        int i = 0;
    char temp[25];
    char *cs = temp;
    int used = 0;
    do {
       sprintf(cs, "%x", *addr++);
        printf("%s", cs);
       cs += used;
       i++;
       if( i < 6){
       printf(":");
       }
    }while (i < 6);
    
    printf(" cs: %s\n", cs);
    the printf occuring inside the loop displays the correct thing, i.e cs temporarily holds the correct part of my mac address, however I cannot seem to get it to reset to the beginning of temp so that I can display the mac address after the loop - i.e cs or temp holds the entire mac address that I can then return to the method that called it.
    I tried doing something like:
    Code:
    *cs = temp;
    for (i = 0; i < 25; i++){
    printf("\n%s\n", cs++);
    }
    but that crashes the terminal,
    so does
    Code:
    printf("\n%s\n", temp);
    and so does even looping through the temp array displaying each character.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Your sprintf:
    Code:
    sprintf(cs, "%x", *addr++);
    whiteflags' sprintf:
    Code:
    sprintf(cs, "%x%n", *addr++, &used);
    Notice anything different?

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    So this gives me:
    Code:
    int PrintMACaddress (unsigned char *addr)
    {
        int i = 0;
    char temp[25];
    char *cs = temp;
    int used = 0;
    do {
       sprintf(cs, "%x%n", *addr++, &used);
        printf("%s", cs);
       cs += used;
       i++;
       if( i < 6){
       printf(":");
       }
    }while (i < 6);
    printf(" cs: %s\n", cs);
    
    
    return 1;
    
    }
    cs: 46

    The printf in the while gives the right thing which tells me at the time cs is the right character. How do I move it back so that the printf outside the while loop is back at the beginning of the mac address?

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by a.mlw.walker View Post
    The printf in the while gives the right thing which tells me at the time cs is the right character. How do I move it back so that the printf outside the while loop is back at the beginning of the mac address?
    You moved cs through the array (by doing cs += used), so it no longer points to the start of the sprintf'ed MAC address. You already have a pointer to the beginning of the sprintf'ed MAC address however, so just print that. Yes, I'm intentionally being vague, I want you to give a little thought to what your code is doing (and should be doing), rather than just copy-pasting whatever we post here.

  8. #8
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    Why don't you just do this?:
    Code:
    #include <stdio.h>
    
    int printmac(const unsigned char ptr[6])
    {
    	return printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
    		      ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
    }
    Last edited by Barney McGrew; 11-19-2013 at 03:49 PM.
    i dont believe in competition in da field of cboard posts, u see, i believe in a collection of posts each 2 be admired for der own personal statement. when in doubt, ask Willy!

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by vart View Post
    why not to check return value of sprintf? %n usage in this case is overkill IMHO
    Selecting one option among two that do the same thing is not overkill.

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    204
    So I see what you mean now Andruil463, in theory:

    Code:
    int PrintMACaddress (unsigned char *addr)
    {
        int i = 0;
    char temp[25];
    char *cs = temp;
    int used = 0;
    do {
       sprintf(cs, "%x:%n", *addr++, &used);
        //printf("%s", cs);
       cs += used;
       i++;
    }while (i < 6);
    *cs = temp;
    printf("cs: %s\n", cs);
    return 1;
    
    }
    used is keeping tabs on how many characters have been printed and therefore moves cs along that many places in the array temp. cs starts at the beginning of temp on this line:

    *cs = temp;
    so by my understanding I should be able to set cs back to *cs = temp; and then print cs again.
    However that outputs:
    cs: 46

    So Im struggling to understand how to set cs back to the beginning to print it out completely.

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    *cs affects the character pointed to by cs. If you want to move the pointer itself, you have to assign to cs.

  12. #12
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You need to assign cs to temp if you want to use cs to print. But you don't need to do that. cs was not the variable I was referring to.

    What variable contains the MAC address (i.e. where did you sprintf it)?
    Do you have a pointer to the beginning of that array?
    What do you get if you use the name of an array without any [ ] brackets?

  13. #13
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    "used" is declared as 0 and never changes from 0

    Code:
    int used = 0;
    ...
    cs += used;
    Therefore cs never changes from one loop to the next.
    Fact - Beethoven wrote his first symphony in C

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Click_here View Post
    "used" is declared as 0 and never changes from 0

    Code:
    int used = 0;
    ...
    cs += used;
    Therefore cs never changes from one loop to the next.
    used is set by the line
    Code:
    sprintf(cs, "%x%n", *addr++, &used);

  15. #15
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Thanks - I've never seen this used before

    I'd be more inclined to use += sizeof(*addr) in this example, but I can see how it would be useful on with larger problems.
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 07-24-2012, 10:41 AM
  2. Replies: 2
    Last Post: 10-06-2009, 09:37 AM
  3. Converting unsigned long array to unsigned char array
    By delvec28 in forum C Programming
    Replies: 2
    Last Post: 09-07-2009, 08:53 PM
  4. Converting unsigned char[] to char[]
    By Maragato in forum C Programming
    Replies: 8
    Last Post: 09-04-2006, 08:24 PM
  5. unsigned char vs signed char and range of values
    By Silvercord in forum C++ Programming
    Replies: 5
    Last Post: 01-22-2003, 01:30 PM