【问题标题】:Why is this code exiting prematurely?为什么此代码过早退出?
【发布时间】:2011-03-31 07:27:22
【问题描述】:
    #include <stdio.h>
    #define MAX 5
    int stk[MAX];
    int top=-1;

    main() 
     {
      char ch;
      void push();
      void pop();
     void display();

     do
     {
      printf("1. Push\n");
      printf("2. Pop\n");
      printf("3. Display\n");
      ch=getchar();

         if(ch=='1')
            push();
         if(ch=='2')
            pop();
         if(ch=='3')
            display();

    printf("Do u want to continue y/n"); 
    ch=getchar();
       }while(ch=='y'||ch=='Y');

    }

void push()
 {
   }

void pop()
 {
   }

void display()
 {
   }

当我完成推送操作的那一刻......程序打印““你想继续y/n”并退出......不等待用户输入“”y/Y”

请帮忙

【问题讨论】:

  • 我在 linux 上做这个程序……在虚拟机上……
  • 请不要在先询问OP前添加作业标签。人们为自我教育提出类似家庭作业的问题有很多先例,当所有 OP 想要的只是一个解决方案时,家庭作业标签不可避免地会导致否决票或迟钝/自己动手做的答案。话虽如此,@Vinod,请指出这是否作业。答案的风格会因此而变化。
  • paxdiablo:我相信这完全属于“请向我发送代码”类别。
  • 我不同意@pax 关于识别教学问题的看法。 OP为他或她自己设置它的事实并不重要。我不喜欢[家庭作业]来识别这些问题,但它们都是一样的。请参阅Etiquette on retagging questions as homework 了解有关元数据的几轮之一。还有thisthis 和其他一些我现在找不到的。
  • 我觉得在劫持了@Vinod 的线程之后,我们应该明确说明作业(即使是真实的,如果从老师那里得到的必须在作业中提交)问题在 Stack Overflow 上是可以的。请不要感觉不鼓励您在这里寻求帮助。但我们通常想看看您尝试了什么以及您遇到了什么困难。这个特别的问题绝对没问题。

标签: c programming-languages stack


【解决方案1】:

这是因为,当您输入 1 后跟 RETURN 键时,两个 字符会放入您的缓冲区(1newline)。

newline 然后被第二个getchar() 拾取,因为它既不是Y 也不是y,所以它退出了。

快速修复(但很笨拙):在 printf 之前添加另一个 getchar();

如果您想要更强大的用户输入,请参阅herehere 或使用我的武器库中的这个近乎防弹的代码:

#include <stdio.h>
#include <string.h>

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

 

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        // Extra NL since my system doesn't output that on EOF.
        printf ("\nNo input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long [%s]\n", buff);
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}

这是一个测试运行:

$ ./tstprg
Enter string>[CTRL-D]
No input

$ ./tstprg
Enter string> a
OK [a]

$ ./tstprg
Enter string> hello
OK [hello]

$ ./tstprg
Enter string> hello there
Input too long [hello the]

$ ./tstprg
Enter string> I am pax
OK [I am pax]

您可能还想充实您的 pushpopdisplay 函数 :-) 开个玩笑。我假设这是你的下一步。


顺便说一句,如果这个家庭作业,我建议不要把上面的代码作为你自己的工作上交。您几乎肯定会被认定为作弊,因为这很可能超出了您目前接受的教育水平,并且可以通过简单的网络搜索获得:输入

rc = getLine ("Enter string> ", buff, sizeof(buff));

进入您友好的社区 Google 搜索框查找。

【讨论】:

    【解决方案2】:

    需要注意的小事。 getChar 返回 int 而不是 char。这可能会导致各种混乱和意外问题,因为类型可能大小不同。

    【讨论】:

      【解决方案3】:
      1. 当用户按下 Enter 键时,您的缓冲区中有一个换行符 (\n)。
      2. 您调用getchar() 一次,从缓冲区中读取该换行符,该换行符分配给ch,不等于'y''Y',因此您的循环退出。

      至于解决这个问题,留给你作为练习。除了单独的getchar() 之外,您还可以考虑使用其他读取数据的方法。一些输入函数参见here(提示:fgets)。您还可以尝试从缓冲区中提取此字符并将其丢弃,以便随后对 getchar() 的调用按预期工作。

      如果这是针对学校的(看起来是这样),您可能需要编写一个可以在整个课程中重复使用的函数。这样,您就可以调试它,并且熟悉它的工作原理。

      祝你好运!

      【讨论】:

      • 谢谢你......但你能告诉我如何避免它吗?
      • 我包含的链接有几个功能 - scanffgets 等。快速解决方法是在 ch=getchar() 部分之前放置一个 getchar()
      猜你喜欢
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-12
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多