Help, newbie question. Copy Long into an unsigned char array issue

This is a discussion on Help, newbie question. Copy Long into an unsigned char array issue within the C Programming forums, part of the General Programming Boards category; Hello, I am a C programming newbie. This is my first program and I have made it through quite well, ...

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    14

    Help, newbie question. Copy Long into an unsigned char array issue

    Hello,

    I am a C programming newbie. This is my first program and I have made it through quite well, researching tutorials on the web etc. I have a hurdle I just cannot figure out;

    Code:
    int main()
    {
     /* Ask for a position input */
     bool ValueOk = false;
     unsigned char Posn[4] = {0};
     unsigned char Temp[1] = {0};
     long double a;
     long b;
     int i;
     int ulIdx;
    
     do
     {
      cout << "Enter Desired Position (0.00 -> 195.00 mm):  ";
      scanf("%Lf", &a);
      if (a >=0.00 && a<= 195.00)
      {
       if (a < 0)
       {
        b = floor(a * 100);
       } else
       {
        b = ceil(a * 100);
       }
       printf("%02X", b);
       Posn[0] = b;        <---- PROBLEM
       printf("%02X", Posn[0]);
       /* Invert Order Of Bytes For abSendData */
       for (ulIdx = 0; ulIdx < 4; ++ulIdx)
       {
        Temp[ulIdx + (3 - ulIdx)] = Posn[ulIdx];
       }
       for (i=0; i<4; ++i)
       {
        Posn[i] = Temp[i];
       }
       ValueOk = true;
      }
     } while (!ValueOk);
    }
    
    
    How do I copy the variable "b" (long), represented as (4) byte values, into the Posn[0, 1, 2, 3] array? I also, want to invert the order, hence the reason for the loop above. I want to then shuffle the (4) bytes in the Posn array, as Posn[3, 2, 1, 0]. How is this done? I've been playing with sprintf, without success. Would someone be kind enough to explain this to me?

    Many thanks!

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    You'll need to mask the number with a bitwise and(&) and shift it down a number of bits to store it in a 1 byte context.

    A couple examples:

    Code:
    posn[0] = (0xff000000 & b) >> 24;
    posn[1] = (0x00ff0000 & b) >> 16;
    Last edited by Cynic; 04-21-2012 at 07:11 PM.

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    I can see what the mask is doing, but what does the " >> 24" and " >> 16" do? Is there an easy way to do the mask shifting in a loop? What happens if you have multiple array positions to fill?

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,261
    Do the shift before the mask because it results in smaller constants, in fact it makes them all the same as well:
    Code:
    posn[0] = (b >> 24) & 0xFF;
    posn[1] = (b >> 16) & 0xFF;
    ...
    If you want to put that into a loop, you need only recognise that the shift differs by exactly 8 each time.
    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"

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Quote Originally Posted by 99bobster99 View Post
    I can see what the mask is doing, but what does the " >> 24" and " >> 16" do? Is there an easy way to do the mask shifting in a loop? What happens if you have multiple array positions to fill?
    The >> operator shifts the bits left that number of bits. There is a complementary << operator that shifts right that number of bits.

    Yes, you can place it in a loop. You would need to make an array for the bits:

    Code:
    int shift_count[4] = { 24, 16, 8, 0 };
    Then you can loop through. That is one way to do it. You could also start with a predetermined number and subtract 8 for each loop iteration or start at the left most byte with a shift of zero and add eight with each iteration. Many ways to accomplish this small task.

  6. #6
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    Thank you for the lesson folks, very informative! How about the shuffling of the bytes from front to back, is there an easier way to accomplish this?

  7. #7
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    Thank you Cynic and iMalc, you guys are awesome! This worked perfectly! I see the lameness in my last question, since inverting the order of the "shift_counter" array to 0, 8, 16 and 24, reversed the order of the Hex values in my Posn array.

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,261
    If you do it that way around then your shift amount is just 8 time your loop counter, so you could remove the lookup table.
    But hey, the small lookup table will work too.
    Nice work applying some thinking to the problem.
    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"

  9. #9
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    It should be noted that your program is C++ since you are using cout. However, you seem to be reading in using scanf. Don't jumble up I/O functions from both languages, either write in C++ the C++ way or write in C the only way.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  10. #10
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    Claudiu, thank you for pointing this out! This will come in handy since I need to eventually convert this code to Linux (Fedora 13.0). I was told that as long as I keep everything in "C", it should import properly within Linux. So I am assuming, the "C++" cout command may have caused me a problem during this conversion? Is this true?

    I have another challenge I am playing with, the example above converts the "Long" integer to (4) bytes within an array. How would you go the opposite way, take the (4 bytes) within the array and turn it back into a "Long" integer? I tried using the strtol command but I keep getting a "Result Too Large" error??

  11. #11
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    C and C++ are two different languages, although C is a subset of C++ in a sense. Bottom line is if you use cout, you are in the C++ beyond C realm and your code should be posted on the C++ forum.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  12. #12
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    I want to stay in the C programming realm. I will change the commands around. Thank you for pointing that out!

    for interest sake, you guys showed me how to get the "Long" into (4) hex values within an array. How do you get an array of (4) hex values into a "Long"?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. [C]Convert Char* to Unsigned Long
    By MaSSaSLaYeR in forum C Programming
    Replies: 10
    Last Post: 11-17-2011, 05:46 AM
  2. Converting unsigned long array to unsigned char array
    By delvec28 in forum C Programming
    Replies: 2
    Last Post: 09-07-2009, 08:53 PM
  3. problem with char * and unsigned long
    By Mouse_103 in forum C++ Programming
    Replies: 4
    Last Post: 04-09-2006, 07:07 PM
  4. Splitting unsigned long (newbie)
    By dave_75 in forum C++ Programming
    Replies: 2
    Last Post: 07-03-2005, 10:06 AM
  5. How do I insert a char in an unsigned long* v?
    By Robert in forum C++ Programming
    Replies: 17
    Last Post: 07-02-2002, 04:03 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21