引言:假设想把一个字符串读到程序中。必须首先预留存储字符串的空间。然后使用输入函数来获取这个字符串。



读取字符串输入的第一件事是建立一个空间以存放读入的字符串。

char *name;

scanf("%s", name);

这段代码尽管可能通过编译,但由于name能够指向不论什么地方,所以它的输入值可能覆盖曾经name所指位置的值。

解决的方法是声明一个固定大小的字符数组,或者使用C库里的分配存储空间的函数。



1、gets函数从系统标准输入获得一个字符串。读取字符串直到遇到一个换行符(\n)。它读取换行符之前的全部字符。在这些字符后加入一个空字符(\0),然后把这个字符串交给调用它的程序。它把读取的换行符直接丢弃。而不是把它放入字符串中,这与以下讨论的fgets函数不同,以下再给出样例证明这一点。

#include <stdio.h>

char *gets(char *s);

演示样例:

#include <stdio.h>

#define MAX 18

int
main(int argc, char **argv)
{
char name[MAX];
char *ptr;
printf("what't your name?\n");
ptr = gets(name); /*注意:gets()返回的指针与传递给它的是同一个指针*/
printf("%s? Ah ! %s\n", ptr, name);
return 0;
}

注意,假设gets出错时它返回一个空地址,因此在使用时一般使用例如以下技巧:

while((ptr = gets(name)) != NULL){
……
}



2、gets函数的一个不足是它不检查预留存储区是否可以容纳实际输入的数据。多出来的字符简单地溢出到相邻的内存区。fgets()函数改进了这个问题。它可以指定最大读入字符数。fgets()和gets()有3点不同:

a、它须要第二个參数来说明组大读入字符数。

假设这个參数值为n,fgets()就会读取最多n-1个字符或者读完一个换行符为止。

b、假设fgets读取到换行符。就会把它存放在字符串里。而不是像gets()那样丢弃它。也就是说它在字符串的最后存放的是换行符(\n),而不是空字符(\0)。

c、它还须要第三个參数来说明读哪一个文件。

#include <stdio.h>

char *fgets(char *s, int size, FILE *strem);

演示样例

#include <stdio.h>

#define MAX 18

int
main(int argc, char **argv)
{
char name[MAX];
char *ptr;
printf("what't your name? \n");
ptr = fgets(name, MAX, stdin);
printf("%s? Ah ! %s\n", ptr, name);
return 0;
}

编译測试结果显示:

what't your name?
libing
libing
? Ah ! libing

它显示了fgets()的一个不足之处,fgets()把换行符存储到字符串里了。这样每次显示字符串时就会显示换行符。



以下对fgets()和gets()两个函数对于换行符不同处理的演示样例证明:

#include <stdio.h>

#define MAX 18

int
main(int argc, char **argv)
{
char name1[MAX];
char name2[MAX];
char *ptr;
printf("what't your name?\n");
ptr = fgets(name1, MAX, stdin);
ptr = gets(name2);
if(strcmp(name1, name2)){<span style="white-space:pre"> </span>/*比較两个字符串,由于gets会在最后将\n改为\0存入字符串,而fgets会直接将\n存入字符串*/
printf("name1 is not equal name2\n");
}
return 0;
}



3、scanf()和gets()基本的区别在于它们假设决定字符串何时结束。scanf()更给予获取单词而不是获取字符串;而gets()函数,会读取全部的字符,直到遇到第一个换行符为止。scanf()使用两种方法决定输入结束。假设使用%s格式。字符串读到下一个空白字符。假设指定了字段宽度,比方%10s,scanf()就会读入10个字符或直到遇到第一个空白字符。由二者中最先满足的哪一个终止输入。

#include <stdio.h>

int
main(void)
{
char name1[11], name2[11];
int count; while(1){
printf("please input 2 names.\n");
count = scanf("%5s %10s", name1, name2);
printf("I read the %d names %s and %s.\n"
,count, name1, name2); }
return 0;
}

执行执行測试:

please input 2 names.
Jesse Jukes
I read the 2 names Jesse and Jukes.
please input 2 names.
Liza Applebottham
I read the 2 names Liza and Applebotth.
please input 2 names.
Portensia Callowit
I read the 2 names am and Portensia.
please input 2 names.
I read the 2 names Callo and wit.







