引用
茫然 的 兩種將字符串轉換成浮點數的方法
方法一:
char szString[] = "-2876.99812376443";
double db1;
db1 = atof(szString);
printf("atof result:\n");
printf("%f %.12f %.2f %e %E\n", db1, db1, db1, db1, db1);
printf("%.1e %.1E %.18e %.18E\n", db1, db1, db1, db1);
方法二:
char szString2[] = "-2876.99812376443";
double db2;
sscanf(szString2, "%lf", &db2);
printf("\nsscanf result:\n");
printf("%f %.12f %.2f %e %E\n", db2, db2, db2, db2, db2);
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家族的函數具體用法寫出來,考試.大希望大家可以共同進步,有什么不對的地方歡迎提出來。先瞄下該家族的一些函數原型:
// 從鍵盤輸入數據到變量
int scanf(char *format,...);
// 從字符串輸入數據到變量,如下相同
int sscanf(const char *buffer, const char *format, ... );
int _sscanf_l(const char *buffer, const char *format, locale_t locale, ... );
int swscanf(const wchar_t *buffer,const wchar_t *format, ... );
int _swscanf_l(const wchar_t *buffer,const wchar_t *format,locale_t locale, ... );
下面我們只看看標准形式的sscanf函數:
int sscanf(const char *buffer, const char *format, ... );
先說說關於它的返回值的問題,庫函數幾乎都是有返回值的,有些人可能很奇怪,怎么很少人用過sscanf的返回值呢?sscanf會返回成功接收到的變量數量的值。比如sscanf("3.14159","%f",&pi);返回值是1。
測試如下程序:
#include <stdio.h>
int main ()
{
int a;
printf ("%d",scanf("%d\n",&a));
return 0;
}
如果你開始就輸入回車,程序會繼續等待你輸入,因為在輸入數字的時候,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的格式匹配還是比較簡單,一定要記住的就是普通變量一定要加上&,否則編譯器無法檢測錯誤,但運行肯定會段錯誤。
代碼及意義
%a讀浮點值(僅適用於 C99)
%A讀浮點值(僅適用於 C99)
%c 讀單字符
%d 讀十進制整數
%i 讀十進制、八進制、十六進制整數
%e 讀浮點數
%E 讀浮點數
%f 讀浮點數
%F 讀浮點數(僅適用於 C99)
%g 讀浮點數
%G 讀浮點數
%o 讀八進制數
%s 讀字符串
%x 讀十六進制數
%X 讀十六進制數
%p 讀指針值
%n 至此已讀入值的等價字符數
%u 讀無符號十進制整數
%[ ] 掃描字符集合
%%讀 % 符號(百分號)
前面都很簡單,%p,%n很少用到,跳過。要輸入%必須要在前面再加一個%,重點來談談%s和%[]。%s是讀入一個數組,他與gets的區別就在於%s會以任何的空字符結束,而gets是回車結束。同樣%s前可以加數字,表示只讀多少個。ANSI C 標准向 scanf() 增加了一種新特性,稱為掃描集(scanset)。 掃描集定義一個字符集合,可由 scanf() 讀入其中允許的字符並賦給對應字符數組。 掃描集合由一對方括號中的一串字符定義,左方括號前必須綴以百分號。 例如,以下的掃描集使 scanf() 讀入字符 A、B 和 C:
%[ABC]
使用掃描集時,scanf() 連續吃進集合中的字符並放入對應的字符數組,直到發現不在集合中的字符為止(即掃描集僅讀匹配的字符)。返回時,數組中放置以 null 結尾、由讀入字符組成的字符串。對於許多實現來說,用連字符可以說明一個范圍。 例如,以下掃描集使 scanf() 接受字母 A 到 Z:
%[A-Z]
重要的是要注意掃描集是區分大小寫的。因此,希望掃描大、小寫字符時,應該分別說明大、小寫字母。對於%[]還可以用^+任意字符(包括eof)來結束字符串的輸入。比如%[^EOF]就是直到有EOF輸入,字符串才中止。但一定要記住就是c語言是緩沖輸入,即使你%[^a],再你輸入回車之前輸入多少的a都是不可能結束的。%s的輸入會跳過空白字符,但是%c則不會。這也就是
scanf("%d", &h);
scanf("%c", &c);
如果這寫的話,變量c放的一定是回車。如果想實現這種輸入,可以在兩個語句之間加入一個getchar(),他可以吃掉這個回車,也可用scanf("%d %c",&h,&c);來做,再輸入數字后加一個空格。就可以了但千萬別用scanf("%d\n", &h); K&R說的十分清楚,任何非格式化的字符都需要完全匹配。意味着,只有輸入數字后面再加\n才是合法的。還有就是*加在任何項的前面表示該項不符值。