一、scanf家族

1、scanf家族的原型
int scanf(char const *format,...);
int fscanf(FILE *stream,char const *format,...);
int sscanf(char const *buffer,char const *format,...);
每个原型中的省略号表示一个可变长度的指针列表。从输入转换而来的值逐个存储到这些指针指向的内存位置。由于C的参数传递都是传值调用决定了可变参数都是指针列表。注意:若给的不是指针,而是变量值。scanf将把变量值当做指针,在进行解引用时或者导致程序终止,或者导致不可预料的内存位置的数据被改写。
2、返回值
     当格式化字符串format到达末尾或者读取的输入不再匹配格式字符串所指定的类型时,输入就停止,并返回被转换的输入值的数目,若在任何输入都没被转换之前文件就到达尾部则返回EOF。
3、类型的匹配
     由于scanf是采用可变参数的机制,所以函数无法验证它们的指针参数是否为正确的类型,所以函数假定它们是正确的,(因此格式字符必须和后面的指针指向的类型保持一致)如果指针参数的类型和输入数据的类型不匹配则结果值就是垃圾。而且邻近的变量也有可能被改写。例如:
float a;
scanf("%d",&a);     //本来a是一个float数据,却用一个整形指针指向变量a。
4、scanf格式代码
format字符串中包括以下内容。
空白字符:他们与输入中的零个或多个空白字符匹配,在处理过程中将被忽略。(常用于%c中)
格式代码:他们指定函数如何解释接下来的输入字符。
其他字符:若出现其他字符时,下一个输入字符必须与之匹配。若匹配则该输入字符丢弃,若不匹配,函数不再读取,直接返回。
格式代码:以%开头,后面接:一个可选的星号;一个可选的宽度;一个可选的限定符;格式代码
     (1)星号:转换后的值被丢弃而不进行存储,跳过不需要的输入字符。
     (2)宽度:限制被读取用于转换的输入字符的个数。若未给出宽度,函数读入字符直到遇到空白字符。
     (3)限定符:修改有些格式代码的含义。注意转换所有的short、long、double、long double时都要加上限定符。若未加上将导致一个较长的变量只有一部分被初始化,一个较短的变量的邻近变量也被修改。这些取决于机器中类型的长度。
格式码\限定符 h l L
d,i,n short long  
o,u,x unsigned short unsigned long  
e,f,g   double long double
例如:short var_a;
scanf("%hd",&var_a);
     (4)格式码:单个字符,表示输入字符如何被解释,以及指针列表指针的指向类型。
代码 对应的指针参数类型 含义
c char * 读取和存储单个字符,前导的空白字符不跳过(可以在格式字符串中加入空格来跳过)。若给出宽度,就读取和存储这个数目的字符,后面不会添加NUL,必须保证足够大的数组空间
i
d
int * 有符号整数被转换。%d解释为十进制。%i根据第一个字符决定值的基数,和整型字符值常量的表示形式相同。10,034,0xa2
u
o
x
unsigned * 无符号整数被转换。u:十进制;o:八进制;x:十六进制
e
f
g
float * 期待一个浮点值。他的形式必须像一个浮点型字面值常量,但小数点并不必须
s char * 读取一串非空白字符,当发现空白时则输入停止。后面自动加上NUL。必须保证足够大的数组空间
n int * 处理字符的个数
5、用scanf实现行定向的输入。

由于scanf把回车也当做空白字符处理所以使用scanf保持行边界的同步时很困难的。为了实现行定向。可以搭配fgets。先用fgets读取一行,然后用sscanf对读取的行处理。
6、使用sscanf处理可变格式的输入。
     int a,b,c;

fgets(buf,20,stdin);


     char *p = strrchr(buf,'\n');


     *p = '\0';               //去除回车符


     if(sscanf(buf,"%d%d%d",&a,&b,&c) != 3)


     {


          a = 1;     //defalut value of a


          if(sscanf(buf,"%d%d",&b,&c) != 2)


          {


               b = 1;     //default value of b


               if(sscanf(buf,"%d",&c)!=1)


               {


                    printf("input error\n ");


                    exit(1);


               }


          }


     }


     printf("a = %d\nb=%d\nc=%d\n",a,b,c);

