C语言库中自带很多I/O(输入输出)函数:

1.scanf()

从第一个非空白字符开始,遇到空白字符(空行、空格、制表符、换行符)结束,其中字符串不包括空白字符。通过转化说明(例如%d)可以输入不同的数据类型,是一个优秀的“翻译家”。

2.getchar()

读取一个字符。

3.gets(int words[])

读取整行输入,并存储字符和\\0到words中,丢弃换行符/不检查溢出/默认从屏幕读入。

4.fgets(int word[], int arrsize, stdin/stdout)

读取整行输入,存储arrsize-1个字符和一个\\0到word中,不丢弃换行符/检查溢出/会指明读入文件(如果读到第一个是\\n则存储\\n,然后停止读取)。

5.gets_s(int word[], int arrsize)

读取整行输入,存储arrsize-1个字符和一个\\0到word中,丢弃换行符/检查溢出/默认从屏幕读入(如果>=arrsize则有可能导致程序终止)。

在需要输入字符串时,我们通常要用到gets(),fgets(),gets_s()这三个函数,在此,我们来比较一下三个函数的适用性。如果目标存储区装得下输入行,三个函数都没问题

如果输入行太长。

使用get()函数不安全,他会擦写现有数据,存在安全隐患

因为get()的唯一参数是words,它无法检查数组是否装得下输入行。如果输入的字符串过长,会导致缓冲区溢出,即多余的字符超出了指定的目标空间。如果这些多余的字符只是占用了尚未使用的内存,就不会立即出现问题;如果它们擦写掉程序中的其他数据,会导致程序异常中止。

使用gets_s()函数和fget()函数类似,用一个参数限制读入的字符数。

但gets_s()函数只从标准输入中读取数据,所以不需要第三个参数。如果gets_s()函数读到换行符,会丢弃它而不是储存它。如果gets_s()函数读到最大字符数都没有读到换行符,会执行以下几步。首先把目标数组中的首字符设置为空字符,读取并丢弃随后的输入直至读到换行符或文件结尾,然后返回空指针。接着,调用依赖实现的“处理函数”(或你选择的其他函数),可能会终止或退出程序。

使用fgets()函数会把换行符放在字符串的末尾(假设输入行不溢出)。

如以下程序:

下面是该程序的输出实例:

可以发现,在输入的“abcde”和“=====”之间有一个换行符“\n”。

系统使用缓冲的I/O。这意味着用户在按下回车键之前,输入都被存储在临时存储区(即,缓冲区)中。按下回车键就在输入中增加了一个换行符,并把整行输入发送给fgets()函数。对于输出,fputs()函数把字符发送给另一个缓冲区,当发送换行符时,缓冲区的内容被发送到屏幕上。

fgets()函数存储换行符有好处也有坏处。坏处是你可能并不想把换行符存储在字符串中,这样的换行符会带来一些麻烦。好处是对于存储的字符串而言,检查末尾是否有换行符可以判断是否读取了一整行。如果不是一整行,要妥善处理一行中剩下的字符。

由此可见,当输入太长时,超过数组可容纳的字符数时,fgets()函数最容易使用,而且可以选择不同的处理方式。

我们可以定义一个s_gets()函数去掉fgets()函数存储在字符串中的换行符。

具体代码如下:

测试它:

输出如下:

s_get()函数也有缺陷是遇到不合适的输入毫无反应,它丢弃多余的字符时,既不通知程序也不告知用户,但是用来替换程序中的fgets()函数就足够了。