C語言提供了兩個控制台格式化輸入、輸出函數printf() 函數 和scanf() 函數,這兩個函數可以在标準輸入輸出裝置上以各種不同的格式讀寫資料。printf()函數用來向标準輸出裝置(螢幕)寫資料; scanf() 函數用來從标準輸入裝置(鍵盤)上讀資料。
一、格式化輸出函數—printf()函數
printf()函數是格式化輸出函數,一般用于向标準輸出裝置按規定格式輸出資訊。在編寫程式時經常會用到此函數。printf()函數的調用格式為:
printf("<格式化字元串>", <參量表>);
其中格式化字元串包括兩部分内容:一部分是正常字元,這些字元将按原樣輸出;另一部分是格式化規定字元,以 “%”開始,後跟一個或幾個規定字元,用來确定輸出内容格式。參量表是需要輸出的一系列參數,其個數必須與格式化字元串所說明的輸出參數個數一樣多,各參數之間用 “,”分開, 且順序一一對應,否則将會出現意想不到的錯誤。
1、格式化規定符
特别注意: %0 和 %x 表示的都是 無符号的整形。
說明:
(1)、可以在“%”和字母之間插進數字表示最大場寬。例如: %9.2f 表示輸出場寬為9的浮點數,其中小數位為2,整數位為6,小數點占一位,不夠9位右對齊。%8s 表示輸出8個字元的字元串,不夠8個字元右對齊。
(2)、可以控制輸出左對齊或右對齊,即在“%”和字母之間加入一個“-”号可說明輸出為左對齊,否則預設為右對齊。例如:%-7d 表示輸出7位整數左對齊。
(3)、對于字元串的長度或整型數位數超過說明的場寬,将按其實際長度輸出。但對浮點數,若整數部分位數超過了說明的整數位寬度,将按實際整數位輸出;若小數部分位數超過了說明的小數位寬度,則按說明的寬度以四舍五入輸出。
(4)、若想在輸出值前加一些0,就應在場寬項前加個0。例如:%04d 表示在輸出一個小于4位的數值時,将在前面補0使其總寬度為4位。
(5)、如果用浮點數表示字元或整型量的輸出格式,小數點後的數字代表最大寬度,小數點前的數字代表最小寬度。例如:%6.9s 表示顯示一個長度不小于6且不大于9的字元串。若大于9,則第9個字元以後的内容将被删除。
(6)、可以在“%”和字母之間加小寫字母l, 表示輸出的是長型數。例如: %ld 表示輸出long整數%lf 表示輸出double浮點數。
2、一些特殊規定字元
例程:
#include <stdio.h>
#include <string.h>
int main()
{
char c, s[], *p;
int a=, b, *i = &b;
float f=;
double x=.;
p="How do you do";
strcpy(s,"Hello, Comrade");
*i=;
c='\x41';
printf("a=%d\n", a); /*結果輸出十進制整數a=1234*/
printf("a=%6d\n", a); /*結果輸出6位十進制數a= 1234*/
printf("a=%06d\n", a); /*結果輸出6位十進制數a=001234*/
printf("a=%2d\n", a); /*a超過2位, 按實際值輸出a=1234*/
printf("*i=%4d\n", *i); /*輸出4位十進制整數*i= 12*/
printf("*i=%-4d\n", *i);/*輸出左對齊4位十進制整數*i=12*/
printf("i=%p\n", i); /*輸出位址i=06E4*/
printf("f=%f\n", f); /*輸出浮點數f=3.141593*/
printf("f=6.4f\n", f); /*輸出6位其中小數點後4位的浮點數f=3.1416*/
printf("x=%lf\n", x); /*輸出長浮點數x=0.123457*/
printf("x=%18.16lf\n", x);/*輸出18位其中小數點後16位的長浮點數x=0.1234567898765432*/
printf("c=%c\n", c); /*輸出字元c=A*/
printf("c=%x\n", c); /*輸出字元的ASCII碼值c=41*/
printf("s[]=%s\n", s); /*輸出數組字元串s[]=Hello, Comrade*/
printf("s[]=%6.9s\n", s);/*輸出最多9個字元的字元串s[]=Hello, Co*/
printf("s=%p\n", s); /*輸出數組字元串首字元位址s=FFBE*/
printf("*p=%s\n", p); /* 輸出指針字元串p=How do you do*/
printf("p=%p\n", p); /*輸出指針的值p=0194*/
getch();
return ;
}
二、格式化輸入函數—scanf()函數
scanf()函數是格式化輸入函數,它從标準輸入裝置(鍵盤) 讀取輸入的資訊。其調用格式為:
scanf("<格式化字元串>", <位址表>);
格式化字元串包括以下三類不同的字元;
1、格式化說明符:格式化說明符與printf()函數中的格式說明符基本相同。
2、空白字元:空白字元會使scanf()函數在讀操作中略去輸入中的一個或多個空白字元。
3、非空白字元:一個非空白字元會使scanf()函數在讀入時剔除掉與這個非空白字元相同的字元。
位址表是需要讀入的所有變量的位址,而不是變量本身。這與printf()函數完全不同,要特别注意。各個變量的位址之間同“,”分開。
例 1:
int i,j;
scanf("%d, %d", &i, &j);
上例中的scanf()函數先讀一個整型數,然後把接着輸入的逗号剔除掉,最後讀入另一個整型數。如果“,”這一特定字元沒有找到,scanf()函數就終止。若參數之間的分隔符為空格,則參數之間必須輸入一個或多個空格。
幾點說明:
(1)、對于字元串數組或字元串指針變量,由于數組名和指針變量名本身就是位址,是以使用scanf()函數時,不需要在它們前面加上“&”操作符。
例2:
int main()
{
char *p, str[];
scanf("%s", p);//本就是位址,無需加&
scanf("%s", str);
printf("%s\n", p);
printf("%s\n", str);
}
(2)、可以在格式化字元串中的“%”各格式化規定符之間加入一個整數,表示任何讀操作中的最大位數。
如例2中若規定隻能輸入10字元給字元串指針p, 則第一條scanf() 函數語句變為:
scanf(“%10s”, p);
程式運作時一旦輸入字元個數大于10,p就不再繼續讀入,而後面的一個讀入函數即scanf(“%s”, str)就會從第11個字元開始讀入。實際使用scanf()函數時存在一個問題,下面舉例進行說明:
當使用多個scanf()函數連續給多個字元變量輸入時,例如:
例3:
int main()
{
char c1, c2;
scanf("%c", &c1);//注意是連續輸入字元變量char
scanf("%c", &c2);
printf("c1 is %c, c2 is %c", c2, c2);
}
運作該程式,輸入一個字元A後回車 (要完成輸入必須回車), 在執行scanf(“%c”, &c1)時, 給變量c1指派”A”, 但回車符仍然留在緩沖區内,執行輸入語句scanf(”%c”, &c2)時, 變量c2輸出的是一空行,如果輸入AB後回車, 那麼輸出結果為: c1 is A, c2 is B。要解決以上問題,可以在輸入函數前加入清除函數fflush(stdin)。修改以上程式變成:
#include<stdio.h>
int main()
{
char c1, c2;
scanf(“%c”, &c1);
fflush(stdin);
scanf(“%c”, &c2);
printf(“c1 is %c, c2 is %c”, c1, c2);
}
三、非格式化輸入輸出函數
非格式化輸入輸出函數可以由上面講述的标準格式化輸入輸出函數代替,但這些函數編譯後代碼少,相對占用記憶體也小,進而提高了速度,同時使用也比較友善。下面分别進行介紹。
1、 puts()函數
puts()函數用來向标準輸出裝置(螢幕)寫字元串并換行,其調用格式為:
puts()函數的作用與語printf(“%s\n”, s)相同。
例:
int main()
{
char s[], *f;
strcpy(s, "Hello! Turbo C2.0");
f="Thank you";
puts(s);
puts(f);
}
說明:
(1)、puts()函數隻能輸出字元串,不能輸出數值或進行格式變換。
(2)、可以将字元串直接寫入puts()函數中。如:puts(“Hello, Turbo C2.0”);
2、gets()函數
gets()函數用來從标準輸入裝置(鍵盤)讀取字元串直到回車結束,但回車符不屬于這個字元串。其調用格式為:
gets(s)函數與scanf(“%s”, &s)相似,但不完全相同,使用scanf(“%s”,&s)函數輸入字元串時存在一個問題,就是如果輸入了空格會認為輸入字元串結束,空格後的字元将作為下一個輸入項處理,但gets() 函數将接收輸入的整個字元串直到回車為止,gets()會吸收空格。
例:
int main()
{
char s[20], *f;
printf("What's your name?\n");
gets(s); /*等待輸入字元串直到回車結束*/
puts(s); /*将輸入的字元串輸出*/
puts("How old are you?");
gets(f);
puts(f);
}
說明:
gets(s)函數中的變量s為一字元串。如果為單個字元, 編譯連接配接不會有錯誤, 但運作後會出現”Null pointer asignmemt”的錯誤。
3、putchar()函數
putchar()函數是向标準輸出裝置輸出一個字元,其調用格式為:
putchar()函數的作用等同于printf(“%c”, ch);
例:
int main()
{
char c; /*定義字元變量*/
c='B'; /*給字元變量指派*/
putchar(c); /*輸出該字元*/
putchar('\x42'); /*輸出字母B*/
putchar(); /*直接用ASCII碼值輸出字母B*/
}
從本例中的連續四個字元輸出函數語句可以厘清字元變量的不同指派方法。
4、getchar()函數
getchar()函數也是從鍵盤上讀入一個字元,并回顯。它與前面函數的差別在于:getchar()函數等待輸入直到按回車才結束,回車前的所有輸入字元都會逐個顯示在螢幕上,但隻有第一個字元作為函數的傳回值。getchar()函數的調用格式為:
getchar();
例:
int main()
{
char c;
c=getchar(); /*從鍵盤讀入字元直到回車結束*/
putchar(c); /*顯示輸入的第一個字元*/
getch(); /*等待按任一健*/
}
5、getch()和getche()函數
這兩個函數都是從鍵盤上讀入一個字元。其調用格式為:
getch();
getche();
兩者的差別是:getch()函數不将讀入的字元回顯在顯示螢幕上,而getche()函數卻将讀入的字元回顯到顯示螢幕上。
例:
int main()
{
char c, ch;
c=getch(); /*從鍵盤上讀入一個字元不回顯送給字元變量c*/
putchar(c); /*輸出該字元*/
ch=getche(); /*從鍵盤上帶回顯的讀入一個字元送給字元變量ch*/
putchar(ch);
}
利用回顯和不回顯的特點,這兩個函數經常用于互動輸入的過程中完成暫停等功能。如下例子所示:
例:
int main()
{
char c, s[20];
printf("Name:");
gets(s);
printf("Press any key to confinue...");
getch(); /*等待輸入任一鍵,按鍵内容不會顯示*/
}