二、printf家族
1、原型
int printf(char const *format,...);
int fprintf(FILE *stream,char const *format,...);
int sprintf(char *buffer,char const *format,...);
2、类型匹配
printf函数和scanf一样,无法验证一个值是否具有格式码所表示的正确类型。所以保证他们相互匹配是程序员的责任。
3、printf格式码
format字符串包含格式码,它使参数列表的下一个值根据指定的方式进行格式化,对于其他的字符则原样输出。
格式码由一个%开头,后边可以跟:
标志字符、字段宽度、精度、修改符、#标志、格式码
(1)标志字符:
标志 含义
- 左对齐;默认右对齐
0 右对齐时,用0填充左边未使用的列;默认用空格填充
+ 当一个数为正数时,前面加上一个+号,默认不显示
空格 当一个数为正数时,前面加上一个空格,默认不显示
(2)字段宽度:指定输出的最小字符数,若输出的小于字段宽度。则根据标志字符进行相应的修改输出
(3)精度:
作用于%s:指定要被转换的最多字符数
作用于%f:指定出现在小数点后的数字位数
(4)修改符:
修改符 作用对象 表示类型
h d,i,o,u,x short型整数
l d,i,o,u,x long型整数
l e,f,g long double型数据
(5)格式代码
代码 参数 含义
c int 参数被裁剪为unsigned char类型并作为字符打印
d
i
int 作为一个十进制整数打印
o
u
x
unsigned int 参数作为一个无符号值打印,u使用十进制,o使用八进制,x使用十六进制
e、f、g double 参数按照浮点数打印,精度缺少为6位
s char * 打印一个字符串
n int * 打印字符的个数
(6)#标志

#标志可以作用于格式代码:o,x,e,f,g     也就是无符号数和浮点数
o:产生的值以0开头;x:以0x开头;(这两个很实用。)
e,f,g:确保结果始终包含一个小数点即使后面没有数字。

long double a = 3.14;
printf("a = %08.3lf",a);     //右对齐,开头补零,字符宽度8位,精度3位,以long double型输出。


三、利用sprintf和scanf实现字符串和数值的相互转换
利用sscanf可以实现字符串向数值的转换,而利用sprintf实现数值向字符串的转换
#include<stdio.h>

int main()

{

     float a = 3.14;

     double b;
     char buf[20];

sscanf("3.42","%lf",&b);          //将字符串转换为数值double

     sprintf(buf,"%.2f",a);               //将double型数值转换为字符串


     printf("b = %.2f\n",b);

     printf("buf is:%s\n",buf);

}
另外标准库提供的用于字符串转换为整型/浮点型的函数有:
int atoi(char const *string);
long int atol(char const *string);
long int strtol(char const *string,char **unused,int base);
long int strtoul(char const *string,char **unused,int base);

double atof(char const *string);
double strtod(char const *string,char **unused);
使用注意事项:
1、跳过前导空白字符,忽略非法缀尾字符
2、对于整型,当base=0时,根据string的字面确定string的进制。(八进制(以0开头)、十进制(默认)、十六进制(以0x开头));
3、若不能转换为相应类型则返回0
4、unused指向无法转换的字符的指针的指针。

四、通过sprintf获取一个整数的位数
通常对于一个整数data,我们需要获得其位数的方法为:对其与10、100、1000、等相除来确定共有多少位。
下面程序提供了一个获取data位数的一个好方法:
     int number,data;

     data = 12345;

     char buf[20];

     sprintf(buf,"%d%n",data,&number);          //利用snprintf防止访问内存越界:snprintf(buf,20,"%d%n",data,&number);

     printf("data is %d,has %d characters\n",data,number);