【C语言天天练(十五)】字符串输入函数fgets、gets和scanf的更多相关文章

  1. python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  2. C语言程序设计(十) 字符串

    第十章 字符串 字符串常量是由一对双引号括起来的一个字符串序列 字符串实际就是由若干个有效数字构成且以字符'\0'作为结束的一个字符序列 C语言没有提供字符串数据类型,因此字符串的存取要用字符型数组来 ...

  3. 【C语言天天练(十)】结构体

    引言:数据常常以成组的形式存在.在C中,使用结构能够把不同类型的值存放在一起. 结构的声明有两种 1.struct SIMPLE{ int a; char b; float c; };然后用标签SIM ...

  4. 【C语言天天练(十九)】restrict关键词

    引言:在内核的系统调用函数里,常常遇到函数的參数使用restrict限定词限定的情况,以下就对该关键词做个总结. 1.restrict关键词是C99特性才加入的,因此在编译使用含有该限定词的程序时,一 ...

  5. 【C语言天天练(二)】预处理

    引言: 学C语言之初.一提到预处理,脑子里想到的就是#define的宏定义以及#include包括的头文件.后来随着对C的深入学习发现.预处理不止这些.比方条件编译.提前定义的宏等等.以下对此进行总结 ...

  6. Go语言核心36讲(Go语言进阶技术十五)--学习笔记

    21 | panic函数.recover函数以及defer语句 (上) 在本篇,我要给你展示 Go 语言的另外一种错误处理方式.不过,严格来说,它处理的不是错误,而是异常,并且是一种在我们意料之外的程 ...

  7. 【C语言天天练(二一)】内联函数

            引言:调用函数时,一般会由于建立调用.传递參数.跳转到函数代码并返回等花费掉一些时间,C语言的解决的方法是使用类函数宏.在C99中,还提出了第二种方法:内联函数.         内联 ...

  8. 【C语言天天练(二四)】内存分配

    引言: 对于C语言程序,了解它执行时在内存中是怎样分配的对于我们理解它的执行机制是很实用的.以下就总结一下C语言程序的一些内存分配知识. 一 一段C程序.编译连接后形成的可运行文件一般有代码段.数据段 ...

  9. 苹果新的编程语言 Swift 语言进阶(十五)--协议

    协议定义了适合某个特定任务或功能需要的方法.属性和其它需求的一个蓝图.协议本身不提供这些需求的实现,它只是描述了一个任务或功能实现的蓝图. 协议与java 语言中的接口定义类似,都是描述了一个实现可以 ...

随机推荐

  1. 转: AlphaImageLoader简介

    Microsoft.AlphaImageLoader是IE滤镜的一种,其主要作用就是对图片进行透明处理.虽然FireFox和IE7以上的IE浏览器已经支持透明的PNG图片,但是就IE5-IE6而言还是 ...

  2. DG创建和提取虚拟机文件

    http://www.cr173.com/soft/33359.html http://www.diskgenius.cn/help/newvmdk.php

  3. Qt Chart 5.7.0 傻瓜安装教程

    前提 qtchart 里的README文件(注意红色标记处)(本人翻译不行.多多见谅,也可以在评论里纠正( ⊙ o ⊙ )) --------------- Qt Charts 5.7.0 ----- ...

  4. JProtector java应用加密工具

    JProtector    专业的java项目加密工具 JProtector简介: JProtector 专业的java项目加密工具.目前java开发的项目发布的时候需要将项目发布到用户手中,但由于一 ...

  5. docker学习笔记14:Dockerfile 指令 ENV介绍

    ENV指令用来在镜像构建过程中设置环境变量.我们来看一个Dockerfile的例子: #test FROM ubuntu MAINTAINER hello ENV MYDIR /mydir RUN m ...

  6. Shell中的if else语句小演示

    安安静静学习小shell,今天看到if else 喽~ 下面这个脚本是判断用户执行脚本的参数,如果是hello的话,就显示how are you 如果什么都没有,就提示输入 如果参数不是hello,就 ...

  7. HTML5实现IP Camera网页输出

    HTML5实现IP Camera网页输出 这两天做OA项目.有一个要通过IP Camera将视频流输出到浏览器端的模块.尽管如今买到的摄像头都会提供浏览器和client的实现,可是一般来说都是仅仅支持 ...

  8. Oracle中查询各种对象的方法小结

    --查看当前库中的所有表select * from all_tables a where a.table_name='INFOCODE_P20081'--查看表结构select * from all_ ...

  9. LVS--什么是LVS?

    1.什么是LVS? 首先简单介绍一下LVS (Linux Virtual Server)到底是什么东西,其实它是一种集群(Cluster)技术,采用IP负载均衡技术和基于内容请求分发技术.调度器具有很 ...

  10. 读书笔记:php_tizag_tutorial

    昨天在实验室花了一天时间看了英文版的php_tizag_tutorial,因为上学期用php和bootstrap写过一个租房网站,对php还是比较熟悉.现在总结一下php_tizag_tutorial ...