首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用java解析cobol s9(6)v99格式的数据

如何用java解析cobol s9(6)v99格式的数据
EN

Stack Overflow用户
提问于 2017-03-06 14:17:16
回答 2查看 4.7K关注 0票数 1

我正在以字符串的形式从服务器发送和接收产品信息,服务器以COBOLS s9(6)v99格式接收和发送产品的价格,我无法用java将给定的十进制从或转换为这种格式。

COBOL s9(6)V99格式示例:

  • 0000016H
  • 0000000{

注意事项:目前我还没有转换的实现,我正在寻找解决方案

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-06 23:19:17

建议

总体而言

  • 换个科波。如果cobol被更改为s9(6)V99 sign leading,那么在java中处理起来就容易多了。在你的例子中,这可能不是一个选择。
  • 如果您可以获得Cobol文案,请使用一个包

套餐

如果您可以获得Cobol文案,为什么不使用Cobol / Java包之一?

注意:即使您没有完整的Cobol抄写簿,也可以为这个字段设置一个Cobol抄写簿,并且仍然可以使用一个包。抄写簿将是:

代码语言:javascript
复制
   01  MY-REC.
       03 FIELD-1              PIC S9(6)V99.

你需要知道的

没有一种单一的Cobol分区十进制格式,它从编译器到编译器以及编码是什么都不一样。要解码Zoned Decimal,您确实需要知道

  • Cobol编译器
  • 服务器上使用的编码

在这种情况下,我想是

  • 运行在IBM大型机或AS400上的IBM编译器
  • 美国Ebdic (IBM037)或类似的东西(绝对不是德国EBCDIC (IBM273))

分区十进制

以分区小数表示:

  • S表示它是一个有符号的数字;该符号将是最后一个数字数字上的overpunched
  • 9表示一位数
  • V表示assumed小数位

因此,s9(6)V99是一个有符号的数字,在小数位+2后面有6个数字。

编码效果

服务器使用的encoding (字符集)决定如何表示符号数字。对于美国(和英国),Ebcdic +0/-0是{ / },但对于德国Ebcdic则不同。对于ASCII服务器来说,情况又不一样了。

Java代码

ebcdic转换代码(注意,它仍然需要根据假定的小数点进行调整):

代码语言:javascript
复制
private static int positiveDiff = 'A' - '1';
private static int negativeDiff = 'J' - '1';

private static char positive0EbcdicZoned = '{';
private static char negative0EbcdicZoned = '}';

public static String fromZoned(String numZoned) {
    String ret;
    String sign = "";
    char lastChar, ucLastChar;

    if (numZoned == null || ((ret = numZoned.trim()).length() == 0) || ret.equals("-")) {
        return "";
    }

    lastChar = ret.charAt(ret.length() - 1);
    ucLastChar = Character.toUpperCase(lastChar);


    switch (ucLastChar) {
    case 'A':
    case 'B':
    case 'C':
    case 'D':
    case 'E':
    case 'F':
    case 'G':
    case 'H':
    case 'I':
        lastChar = (char) (ucLastChar - positiveDiff);
        break;
    case 'J':
    case 'K':
    case 'L':
    case 'M':
    case 'N':
    case 'O':
    case 'P':
    case 'Q':
    case 'R':
        sign = "-";
        lastChar = (char) (ucLastChar - negativeDiff);
        break;
    default:
        if (lastChar == positive0EbcdicZoned) {
            lastChar = '0';
        } else if (lastChar == negative0EbcdicZoned) {
            lastChar = '0';
            sign = "-";
        }           
    }
    ret = sign + ret.substring(0, ret.length() - 1) + lastChar;

    return ret;
}

设置+0/-0字符

代码语言:javascript
复制
public static void setDefaultEbcidicCharacterset(String charset) {
    if (getHold(charset).isEbcdic) {
        byte[] b = {(byte) 0xC0, (byte) 0xD0};
        String s = new String(b, charset);
        if (s.length() == 2) {
            positive0EbcdicZoned = s.charAt(0);
            negative0EbcdicZoned = s.charAt(1);
        }
    }
}

派生符号(用于EBCDIC编码)的另一种方法是将符号转换回原始字节:

代码语言:javascript
复制
private static final byte HIGH_NYBLE = (byte) 0xf0;
private static final byte ZONED_NEGATIVE_NYBLE_VALUE = (byte) 0xD0;

    String Sign = "";
    byte signByte = signStr.getBytes(encoding)[0];
    if (((byte) (signByte & HIGH_NYBLE)) == ZONED_NEGATIVE_NYBLE_VALUE) {
        sign = "-";
    }
    byte lastDigitBytes = (byte) (signByte | HIGH_NYBLE);

ASCII钴

在这种情况下,它是EBCDIC。对于基于ASCII的cobols,它又是不同的。这是Ascii分区-Decimal的JRecord泛型转换类:

注:我是作者JRecord

票数 8
EN

Stack Overflow用户

发布于 2017-03-06 15:23:36

据我所见,这应该是相当简单的。这假设,这似乎是您的例子中的情况,这是一个分区十进制。

首先,你需要得到号码的标志。只需检查最后一个字符。如果它是一个非数字,那么它是负的(假设你是使用F格式的正数)。一旦你有了它,你就可以用正确的、等价的数字替换这个字符了。

现在有一个数字的字符串表示形式。

现在做吧

代码语言:javascript
复制
Integer result = Integer.valueOf(theInputString)

然后除以100,然后重新应用这个标志。您还可以在调用valueOf之前将符号添加为"-“或"+”到字符串中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42627885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档