2010-10-21 30 views
2

我写了一个简单的代码来从键盘上读取一个字符,但程序失败了,为什么?我如何阅读char?只有在阅读一个换行符后有什么更好的方法来读取字符?

int main(int argc, char** argv) 
{ 
char op; 

do 
{ 
    printf("¿Sigues?"); 
    scanf("%c",&op); 
}while(op=='s' || op=='S'); 
return 0; 
} 
+1

“程序失败”,你能解释程序如何失败吗? – JoshD 2010-10-21 19:24:30

+0

它总是只写2次“Sigues”。 – 2010-10-21 19:31:19

回答

2

您的问题是%c转换说明符不会导致scanf()跳过前导空格。读取输入后,您需要处理仍在流中的换行符。

scanf()被第一次通过循环调用时,输入流为空,因此它会等待您键入内容。您输入s并按Enter键,因此输入流包含字符s\n(换行符)。 scanf()从输入流中移除s并将其分配给op。当第二次调用scanf()时,输入流为而不是为空;它仍然有\n字符,所以scanf()会读取它并将其分配给op,这会导致循环条件失败,因此您的循环将退出。

有几种方法可以解决此问题。我要推荐阅读而不是使用fgets()单个字符,如下所示:

char op[3] = {0}; // input character + newline character + 0 terminator 

do 
{ 
    printf("¿Sigues?"); 
    if (fgets(op, sizeof op, stdin)) 
    { 
    /** 
    * Check for a newline character in the input. If it's not there 
    * then the user typed in too many characters. In order to keep 
    * the input stream from getting clogged up with bad input, read 
    * until we find a newline character. 
    */ 
    char tmp[3]; 
    char *newline = strchr(op, '\n'); 
    while (!newline && fgets(tmp, sizeof tmp, stdin)) 
    { 
     newline = strchr(tmp, '\n'); 
    } 
    } 
    else 
    { 
    printf("Error while reading input\n"); 
    op[0] = 0; 
    } 
} while (tolower(op[0]) == 's'); 
+0

就是这样,非常感谢你的解释。 – 2010-10-21 20:14:17

1
op = getc(stdin); 
+0

非常感谢, 你能解释一下他们之间的区别吗? – 2010-10-21 19:29:18

+0

原始文章中的循环将产生与'scanf(“%c”)'相同的结果。 'getc(stdin)'仍然只能读取一个字符,而标准输入中仍然会有'\ n'。 – BeeBand 2010-10-21 20:31:47

1

scanf函数刷新。它不能以平台独立的方式完成

0

你看到一行“Sigues”两次,因为在输入流中有一个\n依然。如果你输入一个字符并按回车,你的输入流中现在有两个字符。您的scanf格式化程序只指定一个字符,因此scanf会读入一个字符,然后前进。但是,流中的下一个字符是\n,因此在第二个循环中退出循环。

注意: @ eduffy的技巧getc(stdin)会做同样的事情,stdin中仍然有\n。你需要以某种方式超过\n

如何读你的字符,然后chomping其余的流到\n字符?我试过这个,它适用于我:

char op; 

do 
{ 
    printf("¿Sigues?"); 
    scanf("%c",&op); 
    while(getchar() != '\n') continue; 
}while(op=='s'|| op=='S'); 
相关问题