Link to home
Start Free TrialLog in
Avatar of baileys
baileys

asked on

Converting long to a fixed length string

How do you convert a long to a string with a length of 4 and how do you convert it back to a long?

                              Sheila
Avatar of alexo
alexo
Flag of Antarctica image

Several options: sprintf(), ltoa(), atol().
Details comming...
Using sprintf():

    char buffer[20];
    long num = 1234L;
    sprintf(buffer, "%4ld", num); /* "Percent Four El Di" in case the font is not clear */

sprintf() will not cause the result to be truncated (so make sure the original long is less than 10000 but larger than -1000 if you want it to fit in 4 spaces) but will pad the value to the right with spaces.  If you want left padding (right justification), use "%-4ld".  If you want leading zeros instead, use "%04ld".

Using sscanf():

    char* string = "4567";
    long num;
    sscanf(string, "%4ld", &num);

This will convert the first four numerical characters in the string into one long.

Disregarding the length, you can use more efficient functions:

    char* string = "9876";
    long num = atol(string);

and

    char buffer[20];
    long num = 9876L;
    ltoa(num, buffer, 10); /* Calculation is decimal - base 10 */

Avatar of baileys
baileys

ASKER

I am converting Ada code to C.  I am not allowed to modify the file structures.  There are two Ada procedures that uses the "unchecked_conversion" procedure that converts one type of data to another type of data and back(without type checking or any checks) without losting the integrity of the data.  One of the Ada functions takes a string date in the format of "YYYYMMDDHHMMSS" and converts it to a long, which represent the number of seconds since Jan 1, 1970.  This long is then converted to a 4 byte string(using the "unchecked_conversion" procedure) which is stored in the database.

The second Ada procedure reverses the process.

Now, the big question is, how to do this in C?  The long HAS to fit into a 4 byte string.
                      Sheila
Avatar of ozo
/* I don't know if this stores the same string as the Ada procedure, but it's certainly unchecked */

#include <string.h>
 
char string[4];
int num=896549100;
memcpy(string,&num,4);

memcpy(&num,string,4);
printf("%d\n",num);
ASKER CERTIFIED SOLUTION
Avatar of alexo
alexo
Flag of Antarctica image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I doubt that it is a four byte string (in the sense of a text string).  Rather it is just four bytes.  In that case, there is no conversion necessary ... a long is already four characters long.

The problem is that, for string manipulation function in C, a zero byte indicates the end of the string.

However, C also includes library functinos for working with arrays of bytes.  For example, you can use strcpy to copy a null terminated string, but memcpy to copy a fixed number of bytes.

If you REALLY need to convert the long to a 'string' of for bytes. then you can say someting like this...

union LongAs3Bytes {
  long lval;
  struct {
    char byte[4];
  } array;
}

then you can say ...

  LongAs4Bytes x;
  int i;
  x.lval = 1234;
  for (i = 0; i < 4; i++) {
    char b = x.array.byte[i];
    // etc
  }

alternatively, you can simply cast
  long l = 1234;
  int i;
  char* array = (char*)l;
  for (i = 0; i < 4; i++) {
    char b = array[i];
    // etc
  }

However, I think (from your description) that you can simply read and write the long directly .. and it will be read/written as four bytes.

As for the conversion from a date format to a long, there are C library functions that will help with this .. alternatively, look at www.snippets.org for appropriate routines.

Please let me if I have understood your problem correctly and have been of any help (or can be of any more)

If so, and you wish to grade me, remember that you must reject previously proposed answers first .. or get in touch with EE customer service and request a split of points.

Roger

One thing you might want to consider is that just because the Ada program stores the data as four bytes doesn't mean that by overlapping them onto a C long variable will give you the correct information, especially if the data comes from a different operating system or compiler. Here is a prime example:

Suppose that the data was stored high-byte first. In other words, the number 00 00 00 FF might actually need to be mapped to FF 00 00 00.

This sort of stuff does come up, so if you are getting wrong answers, this might be why.

As a "worse" example, it might store bit information in reverse order. So,

Binary 10000000 00000000 00000000 01010101
Hex    8   0    0   0    0   0    5   5
Might need to be stored as:
Binary 10101010 00000000 00000000 00000001
Hex    A   A    0   0    0   0    0   1

(See how the BITS themselves are reversed?)

Just keep all this in mind. Also, are you sure your local compiler has long stored as four bytes?

Jes keeping you on your toes.

Rob
Avatar of baileys

ASKER

How do I get contact EE customer service?
>> How do I get contact EE customer service?
Post a 0-point question in the "experts exchange" area.

>> Suppose that the data was stored high-byte first
The "endianness" rikonigsberg refers to is dependent only on the processor, not programming language, compiler or OS.

>> As a "worse" example, it might store bit information in reverse order.
Never!

>> >> Suppose that the data was stored high-byte first
>> The "endianness" rikonigsberg refers to is dependent only on >> the processor, not programming language, compiler or OS.
>> 
>> >> As a "worse" example, it might store bit information in
>> reverse order.
>> Never!  

Perhaps. Like I said, I'm just throwing out a warning just in case the data did come from another source, and a straight mapping doesn't seem to work. Though it might be the case that pure reversal of the bits, reversal of the bytes could occur because the data could come from being processed on another processor. When I was referring to separate OSes, I was not referring to Win95 vs WinNT, but rather varying Unix operating systems. Details are sketchy off the top of my head, but there you go.

And yes, I couldn't remember the name "endian" :)
And the autograder hits again!
Gees .. that autograder is a busy chap !! :-)