如何根据输入控制循环? (为什么这个会永远循环?)
我是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你那里有有趣的小程序。据我所知,有几个
问题。
PERFORM
动词有几种不同的风格(基本、TIMES、UNTIL 和 VARYING)。您尝试使用的
PERFORM UNTIIL
风格具有以下内容“railroad track”语法:
请注意,在
PERFORM
动词之后,您可以在后面编写procedure-name-1
或phrase-1
由任意数量的
imperative-statement-1
组成。这些是相互排斥的选项(即没有图中的路径允许您“环回”。一旦您通过了其中一个选项,另一个选项
不再可用。然而,
你的代码同时做这两件事!由于固有的歧义,我没想到会编译这个
在代码中(我尝试编译你的程序,幸运的是我的编译器出现错误)。
我看到的另一个问题是使用
INPUT
作为变量名。INPUT
是一个大的COBOL 保留字集
所以不能以这种方式使用(我再次希望编译器发出错误)。简单的解决方法是
在名称中添加一些内容(例如 WS-)以消除歧义。
正如 Joe 指出的,执行我认为您正在尝试的操作的典型 COBOL 方法是:
我假设
PARAGRAPH1
负责设置循环控制变量WS-INPUT
。或者(假设
PARAGRAPH2
和PARAGRAPH3
不引用WS-INPUT
并且它们被执行至少一次)
基本区别在于第一个示例是典型的 DO-WHILE 构造(在之前测试
进入循环体),第二个是典型的 DO-UNTIL 构造(始终执行 1 遍
通过循环体并在后续传递之前进行测试)。
第三种方法(过时的方法)是:
这相当于上面的第一个示例。
我不推荐这种编码风格 - 它可以追溯到 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:
Note that just after the
PERFORM
verb you can code eitherprocedure-name-1
orphrase-1
followedby an arbitrary number of
imperative-statement-1
. These are mutually exclusive options (ie. there is nopath 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 largeset 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:
I assume
PARAGRAPH1
is responsible for setting the loop control variableWS-INPUT
.Or (assuming
PARAGRAPH2
andPARAGRAPH3
do not referenceWS-INPUT
and they are executedat least once)
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:
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.
您正在将内联表演与段落表演混合在一起。很奇怪。我怀疑它只是因为您将 Cobol-74 终止符(句点)与 Cobol-85 终止符(End-Perform)混合而编译。如果您的编译器支持 End-* 范围终止符,则您不应使用句点,除非作为段落结尾,否则您可能会创建一些非常扭曲和混乱的执行路径。
您还需要管理输入的大小写折叠。
“with test after 是一个特殊的野兽。它相当于其他语言中的 do/while。但它总是可以通过启动读取并将测试放在第一位来编写。
尝试这样的事情:
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: