c函数---fgets,fgetc,gets,getchar,getc区别

时间:2022-08-09 01:51:26

int getch(void)    

//从标准输入读入一个字符,当你用键盘输入的时候,屏幕不显示你所输入的字符。也就是,不带回显。

int getche(void)    

//从标准输入读入一个字符,键盘输入的时候,屏幕显示所输入的字符。带回显。


这两个函数包含在头文件conio.h中,需要记住的是conio.h不是C标准库中的头文件。

Micorsoft 和 Borland的 C编译器提供了conio.h,用来创建控制台文本用户界面。

一般在Windows系统下安装了VS、VC等,就可以包含conio.h头文件。

但是一般在Unix、Linux系统中,/usr/include/中都没有这个头文件。


getch和getche在等待用户从键盘输入的时候,用户按下一个键后,不需要按回车,程序自动往下执行。

在Linux中,终端输入在缺省情况下是被“一锅端”的,也就是说整行输入是被一起处理的。

通常,这是一种人们所希望的方便的办法,但它也意味着在读入数据时必须按一下回车键表示输入行结束后才能得到输入的数据。


       #include <stdio.h>

       int fgetc(FILE *stream);
       //fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error.
       ///从流stream中读一个字符。可以将标准输入stdin作为它的实参,这时候从标准输入读取一个字符。

       char *fgets(char *s, int size, FILE *stream);
      // fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.  
      //Reading stops after an EOF or a newline.  If a
      // newline is read, it is stored into the buffer.  A '\0' is stored after the last character in the buffer.
      /从流stream中读入最多num个字符到字符数组str中,当遇到换行符时、或读到num-1个字符时停止。
   //自动加上'\0'空字符结尾

       int getc(FILE *stream);
       //getc() is equivalent to fgetc() except that it may be implemented as a macro which evaluates stream more than once.
      //和fgetc等效,由fgetc通过宏实现。
      
      
       int getchar(void);
       // getchar() is equivalent to getc(stdin).
       //从标准输入stdin读入一个字符,程序等待你输入的时候,你可以输入多个字符,回车后程序继续执行。
       //但getchar只读入一个字符

       char *gets(char *s);
       //gets() reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which it replaces with '\0'.
      // No check for buffer overrun is performed (see BUGS below).
      //从标准输入stdin读取一个字符串,遇到换行或结束时候终止。
   //不同于fgets,他没有指定num,所以需要注意字符数组str的大小。

      
       int ungetc(int c, FILE *stream);
       ungetc()  pushes c back to stream, cast to unsigned char, where it is available for subsequent read operations.  Pushed-back characters will be returned in reverse
       order; only one pushback is guaranteed.
    
    //输出函数
    int fputc ( int character, FILE * stream );
    int putc ( int character, FILE * stream );       //通过宏定义和fputc实现
    int putchar ( int character );        //通过宏定义实现:#define putchar(c) fputc(c, stdout)
    int fputs ( const char * str, FILE * stream );
    int puts ( const char * str );


    
    示例
    
    //不建议使用
    void test()
    {
        char line[512];
        gets(line);
        printf("-----\n");
        puts(line)
    }
    
    //
    void test()
    {
        FILE *fp = stdin;
        char ch;
        ch = fgetc(fp);
        while(ch != EOF)
        {
            putchar(ch);
            ch = fgetc(fp);
        }
    }
    //
    void test()
    {
        char c;
        FILE* fp = fopen("tmp","r");
        if(fp == NULL)
            perror("fopen");
        while(!feof(fp))
        {
            c = fgetc(fp);
            putchar(c);
        }
    }


//getchar()直到遇见ENTER 键才返回,返回值是第一个字符,但是后面的字符也不会被丢弃,而是保存在一个缓冲区内。

void test()
{
        int ch,cha;
        //ch = getch();
        cha = getchar();
        printf("cha=[%d]\n",cha);
        //getch();
        return;
}

void test()
{
        char c;
        while((c = getchar()) != '\n')
                printf("%c",c);
        printf("\n");
}


scanf()和getchar()函数是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取。

而读取时遇到回车(/n)而结束的,这个/n会一起读入输入流缓冲区的,所以第一次接受输入时取走字符后会留下字符/n,

这样第二次的读入函数直接从缓冲区中把/n取走了,显然读取成功了,

所以不会再从终端读取!这就是为什么这个程序只执行了一次输入操作就结束的原因


void test()
{
        char ch1,ch2;
        ch1 = getchar();
        ch2 = getchar();
        printf("%d %d\n",ch1,ch2);
}

void test10()
{
        char ch1,ch2;
        scanf("%c",&ch1);
        scanf("%c",&ch2);
        printf("%d %d\n",ch1,ch2);
}

小结:
第一:要注意不同的函数是否接受空格符、是否舍弃最后的回车符的问题!
读取字符时:
scanf()以Space、Enter、Tab结束一次输入,不会舍弃最后的回车符(即回车符会残留在缓冲区中);
getchar()以Enter结束输入,也不会舍弃最后的回车符;
读取字符串时:
scanf()以Space、Enter、Tab结束一次输入
gets()以Enter结束输入(空格不结束),接受空格,会舍弃最后的回车符!

第二:为了避免出现上述问题,必须要清空缓冲区的残留数据,可以用以下的方法解决:
方法1:c语言里提供了函数清空缓冲区,只要在读数据之前先清空缓冲区就没问题了!
       这个函数是fflush(stdin)。
方法2:自己取出缓冲区里的残留数据。
       scanf("%[^/n]",string); 扫描表为回车字符,读取时候遇到回车就停止!

getchar()函数只有在满足输入次数要求的前提下,遇到回车时才结束输入,之前所有的字符都会逐个显示在屏幕上,但是只有第一个字符返回一个ASCII码。