使用 errx() 正确终止程序时出现问题

Issue terminating the program correctly using errx()

提问人:Haidari 提问时间:5/21/2023 更新时间:5/21/2023 访问量:57

问:

尝试使用 if 语句终止程序并在运行程序的其余部分之前输出错误消息:但是,printf 语句在调用 errx 后跟随。

#include <stdio.h>
#include <err.h>

int main(){
    printf("\nEnter an integer: ");
    int age;
    if(age){
        scanf("%d", &age);
        printf("\nEnter a real number: ");
        float percent;
        scanf("%f", &percent);
        if(percent){
            printf("\nEnter an integer: ");
            int semesters;
            scanf("%d", &semesters);
            if(semesters){
                printf("\nHenry wanted to be a TA since he was %d years old!\nLittle did he know that he would sacrifice %.2f%% percent of his day.\nSo Henry quit suddenly after %d semesters as a TA...\n", age, percent, semesters);

                errx(0,"\nProgram was completed without errors");
            }
            else{
                errx(1,"Error reading input");
            }
        }
        else{
                errx(1, "Error reading input");
        }
    }
    else{
        errx(1,"Error reading input");

如您所见,我有 3 个 if 语句检查输入值,但是如果我尝试使用以下输入在 Linux 上运行它:

Enter an integer: [

Enter a real number:
a.out: Error reading input
Enter an integer: 

程序在第一次输入“[”后终止,但接下来的内容我真的不明白。为什么调用 print 语句,为什么在第二个 printf 语句之后出现错误消息?

C Linux 错误处理

评论

0赞 Weather Vane 5/21/2023
您需要使每个输出以正确的顺序显示,因为末尾没有换行符。另请注意,您输出了 3 条相同的消息,因此无法看到执行的是哪一条消息。fflush
2赞 teapot418 5/21/2023
int age; if (age)正在使用未初始化的变量,并且其行为未定义。
0赞 Weather Vane 5/21/2023
...与其他两个输入类似,和 .在测试数据本身之前,请务必检查返回的值(成功转化次数)。如果无法转换输入,则验证数据是没有用的。float percent;int semestersscanfscanf
0赞 teapot418 5/21/2023
啊,你是说把放在后面吗?无论如何,这并不是您对scanf进行错误检查的方式,您应该查看其返回值。if (age)scanf("%d", &age);
0赞 Haidari 5/22/2023
谢谢你们俩。我认为我不应该检查 scanf 函数的返回值。现在这很有意义。

答:

0赞 Harith 5/21/2023 #1
int age;
if(age){

该变量从未初始化,因此后续测试使用未初始化变量的值,从而触发未定义的行为。age

该函数返回成功执行的转换次数。更好的代码会检查它:scanf()

// scanf("%d", &age);
   if (scanf ("%d", &age) != 1) {
      fputs ("Error: Invalid input.\n", stderr);
      return EXIT_FAILURE;
   }

缓冲的数据在调用时或程序终止时被刷新。如果是行缓冲的(通常在流连接到终端/控制台时出现这种情况),则当遇到换行符时,流也将被刷新。但是,由于程序调用了未定义的行为,因此无法对程序执行的继续做出假设。 在对 的调用中添加换行符 ,或 调用 。printf()fflush (stdout)stdoutprintf()fflush (stdout);

您需要刷新每个输出以使它们以正确的顺序显示,因为末尾没有换行符。另请注意,您输出了 3 条相同的消息,因此无法看到执行的是哪一条消息。– 风标