Issue terminating the program correctly using errx()

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

Issue terminating the program correctly using errx()

问题

It appears that you are experiencing unexpected behavior in your C program. The issue is that you're using the if statement to check the value of variables like age and percent before you've actually initialized them. This can lead to undefined behavior in your program.

To resolve this issue, you should initialize the variables before checking their values in your if statements. Here's a corrected version of your code:

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

int main(){
    int age;
    printf("Enter an integer: ");
    if(scanf("%d", &age) != 1){
        errx(1, "Error reading input");
    }

    float percent;
    printf("Enter a real number: ");
    if(scanf("%f", &percent) != 1){
        errx(1, "Error reading input");
    }

    int semesters;
    printf("Enter an integer: ");
    if(scanf("%d", &semesters) != 1){
        errx(1, "Error reading input");
    }

    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, "Program was completed without errors");
    return 0;
}

In this corrected code, I've initialized the variables age, percent, and semesters before using them in the if statements to check for valid input. This should prevent the unexpected behavior you observed in your original code.

英文:

Attempted using if statements to terminate the program and output error messages before running the rest of the program: however, the printf statments follow after errx is called.

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

int main(){
    printf(&quot;\nEnter an integer: &quot;);
    int age;
    if(age){
        scanf(&quot;%d&quot;, &amp;age);
        printf(&quot;\nEnter a real number: &quot;);
        float percent;
        scanf(&quot;%f&quot;, &amp;percent);
        if(percent){
            printf(&quot;\nEnter an integer: &quot;);
            int semesters;
            scanf(&quot;%d&quot;, &amp;semesters);
            if(semesters){
                printf(&quot;\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&quot;, age, percent, semesters);

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

As you can see I have 3 if statements checking input values, but If I try to run this on Linux with the following input:

Enter an integer: [

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

The program terminates after the first input of "[" but what follows it I don't really understand. Why were the print statements called and why is the error message after the second printf statement?

答案1

得分: 0

int age;
if (age) {

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

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

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

printf()缓冲的数据在调用fflush(stdout)时被刷新,或者在程序终止时被刷新。如果stdout是行缓冲的(通常情况下,当流连接到终端/控制台时),那么当遇到换行符时,流也将被刷新。但由于程序调用了未定义的行为,不能对程序的执行继续性做任何假设。
在调用printf()时添加一个换行,或者调用fflush(stdout);

为了使它们按正确的顺序显示,您需要对每个输出进行刷新,因为末尾没有换行符。还要注意,您输出了3条相同的消息,因此无法看出哪一条被执行。 – Weather Vane

英文:
int age;
if(age){

The variable age was never initialized, so the subsequent test uses the value of an uninitialized variable and thus triggers undefined behaviour.

The scanf() function returns the number of conversions successfully performed. Better code would check for it:

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

The data buffered by printf() is flushed when fflush (stdout) is called, or when the program terminates. If stdout is line-buffered (which is usually the case when the stream is connected to a terminal/console), then the stream will also be flushed when a newline character is encountered. But since the program invokes undefined behaviour, no assumption about the continuation of the execution of the program can be made.
Add a newline in the calls to printf(), or call fflush (stdout);.

You need to fflush each output to make them appear in the correct sequence, because there isn't a newline at the end. Note too that you output 3 identical messages, so it can't be seen which one was executed.
Weather Vane

huangapple
  • 本文由 发表于 2023年5月21日 17:18:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76299143.html
匿名

发表评论

匿名网友

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

确定