如何根据输入控制循环? (为什么这个会永远循环?)

发布于 2024-12-11 19:38:11 字数 388 浏览 0 评论 0原文

我是 COBOL 新手,只是想知道我正在发生的一些奇怪的事情。我想创建一个循环,遍历并执行 3 个段落,直到用户在第一段中提供的输入为“否”。

有什么方法可以使用此输入,或者我是否必须更改周围的所有内容,以便在执行第一段之前给出输入?现在我的循环看起来像:

PERFORM PARAGRAPH1 WITH TEST AFTER UNTIL INPUT = "no"
     PERFORM PARAGRAPH2
     PERFORM PARAGRAPH3
END-PERFORM.

目前它只是不断循环并且永远不会结束,正如您可以猜到的那样,这是一个问题。我想我可能还没有完全理解 COBOL 的范围,这是我第一次实际尝试 COBOL。

非常感谢任何帮助:)

I'm new to COBOL and just wondering about some weird things I have going on. I want to make a loop that goes through and executes 3 paragraphs until the input provided by the user in the first paragraph is "no".

Is there any way I can use this input or do I have to change everything around so that the input is given before the first paragraph is executed? Right now my loop looks like:

PERFORM PARAGRAPH1 WITH TEST AFTER UNTIL INPUT = "no"
     PERFORM PARAGRAPH2
     PERFORM PARAGRAPH3
END-PERFORM.

Currently it just keeps looping and never ends, which as you can guess is a problem. I think I may just not fully understand the scope of COBOL yet, this is my first actual attempt at COBOL.

Any help is really appreciated :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陪我终i 2024-12-18 19:38:11

你那里有有趣的小程序。据我所知,有几个
问题。

PERFORM 动词有几种不同的风格(基本、TIMES、UNTIL 和 VARYING)。
您尝试使用的 PERFORM UNTIIL 风格具有以下内容
“railroad track”语法:

  __________________________________________________________________________________________________ 
 |                                                                                                  |
 | >>__PERFORM__ _procedure-name-1__ _______________________________ __| phrase 1 |_ ____________>< |
 |              |                   |_ _THROUGH_ __procedure-name-2_|               |               |
 |              |                     |_THRU____|                                   |               |
 |              |_| phrase 1 |__ ________________________ __  END-PERFORM___________|               |
 |                              |_imperative-statement-1_|                                          |
 |                                                                                                  |
 | phrase 1:                                                                                        |
 | |__ ____________________________ __UNTIL__condition-1__________________________________________| |
 |    |_ ______ __TEST__ _BEFORE_ _|                                                                |
 |      |_WITH_|        |_AFTER__|                                                                  |
 |                                                                                                  |
 |__________________________________________________________________________________________________|

