stdio.h中的那些API--gets,fgets,getchar,scanf

时间:2021-01-23 01:48:23

首先这4个函数都是获取输入数据的接口,且容我一一道来

1.char *gets(char *str)

功能:从标准输入获取string

    从标准输入读取字符,并作为string存入参数str中,在遇到换行符'\n'或EOF(文件结束符)时停止读取。'\0'会自动追加到最后一个字符之后。

NOTE:gets跟fgets的一些区别:1)'\n'不会包含在str中,而fgets的会

                           2)gets没有提供机制让你设定有多少个字符会被读入,而fgets会,因此使用gets的时候,要注意str指向的buffer是否会溢出。

参数:str

指向用来存取C string的buffer的指针

返回值:

成功,返回str字符串

如果没有读取任何字符就遇到了EOF,那么str保持不变,并返回NULL指针

失败,返回NULL指针

可以用ferror和feof来检查是什么原因导致NULL指针的返回。

/* 
 * File:   main.cpp
 * Author: Carl
 *
 * Created on 2012年9月6日, 下午9:03
 */

#include <cstdlib>
#include <cstdio>

int test_gets()
{
    char string[20] = {0};
    printf("Insert your full address:");
    gets(string);
    printf("Your address is: %s\n", string);//注意最后的'\n'符,否则输出不会换行的哦
    
    return 0;
}

int main(int argc, char** argv)
{
    test_gets();
    return 0;
}

g++ main.cpp 得到可执行文件a.out

$./a.out

执行如下

[carl@Fedora test_stdio]$ ./a.out 
Insert your full address:hello
Your address is: hello
[carl@Fedora test_stdio]$ ./a.out 
Insert your full address:kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Your address is: kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Segmentation fault

2.char *fgets(char *str, int num, FILE *stream);

功能:从stream中读取字符,并作为C string存入到str中,在读取num-1个字符,或遇到'\n'、EOF时,停止读取,3个条件满足一个就立即停止

NOTE:‘\n'使fgets停止读取,并被认作合法字符,包含在str中,'\0'会被自动追加到最后一个读取的字符之后。

参数:

str: 指向用来存放string的char数组的指针

num:被读取的最大字符数目(包括'\0'字符),通常用str数组的长度

stream:指针,指向一个FILE对象,fgets从这个对象中读取字符。要从标准输入读取,可用stdin作为实参。

返回值:

成功,返回str字符串

如果没有读取任何字符就遇到了EOF,那么str保持不变,并返回NULL指针

失败,返回NULL指针

可以用ferror和feof来检查是什么原因导致NULL指针的返回。

#include <cstdlib>
#include <cstdio>

int test_fgets()
{
    FILE *pFile = NULL;
    char mystring[25] = {0};
    
    pFile = fopen("myfile.txt", "r");
    if (pFile == NULL)
    {
        perror("Error opening file");
    }
    else
    {
        if (fgets(mystring, sizeof(mystring), pFile) != NULL)
        {
            puts(mystring);
        }
        fclose(pFile);
    }
    
    return 0;
}

int main(int argc, char** argv)
{
    test_fgets();
    return 0;
}

g++ main.cpp

如果我的myfile.txt如下

this is 
the first line
this is the 2nd line
this is the 3rd line

执行结果为:

[carl@Fedora test_stdio]$ ./a.out 
this is 

[carl@Fedora test_stdio]$

如果myfile.txt如下:

this is the first line
this is the 2nd line
this is the 3rd line

执行结果如下

[carl@Fedora test_stdio]$ ./a.out 
this is the first line

[carl@Fedora test_stdio]$

跟gets比起来,fgets可以在第2个参数设置最多可读入的字符数,有效防止溢出,更安全一点


3.int getchar(void); //注意函数类型为int哦,不是char哦stdio.h中的那些API--gets,fgets,getchar,scanf

功能:返回从标准输入的下一个字符

参数:无

返回值:

字符作为一个int型值被返回

如果遇到EOF或者读取错误,函数返回EOF,并且相应的error或EOF标识被设置。可以用ferror和feof来检查是读取错误还是遇到EOF

/* 
 * File:   main.cpp
 * Author: Carl
 *
 * Created on 2012年9月6日, 下午9:03
 */

#include <cstdlib>
#include <cstdio>

int test_getchar()
{
    char c;
    puts("Enter text. Include a dot('.') in a sentence to exit:");
    do
    {
        c = getchar();
        putchar(c);
    } while(c != '.');
    putchar('\n');
    
    return 0;
}

int main(int argc, char** argv)
{
    test_getchar();
    return 0;
}

