sscanf函数的用法 fscandf 读取一次指针会后移么

1643人阅读
C/C++(4)
1.格式化输出
int printf(const char *restrict format, ...);
int fprintf(FILE *restrict fp, const char *restrict format, ...);
int dprintf(int fd, const char *restrict format, ...);
int sprintf(char *restrict buf, const char *restrict format, ...);
int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
printf 将格式化数据写到标准输出,fprintf 写至指定流,dprintf 写至指定文件描述符。
sprintf 将格式化字符写入数组 buf。sprintf 在该数组的尾端自动加入一个 null 字节,但该字符不包括在返回值中。sprintf 函数可能会造成由 buf 指向的缓冲区的溢出。调用者有责任确保该缓冲区足够大。缓冲区溢出会造成程序不稳定甚至安全隐患,为解决这种缓冲区溢出问题,引入 snprintf 函数。
snprintf 函数中,缓冲区长度是一个显式参数,超过缓冲区尾端写的所有字符都被丢弃。如果缓冲区足够大,snprintf 会返回写入缓冲区的字符数,该值不包括尾端的 null 字节。若 snprintf 函数返回小于缓冲区长度的正值,则没有截断输出;若返回负值,则说明出现编码错误。
格式说明控制其余参数如何编写,以及如何显示。每个参数按照转换说明编写,转换说明以百分号%开始。一个转换说明有4个可选部分:
%[flag][fldwidth][precision][lenmodifier]convtype
(撇号)将整数按千位分组字符
在字段内左对齐输出
总是显示带符号转换的正负号
如果第一个字符不是正负号,则在其前加入一个空格
指定另一种转换形式
添加前导0(而非空格)进行填充
fldwidth:说明最小字段宽度
precision:说明整型转换后最少输出数字位数、浮点数转换后小数点后最少位数、字符串转换后最大字节数。精度为一个点(.),其后跟随一个可选非负十进制数或星号(*)。
convtype:
有符号十进制
无符号八进制
无符号十进制
无符号十六进制
双精度浮点数
指数格式双精度浮点数
根据转换后的值解释为 f、F、e、E
十六进制指数格式双精度浮点数
指向 void 的指针
到目前为止,此printf调用输出的字符数目将被写入到指针所指向的带符号整型中
一个 % 字符
sprintf 是较常用的输出函数之一,用法如下:
a. 格式化数字字符串
sprintf最常见的应用之一莫过于把整数打印到字符串中,所以,spritnf在大多数场合可以替代itoa。如:
sprintf(s, "%d", 123);
sprintf(s, "%8d%8d", 123, 4567);
sprintf(s, "%-8d%8d", 123, 4567);
sprintf(s, "%8x", 4567);
sprintf(s, "%-8X", 4568);
b. 控制浮点数打印格式,默认保留小数点后6位
sprintf(s, "%f", 3.1415926);
// "3.141593"
但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m.nf” 格式,其中m表示打印的宽度,n表示小数点后的位数。比如:
sprintf(s, "%10.3f", 3.1415626);
sprintf(s, "%-10.3f", 3.1415626);
sprintf(s, "%.3f", 3.1415626);
// "3.142"
对于如下代码:
int i = 123;
sprintf(s, "%.3f", i);
其结果是什么? “0.000”。。
原因是参数压栈时调用者并不知道跟 i 相对应的格式控制符是个”%f”。而函数执行时函数本身则并不知道当年被压入栈里的是个整数,于是保存整数 i 的那4个字节就被强行作为浮点数格式来解释了,导致出错了
sprintf(s, "%.3f", (float)i);
c.利用sprintf的返回值
例如,下面代码生成10个[0,100)的随机数,并输出到数组中,以逗号隔开:
#include &stdio.h&
#include &time.h&
#include &stdlib.h&
int main() {
srand(time(0));
char s[64];
int offset = 0;
for (int i = 0; i & 10; i++) {
offset += sprintf(s + offset, "%d,", rand() % 100);
s[offset - 1] = '\n';
printf(s);
2.格式化输入
int scanf(const char *restrict format, ...);
int fscanf(FILE *restrict fp, const char *restrict format, ...);
int sscanf(const char *restrict buf, const char *restrict format, ...);
scanf 族函数用于分析输入字符串,并将字符序列转换成指定类型的变量。在格式之后的各参数包含了变量的地址,用转换结果对这些变量赋值。
格式说明控制如何转换参数,以便对它们赋值。转换说明以百分号 % 开始,除转换说明和空白字符外,格式字符串中其他字符必须与输入匹配,若有一个字符不匹配,则停止后续处理,不再读输入的其他部分。
一个转换说明有 3 个如下的可选择的部分:
% [*][fldwidth][m][lenmodifier]convtype
其中,可选择的星号(*)用于抑制转换。按照转换说明的其余部分对输入进行转换,但转换结果并不存放在参数中。
fldwidth 说明最大宽度(即最大字符数),lenmodifier 说明要用转换结果赋值的参数大小。
convtype 字段类似于printf 族的转换类型字段,但两者之间还有些差别。一个差别是作为一种选项,输入中带符号的可赋予无符号类型。
在字段宽度和长度修饰符之间的可选项m 是赋值分配符,它可以用于%c、%s 以及 %[ 转换符,迫使内存缓冲区分配空间以接纳转换字符串。在这种情况下,相关参数必须是指针地址,分配的缓冲区地址必须复制给该指针。如果调用成功,该缓冲区不再使用时,由该调用者负责通过调用 free 函数来释放缓冲区。
有符号十进制,基数为10
有符号十进制,基数由输入格式决定
无符号八进制(输入可选地有符号)
无符号十进制,基数为10(输入可选地有符号)
无符号十六进制(输入可选地有符号)
a、A、e、E、f、F、g、G
字符(若带长度修饰符l,为宽字符)
字符串(若带长度修饰符l,为宽字符串)
匹配列出的字符序列,以 ] 终止
匹配除列出字符以外的所有字符,以 ] 终止
指向 void 的指针
到目前为止,此printf调用输出的字符数目将被写入到指针所指向的带符号整型中
一个 % 字符
sscanf 与scanf 类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。其中的format可以是一个或多个:
{%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号}
1.* 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)
2.{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
3.width表示读取宽度。
4.{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
5.type :%s,%d之类。
6.特别的:%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值
支持集合操作:
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB'] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,贪婪性
sscanf 用法:
a. 常见用法
char buf[512];
sscanf("123456 ", "%s", buf);
printf("%s\n", buf);
b. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
sscanf("123456 ", "%4s", buf);
printf("%s\n", buf);
c. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
sscanf("123456 abcdedf", "%[^ ]", buf);
printf("%s\n", buf);
// "123456"
d.取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
printf("%s\n", buf);
char s[] = "abcdef ";
char buf[512];
sscanf(s, "%[a-z0-9, ,:]", buf);
e.取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
printf("%s\n", buf);
// "123456abcdedf"
f.给定一个字符串”iios/12DDWDFF@122”,获取 / 和 @ 之间的字符串,先将 “iios/”过滤掉,再将非’@’的一串内容送到buf中
sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
printf("%s\n", buf);
// "12DDWDFF"
g.给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)
sscanf(“hello, world”, "%*s%s", buf); //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了,如果没有空格则结果为NULL。
printf("%s\n", buf);
// "world"
h.提取字符串中的各个数字到各变量中
sscanf("", "%d:%d:%d", a, b, c);
// a=2016, b=4, c=21
char sztime1[16] = "", sztime2[16] = "";
sscanf(" - ", "%s - %s", sztime1, sztime2);
如果读取的字符串,不是以空格来分隔的话,就可以使用%[]。 %[]类似于一个正则表达式。[a-z]表示读取a-z的所有字符,[^a-z]表示读取除a-z以外的所有字符。 上述写法也可换作:  
("2006:03:18
2006:04:18", "%[0-9,:]
%[0-9,:]", , );
sscanf 的功能很类似于正则表达式,但却没有正则表达式强大,所以如果对于比较复杂的字符串处理,建议使用正则表达式。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:13144次
排名:千里之外
原创:20篇
(1)(5)(4)(1)(2)(5)(3)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'sscanf()用法详细介绍_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
sscanf()用法详细介绍
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩1页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢  sscanf() - 从一个字符串中读进与指定格式相符的数据.
  函数原型:
  Int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
  int scanf( const char *format [,argument]... );
  说明:
  sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
  其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号}
  1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)
  2、{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
  3、width表示读取宽度。
  4、{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
  5、type :这就很多了,就是%s,%d之类。
  6、特别的:%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值
  支持集合操作:
  %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
  %[aB'] 匹配a、B、'中一员,贪婪性
  %[^a] 匹配非a的任意字符,贪婪性
  1. 常见用法。
  char buf[512] = ;
  sscanf("123456 ", "%s", buf);
  printf("%s\n", buf);
  结果为:123456
  2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
  sscanf("123456 ", "%4s", buf);
  printf("%s\n", buf);
  结果为:1234
  3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
  sscanf("123456 abcdedf", "%[^ ]", buf);
  printf("%s\n", buf);
  结果为:123456
  4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
  sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
  printf("%s\n", buf);
  结果为:123456abcdedf
  5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
  sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
  printf("%s\n", buf);
  结果为:123456abcdedf
  6、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中
  sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
  printf("%s\n", buf);
  结果为:12DDWDFF
  7、给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)
  sscanf(“hello, world”, "%*s%s", buf);
  printf("%s\n", buf);
  结果为:world
  %*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
  如果没有空格则结果为NULL。
  sscanf的功能很类似于正则表达式, 但却没有正则表达式强大,所以如果对于比较复杂的字符串处理,建议使用正则表达式.
  //-------------------------------------------------------
  sscanf,表示从字符串中格式化输入
  上面表示从str中,输入数字给x,就是32700
  久以前,我以为c没有自己的split string函数,后来我发现了sscanf;一直以来,我以为sscanf只能以空格来界定字符串,现在我发现我错了。
  sscanf是一个运行时函数,原形很简单:
  int sscanf(
  const char *buffer,
  const char *format [,
  argument ] ...
  它强大的功能体现在对format的支持上。
  我以前用它来分隔类似这样的字符串:
  int a, b,
  sscanf("", "%d:%d:%d", a, b, c);
  以及 - :
  char sztime1[16] = "", sztime2[16] = "";
  sscanf(" - ", "%s - %s", sztime1, sztime2);
  但是后来,我需要处理-
  仅仅是取消了‘-’两边的空格,却打破了%s对字符串的界定。
  我需要重新设计一个函数来处理这样的情况?这并不复杂,但是,为了使所有的代码都有统一的风格,我需要改动很多地方,把已有的sscanf替换成我自己的分割函数。我以为我肯定需要这样做,并伴随着对sscanf的强烈不满而入睡;一觉醒来,发现其实不必。
  format-type中有%[]这样的type field。如果读取的字符串,不是以空格来分隔的话,就可以使用%[]。
  %[]类似于一个正则表达式。[a-z]表示读取a-z的所有字符,[^a-z]表示读取除a-z以外的所有字符。
  所以那个问题也就迎刃而解了:
  sscanf(" - ", "%[0-9,:] - %[0-9,:]", sztime1, sztime2);
  在softmse (Jake) 的问题贴http://community.csdn.net/Expert/topic/.xml?temp=.4321558中 ,周星星给出了一个很cool的sscanf用例,而后通过学习,发现sscanf真棒,现做一总结。
scanf 原型:
# include &stdio.h&;
int scanf( const char *format, ... );
& & 函数 scanf() 是从标准输入流 stdin 中读内容的通用子程序,可以读入全部固有类型的数据并自动转换成机内形式。scanf() 是 printf() 的补函数。
& & 在 C99 中,format 用 restrict 修饰。
& & format 指向的控制串由以下三类字符组成:
& && & ● 格式说明符
& && & ● 空白符
& && & ● 非空白符
& & 输入格式说明符前缀为百分号(%),告诉 scanf() 下次读入何种数据类型。这些格式说明符的清单如下表所示:
& & ┏━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
& & ┃ 代&&码 │& && && && & 意& && && && && && && && &&&义& && && && & ┃
& & ┠────┼────────────────────────────┨
& & ┃& &%a& &│读浮点值(仅适用于 C99)& && && && && && && && && && && & ┃
& & ┃& &%A& &│读浮点值(仅适用于 C99)& && && && && && && && && && && & ┃
& & ┃& &%c& &│读单字符& && && && && && && && && && && && && && && && &┃
& & ┃& &%d& &│读十进制整数& && && && && && && && && && && && && && &&&┃
& & ┃& &%i& &│读十进制、八进制、十六进制整数& && && && && && && && &&&┃
& & ┃& &%e& &│读浮点数& && && && && && && && && && && && && && && && &┃
& & ┃& &%E& &│读浮点数& && && && && && && && && && && && && && && && &┃
& & ┃& &%f& &│读浮点数& && && && && && && && && && && && && && && && &┃
& & ┃& &%F& &│读浮点数(仅适用于 C99)& && && && && && && && && && && & ┃
& & ┃& &%g& &│读浮点数& && && && && && && && && && && && && && && && &┃
& & ┃& &%G& &│读浮点数& && && && && && && && && && && && && && && && &┃
& & ┃& &%o& &│读八进制数& && && && && && && && && && && && && && && & ┃
& & ┃& &%s& &│读字符串& && && && && && && && && && && && && && && && &┃
& & ┃& &%x& &│读十六进制数& && && && && && && && && && && && && && &&&┃
& & ┃& &%X& &│读十六进制数& && && && && && && && && && && && && && &&&┃
& & ┃& &%p& &│读指针值& && && && && && && && && && && && && && && && &┃
& & ┃& &%n& &│至此已读入值的等价字符数& && && && && && && && && && &&&┃
& & ┃& &%u& &│读无符号十进制整数& && && && && && && && && && && && &&&┃
& & ┃&&%[ ]&&│扫描字符集合& && && && && && && && && && && && && && &&&┃
& & ┃& &%%& &│读 % 符号(百分号)& && && && && && && && && && && && && &┃
& & ┗━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
& & 例如: %s 表示读串而 %d 表示读整数。格式串的处理顺序为从左到右,格式说明符逐一与变元表中的变元匹配。为了读取长整数,可以将 l(ell) 放在格式说明符的前面;为了读取短整数,可以将 h 放在格式说明符的前面。这些修饰符可以与 d、i、o、u 和 x 格式代码一起使用。
& & 默认情况下,a、f、e 和 g 告诉 scanf() 为 float 分配数据。 如果将 l(ell) 放在这些修饰符的前面,则 scanf() 为 double 分配数据。使用 L 就是告诉 scanf(),接收数据的变量是 long double 型变量。
& & 如果使用的现代编译器程序支持 1995 年增加的宽字符特性, 则可以与 c 格式代码一起,用 l 修饰符说明类型 wchar_t 的宽字符指针;也可以与 s 格式代码一起,用 l 修饰符说明宽字符串的指针。l 修饰符也可以用于修饰扫描集,以说明宽字符。
& & 控制串中的空白符使 scanf() 在输入流中跳过一个或多个空白行。空白符可以是空格(space)、制表符(tab)和新行符(newline)。 本质上,控制串中的空白符使 scanf() 在输入流中读,但不保存结果,直到发现非空白字符为止。
& & 非空白符使 scanf() 在流中读一个匹配的字符并忽略之。例如,"%d,%d" 使 scanf() 先读入一个整数,读入中放弃逗号,然后读另一个整数。如未发现匹配,scanf() 返回。
& & scanf() 中用于保存读入值的变元必须都是变量指针,即相应变量的地址。
& & 在输入流中,数据项必须由空格、制表符和新行符分割。逗号和分号等不是分隔符,比如以下代码:
& & scanf( "%d %d", &r, &c );
将接受输入 10 20,但遇到 10,20 则失败。
& & 百分号(%)与格式符之间的星号(*)表示读指定类型的数据但不保存。因此,
& & scanf( "%d %*c %d", &x, &y );
对 10/20 的读入操作中,10 放入变量 x,20 放入 y。
& & 格式命令可以说明最大域宽。 在百分号(%)与格式码之间的整数用于限制从对应域读入的最大字符数。例如,希望向 address 读入不多于 20 个字符时,可以书写成如下形式:
& & scanf( "%20s", address );
& & 如果输入流的内容多于 20 个字符,则下次 scanf() 从此次停止处开始读入。 若达到最大域宽前已遇到空白符,则对该域的读立即停止;此时,scanf() 跳到下一个域。
& & 虽然空格、制表符和新行符都用做域分割符号,但读单字符操作中却按一般字符处理。例如,对输入流 "x y" 调用:
& & scanf( "%c%c%c", &a, &b, &c );
返回后,x 在变量 a 中,空格在变量 b 中,y 在变量 c 中。
& & 注意,控制串中的其它字符,包括空格、制表符和新行符,都用于从输入流中匹配并放弃字符,被匹配的字符都放弃。例如,给定输入流 "10t20",调用:
& & scanf( "%dt%d", &x, &y );
将把 10 和 20 分别放到 x 和 y 中,t 被放弃,因为 t 在控制串中。
& & ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf() 读入字符 A、B 和 C:
& & %[ABC]
& & 使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入字符组成的字符串。
& & 用字符 ^ 可以说明补集。把 ^ 字符放为扫描集的第一字符时,构成其它字符组成的命令的补集合,指示 scanf() 只接受未说明的其它字符。
& & 对于许多实现来说,用连字符可以说明一个范围。 例如,以下扫描集使 scanf() 接受字母 A 到 Z:
& & %[A-Z]
& & 重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写字符时,应该分别说明大、小写字母。
& & scanf() 返回等于成功赋值的域数的值,但由于星号修饰符而读入未赋值的域不计算在内。给第一个域赋值前已出错时,返回 EOF。
& & C99 为 scanf() 增加了几个格式修饰符:hh、ll、j、z 和 t。hh 修饰符可用于 d、i、o、u、x、X 或 n。它说明相应的变元是 signed 或 unsigned char 值,或用于 n 时, 相应的变元是指向 long char 型变量的指针。ll 修饰符也可用于 d、i、o、u、x、X 或 n。它说明相应的变元是 signed 或者 unsigned long long int 值。
& & j 格式修饰符应用于 d、i、o、u、x、X 或 n,说明匹配的变元是类型 intmax_t 或 uintmax_t。这些类型在 &stdint.h&; 中声明,并说明最大宽度的整数。
& & z 格式修饰符应用于 d、i、o、u、x、X 或 n,说明匹配的变元是指向 size_t 类型对象的指针。该类型在 &stddef.h&; 中声明,并说明 sizeof 的结构。
& & t 格式修饰符应用于 d、i、o、u、x、X 或 n,说明匹配的变元是指向 ptrdiff_t&&类型对象的指针。该类型在 &stddef.h&; 中声明,并说明两个指针之间的差别。
# include &stdio.h&;
int main( void )
& & char str[80], str2[80];
& & /* read a string and a integer */
& & scanf( "%s%d", str, &i );
& & /* read up to 79 chars into str */
& & scanf( "%79s", str );
& & /* skip the integer between the two strings */
& & scanf( "%s%*d%s", str, str2 );
& & return 0;
阅读(...) 评论()

我要回帖

更多关于 sscanf函数实现 的文章

 

随机推荐