【问题标题】:Output shows unessesary number in C输出显示 C 中不必要的数字
【发布时间】:2020-06-21 17:31:15
【问题描述】:

我正在编写一个程序来要求用户输入日期,当用户输入 0/0/0 作为日期时,程序停止要求用户输入日期,但是我的输出有问题,这里是代码:

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

int main (){

int d, m, y;



for (;d!=0 && m!=0 && y!= 0;){

printf("Enter a date (xx/xx/xxxx): ");
scanf("%d/%d/%d", &d, &m, &y);

}

    return 0;
}

运行此程序后,输出为“输入日期(xx/xx/xxxx):”只要 0/0/0 不是输入,则该程序的输出如下所示:

Enter a date (xx/xx/xxxx): 5/5/5
Enter a date (xx/xx/xxxx): 6/6/6
6Enter a date (xx/xx/xxxx): 7/7/7
7Enter a date (xx/xx/xxxx): 4/4/4
7Enter a date (xx/xx/xxxx): 3/3/3
7Enter a date (xx/xx/xxxx): 

正如您所看到的输出,问题是在每个换行符上,每个新行上都会显示最大的数字,无论它是否属于 d、m 或 y 变量。 为什么会这样?我该如何解决?

【问题讨论】:

  • 您的代码根本不会打印输出。您在向我们展示您的实际代码吗?

标签: c for-loop output


【解决方案1】:

首先,您的循环访问dmy,即使这些还没有收到初始值。那是未定义的行为。你是说int d = 1, m = 0, y = 0吗?

至于额外的迭代,程序只是按照你的要求做。虽然这些变量不为零,但请要求更多输入。您输入 3/3/3,因此变量不为零,因此它要求更多输入。

我在上面设置了d = 1,以便第一次进入循环;如果我们将变量全部初始化为零,则循环不会执行。

如果我们从循环顶部测试切换到循环底部测试,我们可以使用未初始化的变量

在 C 中进行循环底部测试的方法之一是使用 do/while 循环:

do {
   // ask for input
} while (d != 0 && m != 0 && y != 0); // unless zeros were given, ask again

do 的一个问题是终止表达式在作用域中没有任何内部变量,因此例如这个习语是不可能的:

do {
   int x = some_function();
   // ...
} while (x != 0); // x is not in scope here!

这可能是do 循环不像forwhile 那样被使用的原因之一。在这种情况下,我们可以使用for (;;) 进行无限循环,然后将循环底部测试作为if 进行中断:

for (;;) {
   int x = some_function();
   // ...
   if (x == 0)  // note inversion: while (x != 0) -> if (x == 0)
      break;
   // nothing else here, hence "bottom-of-loop test"
}

最后,我不鼓励您使用scanf 进行交互式输入。如果用户在输入语法中犯了任何错误,scanf 不会提供错误恢复。 scanf 可以处理特定程序中的数据文件并期望正确。在使用scanf 时,您应该捕获它的返回值并对其进行操作:它表示成功进行了多少次转换,如果没有进行任何转换,则可能返回负值EOF

要以更稳健的方式获得交互式输入,我们可以使用fgets 来读取用户的行,并使用较大的缓冲区大小。然后,使用scanf的字符串版本,即sscanf扫描缓冲区的内容(同时截取sscanf的返回值并作用于它,提供错误诊断和恢复)。

还请注意,如果我们调用 scanf("%m", &amp;m) 但没有成功转换(例如 scanf 返回 0 或 EOF),那么在这种情况下 m 将保留其先前的值。如果m 未初始化,则它保持未初始化状态。如果您不检查 scanf 的结果,您的程序将使用旧值,认为它们是新值。

如你所见

我可以看到输出,但在产生输出的程序中什么也看不到。希望这些提示会有所帮助。

【讨论】:

    【解决方案2】:

    当我运行您的代码时,它会立即终止,可能是因为dmy 的值在程序启动时恰好为零。当我更改程序以使用特定标志来指示第一次通过循环时(我将循环更改为 while 循环,因为这就是真正发生的事情)我没有得到您报告的问题:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main ()
      {
      int d, m, y, first = 1;
    
      while(first || (d!=0 && m!=0 && y!= 0))
        {
        first = 0;
    
        printf("Enter a date (xx/xx/xxxx): ");
        scanf("%d/%d/%d", &d, &m, &y);
        }
    
      return 0;
      }
    

    上面的输出是:

    Enter a date (xx/xx/xxxx): 1/2/3                                                                                                                                                   
    Enter a date (xx/xx/xxxx): 4/5/6                                                                                                                                                   
    Enter a date (xx/xx/xxxx): 7/8/9                                                                                                                                                   
    Enter a date (xx/xx/xxxx): 0/0/0    
    

    Online GDB here

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2018-11-17
    • 2016-01-11
    相关资源
    最近更新 更多