C语言scanf函数与空格_c语言scanf读一个单词会取空格吗_xiancaifu的博客-程序员秘密

技术标签: 语言  c  C语言  测试  终端  

| 问题描述一:(scanf()读入字符串中的空格)   |
----------------------------------------------------

#include<stdio.h>
int main()
{
   char a[777];
   scanf("%[^/n]",&a);
   printf("%s",a);
   return 0;
}

说明:
scanf函数中,可以使用 %c来读取一个字符,使用 %s 读取一个字符串,但
是读取字符串时不忽略空格,读字符串时忽略开始的空格,并且读到空格为止,因此只能读取一个单词,而不是整行字符串,因此一般使用fgets来读取一个字符串。其实scanf函数也可完成这样的功能,而且还更强大。这里主要介绍一个参数,%[ ],这个参数的意义是读入一个字符集合。[ ]是个集合的标志,因此%[ ]特指读入此集合所限定的那些字符, 比如 %[A-Z] 是输入大写字母,一旦遇到不在此集合的字符便停止。如果集合的第一个字符是" ^ ", 这说明读取不在" ^ " 后面集合的字符,既遇到" ^ " 后面集合的字符便停止.注意此时读入的字符串是可以含有空格的。

----------------------------------------------------
| 问题描述二:(分析scanf()和getchar()读取字符)
   |
----------------------------------------------------
    scanf(), getchar()等都是标准输入函数,一般人都会觉得这几个函数非常简单,没什么特殊的。但是有时候却就是因为使用这些函数除了问题,却找不出其中的原因。下面先看一个很简单的程序:

程序1:
    #include <stdio.h>
    int main()
    {
char ch1, ch2;
scanf("%c", &ch1);
scanf("%c", &ch2);
printf("%d %d/n", ch1, ch2);
return 0;
    }
   
或者是:
    #include <stdio.h>
    int main()
    {
char ch1, ch2;
ch1 = getchar();
ch2 = getchar();
printf("%d %d/n", ch1, ch2);
return 0;
    }
   
程序的本意很简单,就是从键盘读入两个字符,然后打印出这两个字符的ASCII码值。可是执行程序后会发现除了问题:当从键盘输入一个字符后,就打印出了结果,根本就没有输入第二个字符程序就结束了。例如用户输入字符'a', 打印结果是97,10。这是为什么呢?

【分析】:
    首先我们呢看一下输入操作的原理, 程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,

当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入

这就是例子中为什么会出现输入语句失效的原因!


    其实这里的10恰好是回车符!这是因为scanf()和getchar()函数是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取。而读取时遇到回车(/n)而结束的,这个/n会一起读入输入流缓冲区的,所以第一次接受输入时取走字符后会留下字符/n,这样第二次的读入函数直接从缓冲区中把/n取走了,显然读取成功了,所以不会再从终端读取!这就是为什么这个程序只执行了一次输入操作就结束的原因!

----------------------------------------------------
| 问题描述二:(分析scanf()和gets()读取字符串)
   |
----------------------------------------------------
首先我们看一下scanf()读取字符串的问题:

程序2:
    #include <stdio.h>
    int main()
    {
char str1[20], str2[20];
scanf("%s",str1);
printf("%s/n",str1);   
scanf("%s",str2);
printf("%s/n",str2);
return 0;
    }
   
程序的功能是读入一个字符串输出,再读入一个字符串输出。可我们会发现输入的字符串中不能出现空格,例如:
测试一输入:
Hello world!
输出:
Hello
world!
【分析】到此程序执行完毕,不会执行第二次的读取操作!这个问题的原因跟问题一类似,第一次输入Hello world!后,字符串Hello world!都会被读到输入缓冲区中,而scanf()函数取数据是遇到回车、空格、TAB就会停止,也就是第一个scanf()会取出"Hello",而"world!"还在缓冲区中,这样第二个scanf会直接取出这些数据,而不会等待从终端输入。

测试二:
Hello[Enter]
Hello[
输出]
world[Enter]
world[输出
]
【分析】程序执行了两次从键盘读入字符串,说明第一次输入结束时的回车符被丢弃!即:scanf()读取字符串会舍弃最后的回车符


我们再看一下gets()读取字符串的情况:
用scanf来读取一个字符串时,字符串中是不可以出现空格的,一旦出现空格,后面的数据就会舍弃残留在缓冲区中。其实有另外一个函数是可以接受空格的,那就是gets(),下面我们看一下这个函数的应用,我们把程序2改动一下:
程序3:
#include <stdio.h>
int main()
{
char str1[20], str2[20];
gets(str1);
printf("%s/n",str1);   
gets(str2);
printf("%s/n",str2);
return 0;
}
测试:
Hello world! [输入]
Hello world! [输出
]
12345 [输入
]
12345 [输出
]
【分析】显然与上一个程序的执行情况不同,这次程序执行了两次从键盘的读入,而且第一个字符串取了Hello world! 接受了空格符,而没有像上一个程序那样分成了两个字符串!所以
如果要读入一个带空格符的字符串时因该用gets(), 而不宜用scanf()!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xiancaifu/article/details/6076289

智能推荐

【Unity3D日常开发】Unity3D中实现手势控制模型放大缩小_unity3d点击按钮放大缩小_恬静的小魔龙的博客-程序员秘密

手势控制模型放大缩小是交互中比较常见的功能,今天就来看一下怎么实现吧先看一下效果步骤:先新建一个Cube,调整一下位置和大小新建脚本Gesture.cs,将脚本Gesture挂在Cube上编写脚本Gesture.csusing UnityEngine;using System.Collections;public class Gesture : MonoBe...

随机森林中,为什么oob样本的数量是三分之一_随机森林袋外数据为何是1/3_大哲子的博客-程序员秘密

