Scanf在命名管道程序上读取ctrl + c

问题描述

我正在尝试使用2 C程序(读和写)制作命名管道或FIFO。这两个程序都在while(1)循环上运行。 按ctrl + c时应终止这些程序,但是当我在 write 程序上按ctrl + c时,它仍会向 read 程序发送一些信息。如果我输入普通数字,它可以正常工作,但是当我在 write 程序上按ctrl + c终止时,它会将这个随机数提供给 read 程序

#normal numbers shows:
BMI: 16.1,Overweight

#on ctrl+c input:
BMI = 165534.6 (some random numbers)

这是编写程序的代码

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int fd,fd1,fd2;
    
    //FIFO file path
    char * myfifo = "/tmp/myfifo";

    mkfifo(myfifo,0666);

    float weight,height,bmi = 0;
    char arr1[80];
    while(1)
    {
        //open
        fd = open(myfifo,O_WRONLY);
        fd1 = open(myfifo,O_WRONLY);
        fd2 = open(myfifo,O_WRONLY);

        printf("Name            : ");
        scanf("%[^\n]",arr1);
        getchar();
        write(fd,arr1,strlen(arr1)+1);
        close(fd);
        
        printf("Body Weight in kg    : ");
        scanf("%f",&weight);
        getchar();
        write(fd1,&weight,sizeof(weight));
        printf("%f\n",weight);
        close(fd1);

        printf("Body Height in cm    : ");
        scanf("%f",&height);
        getchar();
        printf("\n---------------------------\n\n");
        write(fd2,&height,sizeof(height));
        printf("%f\n",height);
        close(fd2);

    }
    return 0;
}

这是 read 程序的代码,它会进行while(1)循环

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int fd,fd2;
    char * myfifo = "/tmp/myfifo";
    mkfifo(myfifo,0666);
    float weight,bmi = 0;
    char str1[80];
    while(1)
    {
        //First open in read only and read
        fd = open(myfifo,O_RDONLY);
        fd1 = open(myfifo,O_RDONLY);
        fd2 = open(myfifo,O_RDONLY);
        read(fd,str1,80);
        read(fd1,sizeof(weight));
        read(fd2,sizeof(height));
        
        height = (height / 100);
        
        bmi = weight / (height * height);

        //Print the read string and close
        printf("%s BMI : %.1f\n",bmi);
        close(fd);
        close(fd1);
        close(fd2);

        if(bmi < 18.5)
        {
            printf("Details = Underweight\n");
        }
        else if(bmi >= 18.5 && bmi <= 22.9)
        {
            printf("Details = normal\n");
        }
        else if(bmi >= 23.0 && bmi <= 24.9)
        {
            printf("Details = Overweight\n");
        }
        else if(bmi >= 25.0 && bmi <= 29.9)
        {
            printf("Details = Obese I (Obesitas Class I)\n");
        }
        else
        {
            printf("Details = Obese II (Obesitas Class II)\n");
        }

    }
    return 0;
}

所以,我想知道是否有办法使ctrl + c终止这两个进程?因此,按下cttrl + c后,写入程序将不会发送任何内容。我认为发生此问题是因为 read 程序即使按ctrl + c也会继续从 write 中读取某些输入。

解决方法

这是因为您没有检查read()可能在阅读器中返回0。因此,当它返回0(读取的0个字符)时,您将显示缓冲区中的所有垃圾。当read()返回0时,您应该终止读取器,因为这意味着另一侧已关闭(写入器退出了)。

作为一般规则,请尝试检查服务/ syscalls中的所有返回码。您可以不做任何检查就草拟初稿。但是,当它看起来功能异常时,请在返回码上添加检查。这通常有帮助...