【问题标题】:How to get a single character from a string in COBOL?如何从 COBOL 中的字符串中获取单个字符?
【发布时间】:2013-05-08 13:56:17
【问题描述】:

例如,如果一个字符串是“工作”,我必须访问第三个字符并存储它。在 C 中可以这样做:

char data[5] = "work";
char temp = data[2];

变量temp 将具有值'r'。现在我需要在 COBOL 中实现等价。

【问题讨论】:

  • 向我们展示过程部和数据部的相关代码。
  • 当您说特定字符时,您是指字符位置还是匹配字符?换句话说,如果字符串是“work”,你希望“w”返回 1,还是希望 1 返回“w”?

标签: arrays string variables cobol


【解决方案1】:

首先要了解的是,数组索引在 C 中基于零,在 COBOL 中基于 1。

接下来 COBOL 和 C 有非常不同的方式来表示字符串。在 C 中,通常存储一个字符串 作为字符数组,字符串的结尾通常使用二进制零 (null \0) 表示。 COBOL 没有这样的约定。字符串存储在指定长度的命名数据项中。这些物品通常是 在 WORKING-STORAGE 下声明并有一个与它们关联的“X”类型的图片子句(还有其他几个 PICTURE 子句的可能性,但“X”代表任何类型的字符)。例如:

01    MY-VARIABLE   PIC X(20).

名为 MY-VARIABLE 的工作存储变量声明为 20 个字符长。它可以被赋值 在PROCEDURE DIVISION中如下。

MOVE 'work' TO MY-VARIABLE

然后,您可以使用一种称为 参考修改:

DISPLAY MY-VARIABLE(3:1)

将显示 MY-VARIABLE 的第三个字符(基于 1 的索引),即 'r'。上面括号中的第一个数字 (3) 表示从变量开头的偏移量,第二个数字是从该位置开始的字符数(1)。

还有其他方法可以做到这一点,例如 REDEFINES,其中 MY-VARIABLE 可以重新定义为 20 个 1 字符单元格的数组。这 是一个有点过时的机制,所以我鼓励使用引用修改来访问部分字符串。

【讨论】:

    【解决方案2】:

    重新回答。尽管提到了“字符串”,但我认为您是在谈论可能被称为“字段”的内容,即一段数据。

    01  a-piece-of-data.
        05  first-two-bytes-of-data PIC XX.
        05  third-byte-of-data      PIC X.
        05  fourth-byte-of-data     PIC X.
    

    a-piece-of-data 是一个“组项”,它有四个字节长。 “从属”定义允许您访问四个字节中的各个字节。

    可以这样:

    01  a-piece-of-data             PIC X(4).
    01  FILLER REDEFINES a-piece-of-data.
        05  first-two-bytes-of-data PIC XX.
        05  third-byte-of-data      PIC X.
        05  fourth-byte-of-data     PIC X.
    

    可以通过“下标”来完成:

    01  a-piece-of-data.
        05  FILLER OCCURS 4 TIMES.
            10  a-byte-in-the-piece-of-data PIC X.
    

    现在,

    a-byte-in-the-piece-of-data ( 3 )
    

    引用数据的第三个字节。

    下标可以使用如图所示的文字或数据名称(您以正常方式定义的名称和存储,必须是数字,最好是二进制)或索引名称(使用 INDEXED BY,您在其中定义名称,但编译器定义存储)。

    也可以通过参考修改来完成,如 NealB 所示。

    对我来说,选择通常归结为“下一个人最清楚哪个?”。

    01  WHAREHOUSE-REF.
        05  WHAREHOUSE-CODE    PIC XX.
            88  WHAREHOUSE-HAS-LIFT VALUE "LN" "CV".
        05  WHAREHOUSE-FLOOR   PIC X.
            88  WHAREHOUSE-UPPER-FLOOR VALUE "1" "2".
        05  WHAREHOUSE-BAY     PIC X.
    
    01  W-LIFT-USAGE           PIC X.
        88  W-LIFT-USAGE-NONE  VALUE ZERO.
    
    IF WHAREHOUSE-HAS-LIFT 
    AND WHAREHOUSE-UPPER-FLOOR
        MOVE WHAREHOUSE-FLOOR TO W-LIFT-USAGE
    ELSE
        SET W-LIFT-USAGE-NONE TO TRUE
    END-IF
    PERFORM CALC-ROBOT-TIME-TO-BAY
    

    与(或者是吗?,您每次都可以随时查看手册):

    01  VAR1 PIC X(4).
    01  VAR2 PIC X.
    
    IF VAR1 (1:2) = "LN" OR "CV"
    AND VAR1 (3:1) = "1" OR "2"
        MOVE VAR1 (3:1) TO VAR2 (1:1) 
    ELSE
        MOVE ZERO TO VAR2 (1:1)
    END-IF
    PERFORM CALC-ROUTINE THROUGH CALC-ROUTINE-EXIT
    

    PS。我知道 VAR2,但根据我的经验,有多少没有使用参考修改经验的人会编写它。您还会看到 VAR2 (1:),而只需要一个普通的 VAR2。是的,所选择的名称类型似乎与参考修改密切相关且没有经验。

    【讨论】:

    • SET W-LIFT-USAGE-NONE 为 TRUE 意味着将零移至 VAR2 (1:1)?为什么在 VAR2 之后需要 (1:1)?我可以只使用 MOVE ZERO TO VAR2 吗?
    • 是的,完全正确,但是使用 SET 作为条件名称可以 100% 完全确定正在发生的事情。当然,长度为 1 的 PIC X 的 (1:1) 是不必要的,但是因为严格来说,所有参考修改都是不必要的,所以不要期望看不到它。使用参考修改的人不会以最好的方式使用它,是吗?那么,一个字节的 VAR (1:1),七个字节的 VAR (1:7),然后有人将字段更改为 8 个字节长,会发生什么...?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多