g++ main.cpp

执行结果如下

[carl@Fedora test_stdio]$ ./a.out 
Enter text. Include a dot('.') in a sentence to exit:
hello world.
hello world.
[carl@Fedora test_stdio]$ ./a.out 
Enter text. Include a dot('.') in a sentence to exit:
hello world.kjdksjalkfsaldsjljfksk;samsjljsaljfjsajaslaskdsa......
hello world.
[carl@Fedora test_stdio]$ ./a.out 
Enter text. Include a dot('.') in a sentence to exit:
h
h
lo
lo
.
.
[carl@Fedora test_stdio]$ ./a.out 
Enter text. Include a dot('.') in a sentence to exit:
hello world.
hello world.
[carl@Fedora test_stdio]$ ./a.out 
Enter text. Include a dot('.') in a sentence to exit:
hello world.helkdksaksaklksajsaf
hello world.
[carl@Fedora test_stdio]$ h
-bash: h: command not found
[carl@Fedora test_stdio]$ ./a.out 
Enter text. Include a dot('.') in a sentence to exit:
hel
hel
llo
llo
.
.
[carl@Fedora test_stdio]$ 

4.int scanf(const char *format, ...);

功能:从标准输入读入格式化数据

     从标准输入读入数据,并根据format参数指明的格式来存取到另一个参数所指定的位置。该“另外的参数”应该执行已经分配了内存空间的对象,并且对象类型与format中的格式标识想匹配。

参数:

format

     1)空白字符:该函数会读取并忽略掉下一个非空字符之前的任何空白字符(包括空格,tab,换行符),任意个或者零个

     2)非空字符,除了%:非空白符和格式标示符(%开头的)的任意字符会使函数从标准输入读取下一个字符,并与该非空字符比较,如果相同,则丢弃掉,函数继续根据format进行读取,否则函数失败,返回,并保留一个从标准输入未读取的字串

     3)格式标示符:以%开头的,用来表示数据的类型与格式。格式标示符遵循协议:%[*][width][modifier]type

where:

* 一个可选的星号,表示数据可以从标准输入获取,但被忽略。例如,它不会被存在相关的参数中。
width 指明当前读取选项可读取的最大数目的字符数
modifiers 指定一个跟int,unsigned int,float不同的size:
h : short int (for d, i and n), orunsigned short int (foro,u and x)
l : long int (for d, i and n), orunsigned long int (foro,u and x), or double (fore, f andg)
L : long double (for e, f and g)
type 一个字符,指定了数据类型

scanf 类型标示符:

类型 说明 参数类型
c 单个字符,不会自动追加'\0' char *
d 十进制整数:可加+ - 前缀 int *
e,E,f,g,G 浮点型:含小数点的十进制整数,可选+ -前缀,可选e/E加一个十进制数,例如-732.103,7.12e4 float *
o 八进制整数 int *
s 字符串:读取一系列字符,遇到空白符停止,空白符包括:空格,换行,tab char *
u 无符号十进制整数 unsigned int *
x,X 十六进制整数 int *
附加参数:

       该函数需要一系列引用作为附加参数,每一个指向一个类型与%-tag匹配的对象。

       int n;

       scanf("%d", &n);

返回值:

成功,返回成功读取的对象数目,这个数据跟期待数目会相同,或者遇到匹配失败会比期待的数目要少

如果一个都没读到就读取失败了,EOF就会被返回。

/* 
 * File:   main.cpp
 * Author: Carl
 *
 * Created on 2012年9月6日, 下午9:03
 */

#include <cstdlib>
#include <cstdio>

int test_scanf()
{
    char str[80];
    int  i;
    
    printf("Enter your family name: ");
    scanf("%s", str);  //str可看成一个指针
    printf("Enter your age: ");
    scanf("%d", &i);
    printf("Mr. %s , %d years old.\n", str, i);
    printf("Enter a hexadecimal number: ");
    scanf("%x", &i);
    printf("You have entered %#x (%d).\n", i, i);
    
    return 0;
}

int main(int argc, char** argv)
{
    test_scanf();
    return 0;
}

g++ main.cpp

执行结果:

[carl@Fedora test_stdio]$ g++ main.cpp 
[carl@Fedora test_stdio]$ ./a.out 
Enter your family name: wang
Enter your age: 26
Mr. wang , 26 years old.
Enter a hexadecimal number: ff
You have entered 0xff (255).
[carl@Fedora test_stdio]$ 


水平有限,如果有朋友发现错误,欢迎留言交流。
转载请保留本文链接,如果觉得我的文章能帮到您,请顶一下。,谢谢。