关于scanf()函数的一点理解

习惯了c++的cin.cout之后,也不怎么关注空格,反正cin.cout会自动处理。有一次实验,创建Huffman树,要求输入空格字符,当时就懵逼了.cin咋输入空格呢?

没办法,只能重新用scanf函数了,结果各种悲剧,足足debug一个多小时,这难道就是越学越差劲系列?o(╯□╰)o

scanf()和printf()严格来说并不是c的一部分,当我们用scanf()函数输入数据时,只要不回车,数据就暂存在缓冲区。因此我们可以输入一下

回车一下,也可以全部输完再回车,一般来说这两者没啥区别,但遇到字符输入时就需要格外注意了。

比如输入空格和数字

空格 12(空格的ASCII码值为32)

代码:

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
    char a;
    int b;
    scanf("%c %d",&a,&b);
    cout<<(int)a<<endl;
    cout<<b<<endl;
    return 0;
}

输入空格和12,然后回车,这显然没什么问题

在这基础上,我们做一下改动

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
    char a,a1;
    int b,b1;
    scanf("%c %d",&a,&b);
    scanf("%c %d",&a1,&b1);
    cout<<(int)a<<endl;
    cout<<b<<endl;
    cout<<a1<<endl;
    cout<<b1<<endl;
    return 0;
}

当我们输入a,b后,能不能回车,再输入a1,b1.答案是不能,因为回车被a1给吸收了(o(╯□╰)o)(大一的时候对着明明很清楚的诶,咋忘了呢?)

我们再来做一下改动,我们不想写多个scanf(),改为for循环控制

代码:

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
    char a;
    int b;
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
    scanf("%c %d",&a,&b);
    cout<<(int)a<<endl;
    cout<<b<<endl;
    }
    return 0;
}

大家可能觉得这没什么问题,但输入n之后回车的话,就会悲剧,所以需要在cin>>n后加一个getchar();同时scanf()也要加一个getchar();

正确的代码:

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
    char a;
    int b;
    int n;
    cin>>n;
    getchar();
    for(int i=1;i<=n;i++){
    scanf("%c %d",&a,&b);
    getchar();
    cout<<a<<endl;
    cout<<b<<endl;
    }
    return 0;
}

(ps:嘛,事实上可以用scanf(" %c",&a))这种形式吸收空格和回车(%c前面留个空格))

还有求各位juju不要喷本弱鸡(o(╯□╰)o)

时间: 2024-10-20 10:26:40

关于scanf()函数的一点理解的相关文章

对JS回调函数的一点理解

之前写的异步JS是纯译文,现在刚好工作了2个月,想谈谈我自己对JS回调函数的一点理解,欢迎渴望大家的指正和交流. 回调函数从形式上看就是把函数b作为参数传给函数a,在a的函数体里调用函数b 1 function a(b) { 2 b(); 3 } 4 function b() { 5 ... 6 } 这样做的意义是什么呢 1.控制执行流程,函数b只能在函数a执行后才执行 2.根据不同的需求,可以有各种各样的函数b 3.最重要的,是可以把通过函数a获取的数据传递给函数b 1 function a(

黑马程序员————C语言基本语法(关键字、标识符、注释符、变量、Scanf函数)

第一讲 关键字 1.什么是关键字? 1) 关键字就是C语言提供的有特殊含义的符号,也叫做“保留字” 2) C语言一共提供了32个关键字,这些关键字都被C语言赋予了特殊含义 C语言关键字 auto局部变量(自动储存) break 无条件退出程序最内层循环 case   switch 语句中选择项 char  单字节整型数据 const  定义不可更改的常量值 continue 中断本次循环,并转向下一次循环 default switch 语句中的默认选择项 do  用于构成do.....while

线程的一点理解

一.线程起源 线程的产生基于通过共享公共的内存空间来交换数据可提高协作进程间的通信效率这一思想.线程是程序执行流的最小单元,是进程中的一个实体,一个标准的线程由线程ID.寄存器集合和堆栈组成.是被系统独立调度和分配的基本单位.线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源.一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行.由于线程之间的相互制约,致使线程在运行中呈现出间断性. 在某一时刻,进程内只有一个称为

05-C语言scanf函数

一. 变量的内存分析 1. 字节和地址 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的"字节"和"地址". 1> 内存以"字节为单位" 0x表示的是十六进制,不用过于纠结,能看懂这些数字之间谁大谁小就行了 2> 不同类型占用的字节是不一样的,数据越大,所需的字节数就越多 2. 变量的存储 1> 所占用字节数跟类型有关,也跟编译器环境有关 2> 变量实例 int b = 10; int a = 20; l 内存由

关于C中scanf()函数读取字符串的问题

1 #include <stdio.h> 2 3 int main(void) 4 { 5 char s_name[20]; 6 7 scanf("%s", s_name); 8 printf("Hello, %s!\n", s_name); 9 10 return 0; 11 } 对于这段简单的代码,如果输入一个名字如:Stephen,很容易知道,其输出为: Hello, Stephen! 这个很容易理解,但是输入更完整的名字如:Stephen Pra

Android measure和layout的一点理解

首先,推荐文章,http://blog.csdn.net/hqdoremi/article/details/9980481,http://www.docin.com/p-571954086.html 我理解measure的作用有2个:一个就是调用子view的measure函数,生成他们的高度和宽度,以便在自己的layout阶段参考:另一个是为父view提供关于自己的测量的width和height(这个宽度和高度往往和子view的测量高度和宽度有关),以便父view在layout阶段参考. lay

关于进程的一点理解

一.什么是进程? 进程包含存储在文件中的一组指令,该文件被读入内存并执行.正在执行的每个唯一的实例被称为进程,并且给它唯一一个标识,成为进程ID,它由操作系统确定.比如你在电脑中同时打开两个QQ,那么这两个程序就叫做进程,而且有两个不同的ID号. 二.进程如何创建? 被称为子进程的新进程由父进程的已存在的进程通过调用fork函数创建. pid=fork();//fork函数回传给pid的值是新进程的ID,数据类型为pid_t,属于int型. 子进程被创建为父进程的一个副本. fork函数在成功时

C语言scanf函数详解

函数名: scanf 功 能: 运行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息.能够读入不论什么固有类型的数据并自己主动把数值变换成适当的机内格式. 其调用格式为:      scanf("<格式化字符串>",<地址表>); scanf()函数返回成功赋值的数据项数,出错时则返回EOF. 其控制串由三类字符构成: 1.格

C语言笔记之scanf函数

直接摘抄<C Primer Plus>算求,太经典了,我再偷把懒,就当复习了- 一.概述 从键盘输入的是文本,因为那些键生成文本字符: 字母.数字和标点.比如说,当您想输入整数2004时,您键入字符2. 0. 0和 4 ,如果想把它们存储成4个数值而非字符串,那么您的程序必须把这个字符串逐个字符地转换成数值,这就是scanf()所做的工作!它把输入的字符串转换成各种形式:整数.浮点数.字符和 C的字符串.它是 printf()的逆操作,后者把整数.浮点数.字符和 C的字符串转换成要在屏幕上显示