我正在尝试从COBOL程序生成的.DAT文件中获取值。 但问题是当我尝试将数据显示到我的c ++程序时。 我得到一个奇怪的值,如15.25我得到960000。
我的问题是: 什么是导入的首选数据类型
PIC S9999V99 COMP-5 VALUE +0
and
PIC S9(7) COMP-5 VALUE +0
我的c ++代码将字节导入long
BOOL Import( LONG &nVal, INT nNumChars, FILE *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;
}
第一条记录的十六进制
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
答案 0 :(得分:2)
这是您要阅读的记录:
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
哪里
b means whitespace
zeroes are binary zeros
-- is a BINARY NUMBER COMP-5 and reversed (000003E7) == 999
所以,没有你的1525的痕迹,但也许这可能有助于你识别内容。 看看那个“999”!
HTH!
答案 1 :(得分:0)
你的问题中确实没有足够的信息来回答它。
要做的是,查看生成数据文件的程序,并在那里复制结构。
答案 2 :(得分:0)
正如先前作者所说,需要更多的信息;即哪个 Cobol编译器; Cobol Copybook (或其中的部分)将非常有用。
但是作为char数组读取并使用atol可能是错误的。
对于大多数Cobol编译器(RM Cobol不同),你会
从字节数组计算。对于一个2字节的正数,你可以
long val = byte_array [0] * 256 + byte_array [1] / * Big Ending * / long val = byte_array [0] + byte_array [1] * 256 / * little Ending * /
注意: * 256应该移位8位,但我不会重新调整C移位运算符
Pic 99V99中的V是假定的小数位,即 您需要将以下计算添加到代码
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 */
获得真正的价值。
注意:有些编辑器可以使用Cobol显示Cobol数据文件 字帖(取决于Cobol的哪个版本)。
答案 3 :(得分:0)
PIC S9(7) COMP-5 VALUE +0
COMP-5
表示该值以二进制形式存储。 (您可能需要交换字节,具体取决于平台。)S
表示字段已签名(可能是两个补码)。 9(7)
表示该字段必须具有最大值为±9999999的空间,这需要4个字节(1个符号位+ 24个值位+ 7个填充位)。因此,等效的C数据类型为int32_t
。
PIC S9999V99 COMP-5 VALUE +0
V
是一个隐含的小数位。 COBOL程序放入其中的任何内容在幕后缩放100(例如,15.25被存储为001525,16被存储为001600等)。在C ++中,你必须自己进行扩展。
我通常使用double
作为外部数据类型,但是两位小数强烈建议使用美元和美分,如果可用,则应使用小数类型。
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
这看起来像ASCII字符串014857B�␃␀␀␀␀␀␀12/42 10000
,它会建议DISPLAY
而不是COMP-5
个数字。你确定你正在查看记录的正确部分吗?