功能获取垃圾值

时间:2017-12-14 00:21:52

标签: c

 #include <stdio.h>
   void clearKeyboard(void)
   {
       while (getchar() != '\n')   ; // empty execution code block on purpose
   }
   int yes(void)
   {

       char a,b;
       printf("<Please enter a character>: ");
       scanf("%c%c", &a,&b);

       while ((a !='Y' && a !='y' && a !='N' && a!='n') || (b!='\n'))
       { 
          if (b!='\n') ungetc(b, stdin),scanf("%*[^\n]%c", &b);
          a='n',b='\n';
          clearKeyboard();
          printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: ");
          scanf("%c%c", &a,&b);

        }
        if (a =='Y' || a=='y')
        {
            printf("Contact Management System: terminated\n");
            return 1;

        }
        else 
        {
            if (a =='N' || a=='n')
            ContactManagerSystem();
            return 0;
        }

   }

   int menu(void)

   {
       int i;
       printf("0. Exit\n\nSelect an option:> ");
       scanf("%d", &i);
       while (i<0 || i>6)
       {
           printf("*** OUT OF RANGE *** <Enter a number between 0 and 6>: ");
           scanf("%d", &i);
       }
       return i;
   }

   void ContactManagerSystem(void)

   {
     int i=menu();

      switch(i)
      {
         case 0 :
          printf("Exit the program? (Y)es/(N)o: ");
          yes();


       }

   }
   int main(void)
   {
       ContactManagerSystem();
   }







So my "yes" function is working fine on it's own but when I call it within 

ContactManagerSystem()case 0由于某种原因它会变得疯狂     “是”功能实际上是我需要用户的验证检查功能     输入“是”或“否”,如'Y''''N'或'n'     等待用户输入“Y”,“y”,“N”或“n”(对于是或否)。     如果用户回答是(“Y”,“y”),它将结束显示的程序     以下消息:

  

联系管理系统:已终止&lt; (后面跟换行)       否则,如果用户输入No(“N”,“n”),则应用程序继续       显示菜单。

3 个答案:

答案 0 :(得分:2)

我认为您需要重新考虑使用&&||,并使用括号。此代码还处理EOF和键入的单词(如“是”)。

#include <stdio.h>

int main(void)
{
    char a, b;
    printf("<Please enter a character>: ");
    if (scanf("%c%c", &a, &b) == 2)
    {
        while ((a != 'Y' && a != 'y' && a != 'N' && a != 'n') || b != '\n')
        {
            printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: ");
            if (b != '\n')
            {
                int c;
                while ((c = getchar()) != EOF && c != '\n')
                    ;
            }
            if (scanf("%c%c", &a, &b) != 2)
                break;
        }
        if (a == 'Y' || a == 'y')
        {
            printf("Got yes!\n");
            return 1;
        }
        else if (a == 'N' || a == 'n')
        {
            printf("Got no!\n");
            return 0;
        }
    }
    printf("Got EOF\n");
    return 0;
}

如果a中的字母既不是'Y'也不是'y',也不是'N'也不是'n',或者b中的字母不是换行,报告问题,吞噬任何流浪角色到换行符(或EOF),然后恢复。通过打印和退出状态报告状态。

示例运行:

$ ./scan13; echo $?
<Please enter a character>: yes
*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: no
*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: pdq
*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: y
Got yes!
1
$ scan13; echo $?
<Please enter a character>: n
Got no!
0
$ ./scan13; echo $?
<Please enter a character>: Got EOF
0
$

如下面的评论中所述,scanf()的一个问题是确保错误行为符合预期。使用fgets()或POSIX getline()将整行读入缓冲区通常更容易,然后使用sscanf()解析数据。

答案 1 :(得分:1)

while循环的意义是错误的。假设a得到了字符'y'。然后,由于'y' != 'Y'为真,您将继续循环。

这是一个纠正的循环。

    while ((a !='Y' && a !='y' && a !='N' && a!='n') || (b!='\n'))
    {
        if (b!='\n') ungetc(b, stdin),scanf("%*[^\n]%c", &b);
        a='n',b='\n';
        printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: ");
        scanf("%c%c", &a,&b);
    }

请注意,新代码处理的行太长,并为您排空了原始代码中缺少的行。

Try it online!

while ((a !='Y' && a !='y' && a !='N' && a!='n') || (b!='\n'))

我们希望a成为YyNn之一。如果不是这些,请进入循环。另外,如果b不是换行符,请输入循环。

    if (b!='\n') ungetc(b, stdin),scanf("%*[^\n]%c", &b);

如果b不是换行符,那么该行可能太长了,所以我们不得不排空。首先,将b的值放回输入流中。然后,告诉scanf扫描过去的所有内容到换行符,然后使用它(进入b)。

    a='n',b='\n';

为准备下一次获取输入的scanf调用,请使用将导致循环终止的值预先填充ab。这是scanf封堵(例如EOF或某些文件输入错误)。

其余的代码就像你拥有它一样。

答案 2 :(得分:0)

尝试:

while (  ( !( a =='Y' || a =='y')  &&  !( a =='N' || a =='n') )       ||      (  b !='\n') )