`
paddy.w
  • 浏览: 497337 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于getchar()、scanf()、gets()

    博客分类:
  • C
 
阅读更多
        在看K&R的时候对于getchar()产生了一点疑问,下面根据自己的理解和几个例子说明一下。

        Q1:关于EOF
#include <stdio.h>

int main() {
    int c;

    while((c = getchar()) != EOF)
        putchar(c);

    return 0;
}

        如果输入hello回车,输出结果如下:
hello
hello

        此时再输入ctrl+D(即linux下的EOF表示),程序结束。如果输入hello之后不输入回车,而是EOF,此时程序并没有结束,而是可以继续输入,但并不换行。若再直接ctrl+D那么程序结束。
        这说明,当getchar()读取到换行符的时候,认为此次输入结束。程序换行,执行putchar()输出刚才输入的内容。如果不以回车,而以EOF作为结尾,getchar()仍然并且只是认为此次输入结束,而不是结束程序。当EOF单独出现的时候,getchar()才认为是输入行为终止。

        Q2:getchar()获取几个字符?如何执行的?
        在上面的例子中,输入hello,输出hello。那程序执行的过程是不是getchar()获取到了hello,将其赋给c,判断c!=EOF,输出c?看下面这个例子
#include <stdio.h>

int main() {
    int c;

    c = getchar();
    putchar(c);
    /*
    c = getchar();
    putchar(c);
    */
    return 0;
}

        还用'hello'作为例子,当我们输入hello回车时,程序输出h,然后结束。很显然,getchar()只获取到了一个字符。
        当把注释去掉,再次执行程序。输入hello回车,输出he。程序中出现了两次getchar(),但整个过程中只有一次键盘输入过程,也即第一次getchar(),第二次getchar()并没有要求终端输入。看来,将getchar()理解为请求终端获取输入也不完全正确。其实getchar()的执行的原理是这样的(有部分个人理解):
        用键盘输入字符的时候,输入的字符被放入了缓冲区,直到用户按下回车结束本次输入(回车符也被放入缓冲区)。其实getchar()是从输入流缓冲区中读取数据的,如果缓冲区中没有数据,则会进入等待,直到缓冲区有数据。这也就是程序执行到第一个getchar()时会等待用户输入的原因。当缓冲区有数据时,getchar()会从缓冲区获取第一个字符(显然,缓冲区是FIFO的),在例子中就是h,putchar(c)输出h,再次执行getchar(),获取到了e,putchar(c)输出e,程序结束。
        当然,假设只输入一个字符'a'的时候,也只需要一次键盘输入,程序就会结束。因为回车也算作一个字符,所以输入的其实是两个字符。直接输入回车的话,就需要输入两次才能结束程序。
        最后再看一个例子证明一下上面的判断:
#include <stdio.h>

int main() {

    int ch1, ch2;
    ch1 = getchar();
    ch2 = getchar();
    printf("%d %d", ch1, ch2);

    return 0;
}

        输入hello,输出104 101。这两个数字也正是h和e的ascii码。

        Q3:关于getch()
        getch()和getchar()类似,也是获取一个字符。不同的是getch()不从缓冲区获取,而是直接从键盘输入获取,也即输入一个字符,立刻返回一个字符,不需要按回车。

        Q4:关于scanf()
        scanf()类似getchar(),略有不同的是结束标志。看下面的例子:
#include <stdio.h>

int main() {

    char chs1[10], chs2[10];
    scanf("%s", chs1);
    printf("%s\n", chs1);
    scanf("%s", chs2);
    printf("%s\n", chs2);
    
    return 0;
}

        输入hello world,发现只需要一次输入,程序会输出两次,然后结束。scanf()与getchar()一样,也是从输入流缓冲区获取数据,不同的是,scanf()获取数据时如果遇到回车、空格或TAB则会停止,一次获取数据过程结束。第二个scanf()会继续从输入流缓冲区获取数据。
        在Q1中,如果输入hello回车,仔细观察的话会发现,输出也是hello回车,说明getchar()也获取了缓冲区的回车符。如果在上面这个例子中输入hello回车,输出也是hello回车,并且程序没有结束而是继续等待用户输入,这说明第二个scanf()从缓冲区获取不到数据了,然后等待用户输入,输入world回车,输出world,程序结束。即下面的结果:
hello
hello
world
world

        首先说明,scanf()丢弃了输入hello后的那个回车符,也即scanf()读取字符串会丢弃结尾的回车符。从这个例子中也可以看出,输入hello回车,输出也是hello回车,但是printf()中有一个\n换行符,如果scanf()能获取到hello后面的回车的话,输出结果应该下面这个样子的:
hello
hello

world
world



        这也说明了scanf()会丢弃字符串结尾的回车符。但注意,回车符并没有被scanf()跳过而残留在缓冲区内,而是被scanf()获取但是丢弃了,此时缓冲区内的回车符已经不存在了。

        Q5:关于gets()
        gets和scanf()的用法类似,但是gets()可以获取带空格的字符串,看这个例子:
#include <stdio.h>

int main() {

    char chs1[10], chs2[10];
    gets(chs1);
    printf("%s\n", chs1);
    gets(chs2);
    printf("%s\n", chs2);
    
    return 0;
}

        输入hello world,输出hello world,并继续等待用户输入,输入helloTABworld,输出helloTABworld(TAB代表键盘的tab键,输入制表符),程序结束。
hello world
hello world
hello    world
hello    world

        gets()并不会因为字符串中有空格或者TAB而结束字符的获取,但和scanf()一样,会忽略字符串结尾的回车符。

        清除缓冲区内的残留数据
        1、利用函数fflush(stdin)
        注意:ANSI C中并没有将这个函数作为标准的一部分,是编译器支持的,并不是所有编译器都支持这个函数。所以,严格的讲,这样并不具备绝对的可移植性。
        2、手动取出缓冲区里的残留数据
        scanf("%[^\n]",str);
分享到:
评论

相关推荐

    C语言中getchar, gets, 和 scanf 三种不同函数的区别

    getchar和gets和scanf区别 getchar 用于单个字符,gets(不推荐)用于字符串,而 scanf 用于各种不同的数据类型,通常需要使用格式字符串来指定输入的格式。在现代C编程中,推荐使用更安全的函数来代替 gets,如 ...

    C++深入了解scanf()getchar()和gets()等函数

    C++深入了解scanf()getchar()和gets()等函数

    scanf(), getchar(), 以及gets()函数注意点

    对函数scanf()、getchar()、gets()的异同进行深入剖析

    c语言输入的各种注意问题

    c语言中各种输入函数应该注意的地方,c语言中的scanf、getchar,gets、getche、getch。等函数的用法和区别。

    C输入输出库函数

    如:gets,puts,printf,scanf等。并且在原函数名前加my构成新函数名。如:mygets,myputs,myprintf,myscanf等。 对myprintf函数,其功能与printf函数相同。但只要求支持简单的%c,%d,%s,%f,%lf格式说明。不...

    计算机基础与程序设计.doc

    getchar(c) C. gets(c) D. scanf( %s ,c) E. for(i=0;i;i++) scanf( %c ,&c[i];c[10])='\0' 正确答案:CE 2、设有定义int a[3][6],*p;则正确的指向数组元素的指针赋值是( ) (分数:2分) A. p=*a B. p=a[0] ...

    poj 2643解题报告

    while( scanf("%d",&n) != EOF ) { getchar(); memset( a , 0 , sizeof(a) ); for( i = 1 ; i ; i++ ){ gets( s1 ); gets( s2 ); index[ s1 ] = i; name[ i ] = s2; } scanf("%d",&m); ...

    C语言常用头文件、位运算、SetConsoleTextAttribute()函数.docx

    scanf、printf getchar、putchar gets、puts stdlib.h rand()%a+b:产生0~32767的随机数,a为范围,b为范围起始值,即产生b~b+a-1的随机数。 srand(随机种子):如srand(time(0))。 malloc(8)、calloc(10,sizeof...

    ACM做题时的小技巧

    先用scanf(),再用gets()会读入回车。所以在中间加一个getchar(); scanf("%c%c",&c1,&c2)会读入空格;建议用%s读取字符串,取第一个字符。 5. 读到文件的结尾,程序自动结束 while( ( scanf(“%d”, &a) ) != -...

    C语言程序设计:运算符和表达式.pptx

    getchar 输入字符, printf 格式输出,gets 输入字符串; § 5.8 字符数据的输入输出 putchar 函数(单字符输出函数);输出控制字符;getchar 函数(单字符输入函数) ;§5.9 格式输入与输出 printf函数(格式输出函数...

    小型超市管理系统

    scanf("%ld",&goods[i].count); printf("\n\t 请输入商品的单价:"); scanf("%ld",&goods[i].price); } printf("\n\n\t 输入成功!请按任意键返回:"); getchar(); return; /*返回主页面*/ } void ...

    从Python看C语言(基础语法篇)

    一个学过C/C++的老油条,最近学起了Python,不得不说,知识还是老知识,语法也简单多了,但就是容易搞混。...对于字符串,除了scanf输入,还可以用gets()输入。 输出最常用的非print莫属啦(C语言为printf),但

    iozone.txt

    10. scanf()/fscanf()/sscanf()/vscanf()/vfscanf()/vsscanf() 11. printf()/fprintf()/sprintf()/snprintf()/vprintf()/vfprintf()/vsprintf()/vsanprintf() 12. readv()/writev() 13. read()/written() 14. ...

    C语言程序设计课程设计-通讯录管理系统.doc

    c=getchar(); }while(c&lt;'0'""c&gt;'6'); return(c-'0'); } int Input(Person per[],int n) { int i=0; char sign,x[10]; while(sign!='n'&&sign!='N') { printf("\t编号:"); scanf("\t%d",&per[n+i].score); printf("\...

    C语言课程设计学生成绩管理系统.doc

    scanf("%d",&num); if(i==0) numstus=num; else numstus+=num; if(numstus&gt;lens) { lens+=50; pointer=(student *)realloc(pointer,lens*LEN); } printf(" 请输入学生信息 :\n"); for(;i;i++) { getchar(); printf...

    C语言程序设计实例(200行)

    while((c=getchar())=='y') { i=rand()%100; printf("\nplease input number you guess:\n"); start=clock(); a=time(NULL); scanf("%d",&guess); while(guess!=i) { if(guess&gt;i) { printf("please ...

    指针实验实验报告.doc

    利用大小为n的指针数组指向用gets函数输入的n行,每行不超过80个字符。试编写一个 函数,它将每一行中连续的多个空格字符压缩为一个空格字符。在调用函数中输出压缩 空格后的各行,空行不予输出。 编写一个程序,...

    C标准库函数.CHM

    2.12.4.2 ...scanf Functions 2.12.5 Character I/O Functions 2.12.5.1 fgetc 2.12.5.2 fgets 2.12.5.3 fputc 2.12.5.4 fputs 2.12.5.5 getc 2.12.5.6 getchar 2.12.5.7 gets 2.12.5.8 putc 2.12.5.9 ...

    C语言FAQ 常见问题列表

    o 6.11 为什么有那么多关于空指针的疑惑?为什么这些问题如此经常地出现? o 6.12 我很困惑。我就是不能理解这些空指针一类的东西。 o 6.13 考虑到有关空指针的所有这些困惑, 难道把要求它们内部表达都必须为 0 ...

    你必须知道的495个C语言问题

    5.14 为什么有那么多关于空指针的疑惑?为什么这些问题如此频繁地出现? 5.15 有没有什么简单点儿的办法理解所有这些与空指针有关的东西呢? 5.16 考虑到有关空指针的所有这些困惑,要求它们的内部表示都必须为...

Global site tag (gtag.js) - Google Analytics