开发者

Data conversion from a .DAT file generated from COBOL

开发者 https://www.devze.com 2023-02-11 08:35 出处:网络
I am trying to get a value from a .DAT file generated by a COBOL program. But the problem is when I try to display the data to my c++ program.

I am trying to get a value from a .DAT file generated by a COBOL program. But the problem is when I try to display the data to my c++ program. I get a weird value like for 15.25 i get 960000.

My question is: What's the preferred data type to import

PIC  S9999V99  COMP-5  VALUE +0

and

PIC  S9(7)     COMP-5  VALUE +0

My c++ code to import bytes to long

BOOL Import( LONG &nVal, INT nNumChars, FI开发者_运维百科LE *pFile )
{
   char strVal[10];

   for ( int n = 0; n < (nNumChars); n++ )
   {
      if ( fread( &strVal[n], 1, 1, pFile ) != 1 )
      {
         return FALSE;
      }
   }

   strVal[n] = NULL;

   nVal = atol(strVal);

   return TRUE;
}

Hex of the first record

30 31 34 38 35 37 42 E7    03 00 00 00 00 00 00 31
32 2F 34 32 20 20 31 30    30 30 30 20 20 20 20 20
20 20 20 20 20 20 20 20


This is the record you are trying to read:

  0  1  4  8  5  7  B --    -- -- --  z e r o e s 1    2  / 4  2   b  b  1  0

 30 31 34 38 35 37 42 E7    03 00 00 00 00 00 00 31   32 2F 34 32 20 20 31 30 
 ///////////////////////////////////////////////////////////////////////////////    
  0  0  0  b  b  b  b  b     b  b  b  b  b  b  b  b  

 30 30 30 20 20 20 20 20    20 20 20 20 20 20 20 20 

Where

b means whitespace  

zeroes are binary zeros

-- is a BINARY NUMBER COMP-5 and reversed (000003E7) == 999

So, no trace of your 1525, but perhaps this may help you to identify the contents. Look at that "999"!

HTH!


There really isn't enough information in your question to answer it.

The thing to do, is look at the program that generated the data file, and replicate the structures in there.


As previously authors have stated, more inormation is needed; namely which Cobol Compiler; and the Cobol Copybook (or portion there of) would be useful.

But Reading in as a char array and using atol is probably wrong.

For most Cobol compilers (RM Cobol is different) you would

  • Read as byte array
  • Calculate from the byte array. For a 2 byte positive number you could

    long val = byte_array[0] * 256 + byte_array[1] /* Big Ending */ long val = byte_array[0] + byte_array[1] * 256 /* little Ending */

Note: the * 256 should be shift 8 bits but I do not rember the C shift operators


The V in Pic 99V99 is an assumed decimal place i.e. You will need to add the following calculation to the code

 double ret_val = long_val / 10      /* if  pic p(?)V9 */
 double ret_val = long_val / 100     /* if  pic p(?)V99 */
 double ret_val = long_val / 1000    /* if  pic p(?)V999 */
 double ret_val = long_val / 10000   /* if  pic p(?)V9990 */

to get the real Value.

Note: There are some editors that can display Cobol Data Files using a Cobol Copybook (Depends which version of Cobol though).


PIC S9(7) COMP-5 VALUE +0

The COMP-5 means that the value is stored in binary. (You may need to swap bytes, depending on platform.) The S means the field is signed (probably two's complement). The 9(7) means the field must have room for values up to ±9999999, which requires 4 bytes (1 sign bit + 24 value bits + 7 padding bits). So the equivalent C data type is int32_t.

PIC S9999V99 COMP-5 VALUE +0

V is an implicit decimal place. Anything a COBOL program puts in it gets scaled by 100 behind the scenes (e.g., 15.25 gets stored as 001525, 16 gets stored as 001600, etc.). In C++, you'll have to do this scaling yourself.

I'd normally use double for the external data type, but two decimal places strongly suggests dollars and cents, for which you should use a decimal type if one is available.

30 31 34 38 35 37 42 E7    03 00 00 00 00 00 00 31
32 2F 34 32 20 20 31 30    30 30 30 20 20 20 20 20
20 20 20 20 20 20 20 20

This looks like the ASCII string 014857B�␃␀␀␀␀␀␀12/42 10000, which would suggest DISPLAY rather than COMP-5 numbers. Are you sure you're looking at the right part of the record?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号