请注意,在 PERFORM 动词之后,您可以在后面编写 procedure-name-1phrase-1
由任意数量的imperative-statement-1组成。这些是相互排斥的选项(即没有
图中的路径允许您“环回”。一旦您通过了其中一个选项,另一个选项
不再可用。然而,
你的代码同时做这两件事!由于固有的歧义,我没想到会编译这个
在代码中(我尝试编译你的程序,幸运的是我的编译器出现错误)。

我看到的另一个问题是使用 INPUT 作为变量名。 INPUT 是一个大的
COBOL 保留字集
所以不能以这种方式使用(我再次希望编译器发出错误)。简单的解决方法是
在名称中添加一些内容(例如 WS-)以消除歧义。

正如 Joe 指出的,执行我认为您正在尝试的操作的典型 COBOL 方法是:

    PERFORM PARAGRAPH1
    PERFORM UNTIL FUNCTION LOWER-CASE (WS-INPUT) = 'no'
       PERFORM PARAGRAPH2
       PERFORM PARAGRAPH3
       PERFORM PARAGRAPH1
    END-PERFORM

我假设 PARAGRAPH1 负责设置循环控制变量 WS-INPUT

或者(假设 PARAGRAPH2PARAGRAPH3 不引用 WS-INPUT 并且它们被执行
至少一次)

    PERFORM WITH TEST AFTER UNTIL FUNCTION LOWER-CASE (WS-INPUT) = 'no'
       PERFORM PARAGRAPH2
       PERFORM PARAGRAPH3
       PERFORM PARAGRAPH1
    END-PERFORM

基本区别在于第一个示例是典型的 DO-WHILE 构造(在之前测试
进入循环体),第二个是典型的 DO-UNTIL 构造(始终执行 1 遍
通过循环体并在后续传递之前进行测试)。

第三种方法(过时的方法)是:

       PERFORM PARAGRAPH1
       PERFORM PARAGRAPHS UNTIL LOWER-CASE (WS-INPUT) = 'no'

 PARAGRAPHS.
       PERFORM PARAGRAPH2
       PERFORM PARAGRAPH3
       PERFORM PARAGRAPH1
       .

这相当于上面的第一个示例。
我不推荐这种编码风格 - 它可以追溯到 30 年前的工作方式
或者更多年前。

Interesting little program you have there. As I see it there are a few
problems.

The PERFORM verb comes in a few different flavours (basic, TIMES, UNTIL and VARYING).
The PERFORM UNTIIL flavour, the one you are trying to use, has the following
'railroad track' syntax:

  __________________________________________________________________________________________________ 
 |                                                                                                  |
 | >>__PERFORM__ _procedure-name-1__ _______________________________ __| phrase 1 |_ ____________>< |
 |              |                   |_ _THROUGH_ __procedure-name-2_|               |               |
 |              |                     |_THRU____|                                   |               |
 |              |_| phrase 1 |__ ________________________ __  END-PERFORM___________|               |
 |                              |_imperative-statement-1_|                                          |
 |                                                                                                  |
 | phrase 1:                                                                                        |
 | |__ ____________________________ __UNTIL__condition-1__________________________________________| |
 |    |_ ______ __TEST__ _BEFORE_ _|                                                                |
 |      |_WITH_|        |_AFTER__|                                                                  |
 |                                                                                                  |
 |__________________________________________________________________________________________________|

Note that just after the PERFORM verb you can code either procedure-name-1 or phrase-1 followed
by an arbitrary number of imperative-statement-1. These are mutually exclusive options (ie. there is no
path in the diagram allowing you to 'loop back'. Once you pass through one of these options the other
is no longer available. However,
your code is doing both! I would not have expected this to compile due to the ambiguity inherent
in the code (I tried compiling your program and thankfully my compiler issues an error).

The other problem I see is the use of INPUT as a variable name. INPUT is one of a large
set of COBOL reserved words
so cannot be used this way (again I would expect the compiler to issue an error). The simple fix is to
add something to the name (eg. WS-) to disambiguate it.

As Joe pointed out, the typical COBOL way to do what I think you are attempting is:

    PERFORM PARAGRAPH1
    PERFORM UNTIL FUNCTION LOWER-CASE (WS-INPUT) = 'no'
       PERFORM PARAGRAPH2
       PERFORM PARAGRAPH3
       PERFORM PARAGRAPH1
    END-PERFORM

I assume PARAGRAPH1 is responsible for setting the loop control variable WS-INPUT.

Or (assuming PARAGRAPH2 and PARAGRAPH3 do not reference WS-INPUT and they are executed
at least once)

    PERFORM WITH TEST AFTER UNTIL FUNCTION LOWER-CASE (WS-INPUT) = 'no'
       PERFORM PARAGRAPH2
       PERFORM PARAGRAPH3
       PERFORM PARAGRAPH1
    END-PERFORM

The basic difference is that the first example is a typical DO-WHILE construct (test before
entering loop body) and the second is a typical DO-UNTIL construct (always execute 1 pass
through the loop body and test before subsequent passes).

A third way, outdated method, would be:

       PERFORM PARAGRAPH1
       PERFORM PARAGRAPHS UNTIL LOWER-CASE (WS-INPUT) = 'no'

 PARAGRAPHS.
       PERFORM PARAGRAPH2
       PERFORM PARAGRAPH3
       PERFORM PARAGRAPH1
       .

This is equivalent to the first example above.
I do not recommend this coding style - it dates back to the way things were done 30
or more years ago.

无需解释 2024-12-18 19:38:11

您正在将内联表演与段落表演混合在一起。很奇怪。我怀疑它只是因为您将 Cobol-74 终止符(句点)与 Cobol-85 终止符(End-Perform)混合而编译。如果您的编译器支持 End-* 范围终止符,则您不应使用句点,除非作为段落结尾,否则您可能会创建一些非常扭曲和混乱的执行路径。

您还需要管理输入的大小写折叠。

“with test after 是一个特殊的野兽。它相当于其他语言中的 do/while。但它总是可以通过启动读取并将测试放在第一位来编写。

尝试这样的事情:

Perform Paragraph1
Perform until function lower-case(INPUT) = "no"
    Perform Paragraph2
    Perform Paragraph3
    Perform Paragraph1
End-Perform

You are mixing the inline perform with the paragraph perform. Very odd. I suspect it only compiled because you mixed Cobol-74 terminators (the period) with Cobol-85 terminators (End-Perform). If your compiler supports the End-* scope terminators, you should never use a period except as the end of a paragraph or you can create some very twisted and confusing execution paths.

You also need to manage case folding on your input.

The "with test after is a special beast. It is the equivalent of a do/while in other languages. But it can always be written with a priming read and putting the test first.

Try something like this:

Perform Paragraph1
Perform until function lower-case(INPUT) = "no"
    Perform Paragraph2
    Perform Paragraph3
    Perform Paragraph1
End-Perform
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文