2015-09-10 22 views
-4

我使用C玩,写了这个代码:得到()函数从第二次起跳过

1 #include<stdio.h> 
    2 #define ASK_PROMPT printf("\nDo you want to continue(Y/N):"); 
    3 main() 
    4 { 
    5 char main[20], i; 
    6 start: 
    7 printf("Please enter your string:\n"); 
    8 gets(main); 
    9 printf("\nstring entered was:\n \n%s\n", main); 
    10 ASK_PROMPT; 
    11 scanf("%c",&i); 
    12  
    13 if(i=='Y'||i=='y') 
    14  goto start; 
    15 getch(); 
    16 return; 
    17 } 
当我执行这个代码

,该goto loop无法正常工作。在提供yY对第10行问题的回答时,循环确实起作用,并且第7行再次执行/打印,但第8行被跳过(不等待输入提供)。

  • 任何人都可以解释它为什么会发生?
  • 我该如何解决?
+1

此代码应该是**不**的典型例子。 – Haris

+1

这几乎是你为了输入“Y”或“Y”而击中多个键。但是,这将是非常明显的,所以你必须已经排除了在调试中的可能性... – EOF

+0

意味着,不应该使用goto?我通常不使用转到。但我想问的是为什么它不要求输入。程序是否忘记main已经被声明了? (请不要介意“主”作为另一件事,我试图) – user2507780

回答

0

修复

变化scanf("%c",&i);scanf("%c%*c",&i);

问题

\n输入i是什么原因造成gets()不等待输入后。使用gets()goto

良好做法

  • 停止相反,你可以使用fgets()scanf()等切勿使用废弃的函数。
  • 更改charmain到的数组名称。

感谢@Coolguy关于使用scanf的评论。

+0

感谢您的答复和建议,但即使更改代码后你的建议是显示同样的问题 – user2507780

+0

我已经在我的系统上试过了,然后发布了答案,你在使用哪种编译器? – vish4071

+1

@ user2507780使用'scanf(“%c%* c”,&i);' uld建议使用@ ameyCU的解决方案虽然 –

2

我建议使用gets如果输入的字符串是比main[20]规模较大的有什么用gets。而。 gets不会阻止这一点,它会导致UB

使用fgets -

fgets(main,20,stdin); 

和理性您的问题是,它仍然在stdin原因'\n'scanf("%c",&i);这是gets回报,因为它遇到'\n'

为了避免'\n'后就可以scanf语句做到这一点 -

int c; 
while ((c = getchar()) != EOF && c != '\n'); 
+0

感谢您的回复,我根据您的建议进行了更改。在更改之后,字符串的第一个字母被删除/截断,问题依然存在。 – user2507780

+0

@ user2507780您是否按照我所说的添加了代码? 'getchar'的行应该在'scanf('%c',&i);'在你的代码中。 – ameyCU

+0

@CoolGuy啊我总是忘记它加null。谢谢!! :) – ameyCU

1

问题:

打字Ÿ响应您的提示下输入之后,你的程序的输入流中包含的字符'y''\n'(换行字符)。调用scanf将从输入流中删除'y'字符,并保留换行符。

gets从输入流中读取,直到它看到一个换行符,并丢弃它;因为它看到的第一件事是来自上一个条目的换行符,它将返回而不读取任何其他输入。

解决办法:

首先,不要使用gets。永远。它在1999年修订版中已被弃用,并已从2011年修订版中完全删除。使用它在您的程序中引入故障点/安全漏洞。取而代之的是拨打fgets,请注意fgets会尝试将新行存储在目标缓冲区(如果有空间的话)。

其次,您需要从输入流中消耗尾随的换行符。通过vish4071给出的答案显示了一种方法 - 使用scanf阅读下列您输入的字符(这应该是换行符),并丢弃:

scanf(" %c%*c", &i); 

在格式字符串中的前导空白告诉scanf跳过任何前导空格,%c转换说明符告诉scanf从输入流读取下一个字符并将其值存储到i,并且%*c转换说明符告诉scanf从输入流读取下一个字符并丢弃它。

另一种选择是,直到你看到一个换行符消耗输入:

scanf(" %c", &i); 
while (getchar() != '\n') // repeatedly read characters from input stream 
    ;       // until we see a newline 

另一个选择是读你的输入作为另一个字符串:

char answer[3]; // space for y/n response plus newline plus 0 terminator 
... 
if (fgets(answer, sizeof answer, stdin)) 
{ 
    if (tolower(answer[0]) == 'y') 
    { 
    // do stuff 
    } 
} 

你可能会想,以检查在answer缓冲区中存在换行符;如果它不在那里,那么用户键入的字符数大于缓冲区大小,这可能会使将来的读取变得糟糕,并且在下一次读取操作之前需要清除该虚假输入:

if (!strchr(answer, '\n')) 
    while (getchar() != '\n') 
    ; 
0

对现有代码的最小修复,只需第二次使用gets(main)。如果代码要使用ASK_PROMPT ;,那么ASK_PROMPT的定义不需要结尾; 。如前所述,您可以使用fgets()而不是gets(),并使用适当的循环代替start:并转到。

#include<stdio.h> 
#define ASK_PROMPT printf("\nDo you want to continue(Y/N):") 
int main() 
{ 
    char main[20]; 
    start: 
    printf("Please enter your string:\n"); 
    gets(main); 
    printf("\nstring entered was:\n \n%s\n", main); 
    ASK_PROMPT; 
    gets(main); 
    if(main[0]=='Y'||main[0]=='y') 
     goto start; 
    getch(); 
    return(0); 
} 
相关问题