今天看了RF,发现里面有一个1/3的概率,到底怎么求出来的,我看了数,推了一下公式。模型评估方法在机器学习中,通常把样本分成训练集和测试集,在划分样本的过程中,存在着不同的抽样方法。有哪些抽样方法,他们有什么优缺点1.Holdout检验直接样原始样本37分,70%为训练集,30%为测试集。绘制ROC曲线,计算准确率,召回率。缺点:没有随机性。2. 交叉检验将全部样本划分成K个大小相...

Deepin安装Docker+DockerMySQL5.7_Baldwin_KeepMind的博客-程序员秘密

更多文章请点击文章目录1. 背景2. 安装docker2.1. 获取官网教程2.2. 卸载旧版本2.3. 安装docker更新库安装docker库添加Docker官方GPG key执行命令检查key添加库安装引擎检查安装小总结3. docker安装MySQL3.1 查找所需版本3.2. 执行安装命令4. Docker镜像加速4.1. 常用国内源4.2. 添加国内源获取源地址配置国内加速源小总结5...

面试题:找出n个降序链表中的第k大的值_寻找链表中第k大的数_. 时光吹不老好少年,的博客-程序员秘密

面试题:找出n个降序链表中的第k大的值题目描述:给定n个链表,每个链表中的元素都分别是降序排列的,找出n个链表所包含的所有数中的第k大的值。示例:给定3个降序链表,找出第4大的值。9 -&gt; 6 -&gt; 210 -&gt; 3 -&gt; 2 -&gt; 15 -&gt; 1要找的第4大的值应该为5。思路:利用C++的优先队列,其为大根堆的实现。优先队列存储链表结点,同时需要自定义比较方法。将每个链表的头结点都入堆,结点元素最大的结点会位于堆顶。弹出该结点,并且若该结点还有下一个结点,

Bailian2804 词典【map+字典树】_海岛Blog的博客-程序员秘密

2804:词典描述你旅游到了一个国外的城市。那里的人们说的外国语言你不能理解。不过幸运的是,你有一本词典可以帮助你。输入首先输入一个词典,词典中包含不超过100000个词条,每个词条占据一行。每一个词条包括一个英文单词和一个外语单词,两个单词之间用一个空格隔开。而且在词典中不会有某个外语单词出现超过两次。词典之后是一个空行,然后给出一个由外语单词组成的文档,文档不超过100000行,而且每...

随便推点

推荐给大家,java随机抽题系统_java随机推荐_普通网友的博客-程序员秘密

前言Spring无论在Java生态系统,还是在就业市场,是绝对的王者。大厂面试出镜率之高,投产规模之广,无出其右。随着技术的发展,Spring 从往日的 IoC 框架,已发展成 Cloud Native 基础设施,衍生出大量 Spring 技术栈,如大家熟知的 Spring Boot、Spring Cloud 和 Spring Security 等。我相信很多程序员不管是在面试中,还是在日常开发中,总会面临各种挑战和考验,唯有系统性地掌握 Spring编程思想、设计理念,以及具体的实现方式,方可游刃有余

CVPR 2020 oral:亮风台提出完全可训练的图匹配方法_我爱计算机视觉的博客-程序员秘密

本文为亮风台公司投稿。6月14日-19日,CVPR 2020在线上举行,据了解,本届大会共收到6656篇投稿,接收论文1470篇,录用率约22%,低于ICCV 2019论文录用率(25%...

windows10用IIS搭建WordPress(apache24+mysql5.7+php7.2)_liar771的博客-程序员秘密

准备首先保证安装过Visual C++ Redistributable for Visual Studio 2015下载免安装版Apache&amp;amp;PHP&amp;amp;Mysql下载完成后找一个非中文目录解压 添加系统环境变量,根据自己解压的目录自行修改 D:\ASP\Apache24\bin D:\ASP\mysql-5.7\bin D:\ASP\php7.2 D:\ASP\...

Tensorflow:softmax处理Iris鸾尾花分类_Icoding_F2014的博客-程序员秘密

经典的分类模型,鸾尾花的分类。 数据集样例: length sepal width petal length petal width class 5.1 3.5 1.4 0.2 Iris-setosa 4.9 3 1.4 0.2 Iris-versicolor 4.7 3.2 1.3 0.2 Iris-virginica

ArcGIS模型构建器前提条件的应用(附省界县点练习数据)_GIS前沿的博客-程序员秘密

这次的模型依旧很简单,主要是介绍前提条件在模型构建器中的应用新建模型我就不讲了,之前都说过可参考:ArcGIS模型构建器操作案例——提取相关属性信息首先先简单介绍一下这次模型的功能,就是我们要用省级行政区划边界和全国的县城点来提取出该省县城位置首先我们先想一下,我们正常的操作流程,是新建一个文件夹和gdb数据库,然后再按照操作流程创建模型那么我们可不可以将创建gdb数据库在创建模型的过程中,一并自动创建呢,当然是可以的,我们可以将创建gdb数据库这个流程当做我们运行模型的前提条件,然后一并创建.

matlab 不规则三角网,[转载]不规则三角网(TIN)生成等高线的算法_冯意番的博客-程序员秘密

根据离散点的三维坐标生成等高线的方法主要有网格法和三角网法。三角网方法相比与网格法,能够用较少的空间和时间更精确的拟合复杂地表面,因而得到了广泛的应用。本文主要介绍三角网法生成等高线的算法。下一篇文章用代码实现。1.构造狄洛尼三角在狄洛尼法中将离散分布的地形点称为“参考点”。构成狄洛尼三角网时规定:“每个参考点组成的三角形的外接圆都不包含其他参考点”。其计算方法如下:1)任取一个参考点作为起始点P...

推荐文章

热门文章

相关标签