为什么C代码不会自动结束,而是要我按Ctrl+Z来结束执行?

huangapple go评论67阅读模式
英文:

Why does the code in c not end and forces me to press crl+z to end the execution?

问题

我已经制作了一个简单的代码来打印介于字母之间的数字的反向输出。
例如:如果我在终端上输入:
1 2 3 hello 4 5 6 end
或者通过txt文件输入到函数中,它会返回预期的值:
3 2 1
6 5 4
但它不会结束,我被迫按下ctrl+z才能再次使用终端。

#include <stdio.h>
#include <stdlib.h>

#define MAX_NUM 64

int main() {
    int num[MAX_NUM];
    int size = 0, i;
    char word[20];
    while (scanf("%d", &num[size]) != 0) {
        size++;
        while (scanf("%d", &num[size]) != 0) {
            size++;
        }
        if (scanf("%s", word) != 0 || size == MAX_NUM) {
            for (i = size - 1; i >= 0; i--) {
                if (i == 0)
                    printf("%d", num[i]);
                else
                    printf("%d ", num[i]);
            }
            printf("\n");
            size = 0;
        }
    }
    return 0;
}
英文:

I´ve made a simple code to print in reverse the numbers written between letters.
For example: if I write on the terminal:
1 2 3 hello 4 5 6 end
or enter that in the function through a txt its returning the expected values:
3 2 1\n
6 5 4\n
but it doesn´t end, Im forced to press crl+z to be able to use the trminal again.

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#define MAX_NUM 64

int main() {
    int num[MAX_NUM];
    int size = 0, i;
    char word[20];
    while (scanf(&quot;%d&quot;, &amp;num[size]) != 0) {
		size++;
		while(scanf(&quot;%d&quot;, &amp;num[size]) != 0){
			size++;
		}
        if (scanf(&quot;%s&quot;,word) != 0 || size == MAX_NUM) {
			for (i = size - 1; i &gt;= 0; i--) {
				if(i == 0)
					printf(&quot;%d&quot;, num[i]);
				else
					printf(&quot;%d &quot;, num[i]);
			}
			printf(&quot;\n&quot;);
			size = 0;
        }
    }
    return 0;
}

答案1

得分: 2

因为 scanf 无法读取你的思维。例如,当你调用 scanf("%d", &num[size]) 时,如果当前没有更多可用的数据供读取,scanf 不知道你是否打算再提供更多数据。在返回之前,它需要看到输入的结束,或错误信号,或者一个无法匹配格式的字符。在Windows中,Ctrl-Z表示在终端中运行的程序的标准输入结束。

英文:

> Why does the code in c not end and forces me to press crl+z to end the execution?

Because scanf cannot read your mind. For instance, when you call scanf(&quot;%d&quot;, &amp;num[size]) and there is not presently any more data available to read, scanf doesn't know that you don't intend ever to present any more. Before it returns, it needs to see an end-of-input or error signal or a character that it cannot match to the format. In Windows, Ctrl-Z signals end-of-input on the standard input of a program running in the terminal.

答案2

得分: 1

I'm forced to press ctrl+z to be able to use the terminal again.
然后你不能在Windows上运行。在Windows上,终端中的ctrl-z表示EOF(文件结束)。如果你的程序从scanf调用中接收到EOF,它将进入无限循环。

但是你确实写道:
我被迫按ctrl+z才能再次使用终端。
在这种情况下,你应该是在nix系统(或类似系统)上。在nix中,ctrl-z表示"suspend"(暂停)。它会还给你终端提示符,但不会结束程序。程序仍然在后台运行。运行pidof <程序名称>可以查看它。

关于你的程序有一些评论:

while(scanf(...) != 0)

几乎总是不好的(也许总是不好的)。原因是你不能使用这样的代码来捕获EOF。

更好的方法是:

while(scanf(...) == N)

其中N是你期望扫描的项目数(在你的情况下是1)。通过这样做,EOF将起作用。

scanf("%s", word)

总是不好的 - 非常不好。用户可能会溢出缓冲区。始终限制要读取的最大字符数。在你的情况下可以这样:

scanf("%19s", word)

但是,修复上述问题不会使程序在输入如下内容时结束:

1 2 3 hello 4 5 6 end

程序将调用外部(第一个)scanf("%d", &num[size]) 并永远等待,因为它不会接收到进一步的输入。

你可以通过给它两个连续的非整数输入来结束你的程序。例如:

1 2 3 hello 4 5 6 end abc

这将导致外部的scanf返回零,程序将停止。

如果你想让"end"表示"结束程序",你可以添加如下代码:

if (strcmp(word, "end") == 0) return 0;
英文:

> Im forced to press crl+z to be able to use the trminal again.

Then you can't be running on Windows. On Windows ctrl-z in a terminal means EOF (End Of File). If your program receives an EOF freom a scanf call it will enter an endless loop.

But you do write:

> Im forced to press crl+z to be able to use the terminal again.

In that case you are on a *nix system (or a similar system). On *nix ctrl-z means "suspend". It will give you the terminal prompt back but it will not end the program. The program is still there in the background. Run pidof &lt;program-name&gt; to see that.

Some comments about your program:

while(scanf(...) != 0)

is nearly always bad (perhaps always bad). The reason is that you can't catch an EOF with such code.

The better way is

while(scanf(...) == N)

where N is the number of items you expect to scan (it's 1 in your case). By doing that EOF will work.

Code like

scanf(&quot;%s&quot;,word)

is always bad - very bad. The user may overflow the buffer. Always limit the maximum number of characters to read. In your case like:

scanf(&quot;%19s&quot;,word)

However, fixing the above won't make the program end when you give input like

1 2 3 hello 4 5 6 end

The program will call the outer (first) scanf(&quot;%d&quot;, &amp;num[size]) and wait forever because it doesn't receive further input.

You can end your program by giving it two consecutive non-integer inputs. Example

1 2 3 hello 4 5 6 end abc
                      ^
                      This will cause outer scanf to return zero
                      and the program will stop

If you want "end" to mean "end the program", you can add code like:

if (strcmp(word, &quot;end&quot;) == 0) return 0;

huangapple
  • 本文由 发表于 2023年6月27日 20:00:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76564645.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定