利用printf的%n格式符记录打印字符的个数来统计data的位数。







































scanf与printf用法详解的更多相关文章

  1. C语言printf用法详解

    #include <stdio.h> int main() { printf("%s","hello world1!\n");//%s字符标志可省略 ...

  2. golang格式化输出-fmt包用法详解

    golang格式化输出-fmt包用法详解 注意:我在这里给出golang查询关于包的使用的地址:https://godoc.org    声明: 此片文章并非原创,大多数内容都是来自:https:// ...

  3. C语言对文件的操作函数用法详解1

    在ANSIC中,对文件的操作分为两种方式,即: 流式文件操作 I/O文件操作 一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef str ...

  4. ZT --- extern "C"用法详解 2010-08-21 19:14:12

    extern "C"用法详解 2010-08-21 19:14:12 分类: C/C++ 1.前言: 时常在cpp的代码之中看到这样的代码: #ifdef __cplusplus ...

  5. 【转】 #define用法详解

    #define用法详解   1.#define 的作用 在C或C++语言源程序中允许用一个标识符来表示一个字符串,称为“宏”.被定义为“宏”的标识符称为“宏名”.在编译预处理时,对程序中所有出现的“宏 ...

  6. JS逗号运算符的用法详解

    逗号运算符的用法详解 注意: 一.由于目前正在功读JavaScript技术,所以这里拿JavaScript为例.你可以自己在PHP中试试. 二.JavaScript语法比较复杂,因此拿JavaScri ...

  7. C语言 sscanf用法详解

    /* sscanf用法详解 */ #include <stdio.h> /* sscanf头文件 */ #include <stdlib.h> #include <str ...

  8. C语言对文件的操作函数用法详解2

    fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const  ...

  9. memset用法详解

    原文:http://www.cnblogs.com/PegasusWang/archive/2013/01/20/2868824.html 1.void *memset(void *s,int c,s ...

随机推荐

  1. zoj 3471 Most Powerful(状态压缩dp)

    Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These ato ...

  2. 网络编程API-下 (I/O复用函数)

    IO复用是Linux中的IO模型之中的一个,IO复用就是进程预先告诉内核须要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理.从而不会在单个IO上堵塞了. Linu ...

  3. 【欧拉函数】【HDU1286】 找新朋友

    找新朋友 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  4. Model注解的后台原理

    Asp.net MVC的验证特性是由模型绑定器.模型元数据.模型验证器和模型状态组成的协调系统的一部分. 1.验证和模型绑定 默认情况下,Asp.net MVC框架在模型绑定石执行验证逻辑,在操作方法 ...

  5. Unity IOC注入详细配置(MVC,WebApi)

    一直想写一篇关于unity 详细的配置信息的文章,也算是自我总结吧 先介绍了unity , Unity是微软官方推荐使用的轻型的IOC框架,支持各种方式的注入 ,使用来解耦的利器. 获取unity 的 ...

  6. ios app相互调用

    被调用app配置 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NS ...

  7. ASP.NET,Razor语句中@符号的意义

    比较下面两段代码的区别: <td> @if (item.ModifyTime.HasValue) { @item.ModifyTime.GetValueOrDefault().ToStri ...

  8. JS 一个修改ul的小示例

    javascript提供了innerHTML属性可以获取和设置对象的文本内容. 下面实例演示——单击<ul>下的<li>标签后,改变其显示值: 1.HTML结构 <ul  ...

  9. My97DatePicker使用的问题

    我在iframe中使用My97DatePicker时,发现第一次点击左边的菜单时,在右边的页面可以弹出日期框: 当我第二次点击菜单时,右边的日期文本框却弹出了页面的内容,而不是日期选择框: 首先怀疑是 ...

  10. Android studio GPU Monitor :GPU Profiling needs to be enabled in the device's developer options

    Android studio GPU Monitor 在真机上不能使用,提示:GPU Profiling needs to be enabled in the device's developer o ...