奇怪的终端显示故障在C语言,Ubuntu

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

Wierd terminal display glitch in c, Ubuntu

问题

当我运行第一个代码并在每个打印语句的末尾添加"\n"时,它会给我期望的输出,即在num等于35的情况下生成的序列:

生成的序列:
35
106
53
160...

生成Collatz序列的代码:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

int main(int argc, char* argv[])
{
    int fd[2], fd1[2], num = atoi(argv[1]), id = getpid();

    printf("\n接收到的数字:%d\n", num);

    if(num > 0)
    {
        printf("生成的序列:\n");

        while(num > 1)
        {
            pipe(fd);
            pipe(fd1);

            if(fork()) //父进程
            {
                printf("%d \n", num);
                int n;
                close(fd[0]); //关闭读端
                close(fd1[1]); //关闭写端

                write(fd[1], &num, sizeof(num));
                wait(NULL);
                read(fd1[0], &n, sizeof(n));

                num = n;

                close(fd[1]);
                close(fd1[0]);

                if(num == 1) {
                    printf("1\n");
                    exit(0);
                }
            }

            else //子进程
            {
                int n;
                close(fd[1]); //关闭写端
                close(fd1[0]); //关闭读端

                read(fd[0], &n, sizeof(n));

                if(n%2 == 0)
                    n /= 2;

                else
                    n = 3*n+1;

                write(fd1[1], &n, sizeof(n);

                close(fd1[1]);
                close(fd[0]);
                exit(0);
            }
        }
    }

    else {
        printf("\n错误:数字应该是正数!!\n");
        exit(1);
    }

    return 0;
}

但问题是,如果我将打印行从

printf("%d \n", num);

更改为

printf("%d, ", num);

我的输出会重复,即

对于n=35,将会打印:

序列:35 序列:35, 106 序列:35, 106, 53 序列:35, 106, 53, 160...

虽然在新行上打印可以解决重复问题,但我不想在新行上打印序列中的每个数字。

英文:

When I run the first code it with "\n" at the end of every print statement it gives me the expected output which is in case of num == 35

The generated sequence:
35
106
53
160... 

code to generate collatz sequence:

#include&lt;stdlib.h&gt;
#include&lt;stdio.h&gt;
#include&lt;unistd.h&gt;
#include&lt;sys/wait.h&gt;
#include&lt;sys/types.h&gt;
int main(int argc, char* argv[])
{
int fd[2], fd1[2], num = atoi(argv[1]), id = getpid();
printf(&quot;\nRecieved number: %d\n&quot;, num);
if(num &gt; 0)
{
printf(&quot;The generated sequence: \n&quot;);
while(num &gt; 1)
{   
pipe(fd);
pipe(fd1);
if(fork()) //parent process
{
printf(&quot;%d \n&quot;, num);
int n;
close(fd[0]); //closing read end..
close(fd1[1]); //closing write end..
write(fd[1], &amp;num, sizeof(num));
wait(NULL);
read(fd1[0], &amp;n, sizeof(n));
num = n;
close(fd[1]);
close(fd1[0]);
if(num == 1) {
printf(&quot;1\n&quot;);
exit(0);
}
}
else    //child process
{
int n;
close(fd[1]); //closing write end..
close(fd1[0]); //closing read end..
read(fd[0], &amp;n, sizeof(n));
if(n%2 == 0)
n /= 2;
else   
n = 3*n+1;
write(fd1[1], &amp;n, sizeof(n));
close(fd1[1]);
close(fd[0]);
exit(0);
}
}
}
else {
printf(&quot;\nERROR: number should be positive!!\n&quot;);
exit(1);
}
return 0;
}

...But the problem is if I change the printing line

printf(&quot;%d \n&quot;, num);

to

printf(&quot;%d, &quot;, num);

my output will have repetitions i.e.

it will print:
with n=35

sequence: 35 sequence: 35, 106 sequence: 35, 106, 53 sequence: 35, 106, 53, 160...

Although printing on new line fixes the repetition problem, I don't want to print every number of sequence on new line.

答案1

得分: 6

不带换行字符,输出保留在程序的缓冲区中。当程序分叉时,缓冲区会与程序的其余部分一起复制。最终,父进程和子进程都会写入更多的输出,包括缓冲区中的内容。因此,输出会出现多次。

您可以通过在分叉之前立即放置 fflush(stdout); 来消除缓冲区内容的复制。刷新缓冲区(位于执行进程内部)会将其内容写入流(位于执行进程外部)并将其清空。

英文:

Without a newline character, the output remains in the program‘s buffer. When the program forks, the buffer is duplicated along with the rest of the program. Eventually, both the parent and the child write more output, including what was in the buffer. So the output appears multiple times.

You can eliminate this duplication of the buffer contents by flushing the buffer forking. Put fflush(stdout); immediately before if (fork()). Flushing the buffer (which is inside the executing process) writes its contents to the stream (which is outside the executing process) and empties it.

huangapple
  • 本文由 发表于 2023年3月3日 22:02:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628063.html
匿名

发表评论

匿名网友

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

确定