两种将字符串转换成浮点数的⽅法
⽅法⼀:
1. char szString[] = "-2876.99812376443";
2. double db1;
3. db1 = atof(szString);
4. printf("atof result:/n");
5. printf("%f %.12f %.2f %e %E/n", db1, db1, db1, db1, db1);
6. printf("%.1e %.1E %.18e %.18E/n", db1, db1, db1, db1);
⽅法⼆:
1. char szString2[] = "-2876.99812376443";
2. double db2;
3. sscanf(szString2, "%lf", &db2);
4. printf("/nsscanf result:/n");
5. printf("%f %.12f %.2f %e %E/n", db2, db2, db2, db2, db2);
6. printf("%.1e %.1E %.18e %.18E/n", db2, db2, db2, db2);
这两种⽅法可以得到⼀模⼀样的输出!输出如下:
atof result:
-2876.998124 -2876.998123764430 -2877.00 -2.876998e+003 -2.876998E+003
-2.9e+003 -2.9E+003 -2.876998123764430100e+003 -2.876998123764430100E+003
sscanf result:
-2876.998124 -2876.998123764430 -2877.00 -2.876998e+003 -2.876998E+003
-2.9e+003 -2.9E+003 -2.876998123764430100e+003 -2.876998123764430100E+003
很多⼈对sscanf家族的函数不太了解,我想把sscanf家族的函数具体⽤法写出来,希望⼤家可以共同进步,有什么不对的地⽅欢迎提出来。先瞄下该家族的⼀些函数原型:
// 从键盘输⼊数据到变量
1. int scanf(char *format,...);
// 从字符串输⼊数据到变量,如下相同
1. int sscanf(const char *buffer, const char *format, ... );
1. int _sscanf_l(const char *buffer, const char *format, locale_t locale, ... );
2. int swscanf(const wchar_t *buffer,const wchar_t *format, ... );
3. int _swscanf_l(const wchar_t *buffer,const wchar_t *format,locale_t locale, ... );
下⾯我们只看看标准形式的sscanf函数:
1. int sscanf(const char *buffer, const char *format, ... );
先说说关于它的返回值的问题,库函数⼏乎都是有返回值的,有些⼈可能很奇怪,怎么很少⼈⽤过sscanf的返回值呢?sscanf会返回成功接收到的变量数量的值。⽐如sscanf("3.14159","%f",&pi);返回值是1。
测试如下程序:
1. #include <stdio.h>
2.
3. int main ()
4. {
5. int a;
6. printf ("%d",scanf("%d/n",&a));
7. return 0;
8. }
9.
如果你开始就输⼊回车,程序会继续等待你输⼊,因为在输⼊数字的时候,scanf会跳过空⽩字符。the c programming language上
说,scanf实际上是⽤getchar()接受由数字组成的字符串,再转换成数字。如果我输⼊ctrl-z(unix上是ctrl-d)则会返回-1(随编译器⽽定).这实际上就是常量EOF的值,也就是所谓的返回eof。如果我键⼊的不是数字返回值就是0。但是如果我输⼊浮点数,⼜会怎么样呢?我举的例⼦中同样会返回1,但是缓冲区会留下垃圾,如果是scanf("%d%d",&a,&b);则会出错。这是可以使⽤⼀个库函数fflush(stdin)来清除缓冲。不过貌似⾬中飞燕⼤说这个⽤法是⾮标准的。K&R,只是说⾏为没有定义,但我们可以使⽤while((c=getchar())!='/n'&&c!=EOF);同样可以清除后⾯的垃圾scanf的格式匹配还是⽐较简单,⼀定要记住的就是普通变量⼀定要加上&,否则编译器⽆法检测错误,但运⾏肯定会段错误。
1. ┏━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
将数组格式的字符串转换成数组2. ┃代码│意义┃
3. ┠────┼────────────────────────────┨
4. ┃ %a │读浮点值(仅适⽤于 C99) ┃
5. ┃ %A │读浮点值(仅适⽤于 C99) ┃
6. ┃ %c │读单字符┃
7. ┃ %d │读⼗进制整数┃
8. ┃ %i │读⼗进制、⼋进制、⼗六进制整数┃
9. ┃ %e │读浮点数┃
10. ┃ %E │读浮点数┃
11. ┃ %f │读浮点数┃
12. ┃ %F │读浮点数(仅适⽤于 C99) ┃
13. ┃ %g │读浮点数┃
14. ┃ %G │读浮点数┃
15. ┃ %o │读⼋进制数┃
16. ┃ %s │读字符串┃
17. ┃ %x │读⼗六进制数┃
18. ┃ %X │读⼗六进制数┃
19. ┃ %p │读指针值┃
20. ┃ %n │⾄此已读⼊值的等价字符数┃
21. ┃ %u │读⽆符号⼗进制整数┃
22. ┃ %[ ] │扫描字符集合┃
23. ┃ %% │读 % 符号(百分号) ┃
24. ┗━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
前⾯都很简单,%p,%n很少⽤到,跳过。要输⼊%必须要在前⾯再加⼀个%,重点来谈谈%s和%[]。%s是读⼊⼀个数组,他与gets的区别就在于%s会以任何的空字符结束,⽽gets是回车结束。同样%s前可以加数字,表⽰只读多少个。ANSI C 标准向 scanf() 增加了⼀种新特性,称为扫描集(scanset)。扫描集
定义⼀个字符集合,可由 scanf() 读⼊其中允许的字符并赋给对应字符数组。扫描集合由⼀对⽅括号中的⼀串字符定义,左⽅括号前必须缀以百分号。例如,以下的扫描集使 scanf() 读⼊字符 A、B 和 C:
1. %[ABC]
使⽤扫描集时,scanf() 连续吃进集合中的字符并放⼊对应的字符数组,直到发现不在集合中的字符为⽌(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读⼊字符组成的字符串。对于许多实现来说,⽤连字符可以说明⼀个范围。例如,以下扫描集使 scanf() 接受字母 A 到 Z:
1. %[A-Z]
重要的是要注意扫描集是区分⼤⼩写的。因此,希望扫描⼤、⼩写字符时,应该分别说明⼤、⼩写字母。对于%[]还可以⽤^+任意字符(包括eof)来结束字符串的输⼊。⽐如%[^EOF]就是直到有EOF输⼊,字符串才中⽌。但⼀定要记住就是c语⾔是缓冲输⼊,即使你%[^a],再你输⼊回车之前输⼊多少的a都是不可能结束的。%s的输⼊会跳过空⽩字符,但是%c则不会。这也就是
1. scanf("%d", &h);
2. scanf("%c", &c);
如果这写的话,变量c放的⼀定是回车。如果想实现这种输⼊,可以在两个语句之间加⼊⼀个getchar(),他可以吃掉这个回车,也可⽤scanf("%d %c",&h,&c);来做,再输⼊数字后加⼀个空格。就可以了但千万别⽤scanf("%d/n", &h); K&R说的⼗分清楚,任何⾮格式化的字符都需要完全匹配。意味着,只有输⼊数字后⾯再加/n才是合法的。还有就是*加在任何项的前⾯表⽰该项不符值。
再看⼀例关于如何⽤sscanf来分析⽤逗号作为分解符的字符串,这在数据库查询结果操作中很常见,代码如下:
1. /* The following sample illustrates the use of brackets and the
2. caret (^) with sscanf().
3. Compile options needed: none
4. */
5.
6. #include <math.h>
7. #include <stdio.h>
8. #include <stdlib.h>
9.
10. char *tokenstring = "first,25.5,second,15";
11. int result, i;
12. double fp;
13. char o[10], f[10], s[10], t[10];
14.
15. void main()
16. {
17. result = sscanf(tokenstring, "%[^','],%[^','],%[^','],%s", o, s, t, f);
18. fp = atof(s);
19. i = atoi(f);
20. printf("%s/n %lf/n %s/n %d/n", o, fp, t, i);
21. }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论