- 程序設計基礎教程:C語言
- 常東超 劉培勝 郭來德等編著
- 4412字
- 2020-05-07 11:49:31
3.2 數據的輸入/輸出
在程序運行中,有時需要從外部設備(如鍵盤)得到一些原始數據,而程序計算結束后,需要把計算結果發送到外部設備(如顯示器)上。我們把從外部設備獲得原始數據稱為“輸入”,而把程序計算的結果發送到外部設備上稱為“輸出”。C語言沒有專門的輸入或輸出語句,但在C的標準庫函數中提供了常用的輸入和輸出函數。本節重點介紹字符輸入函數getchar()和輸出函數以及格式輸入函數scanf()和輸出函數printf()。
由于標準庫函數中所用到的變量定義和宏定義均在擴展名為.h的頭文件中描述,因此在需要使用標準I/O庫中的函數時,應在程序前使用下面的預編譯命令#include<stdio.h>或#include"stdio.h"將相應的.h頭文件包含到用戶程序中。
3.2.1 字符輸入/輸出函數
(1)字符輸出函數
一般形式為:
putchar(c);
該函數的作用是向終端(如顯示器)輸出一個字符。C可以是字符常量或變量、整型常量或變量、轉義字符。
【例3.2】 字符輸出舉例。
#include<stdio.h>
void main()
{ char a='A',b='B';
putchar(a);
putchar('A');
putchar(65);
putchar('\n');
putchar(b);
putchar('B');
putchar(66);
}
程序運行結果:
AAA
BBB
注意不能寫成以下形式:
putchar('AB');
putchar("A");
putchar("\n");
(2)字符輸入函數
一般形式為:
getchar();
該函數的作用是從終端(如鍵盤)輸入一個字符。
【例3.3】 字符輸入舉例。
#include<stdio.h>
void main()
{ char ch;
ch=getchar();
putchar(ch);
putchar('\n');
}
程序運行時,如果從鍵盤輸入A并按【Enter】鍵,則可看到屏幕上輸出字符A 。
程序運行結果:
A↙ /*↙代表回車*/
A
使用getchar()函數要注意以下幾個方面:
①getchar()函數的括號()內不允許有任何數據,但這一對圓括號不可少,這一點要和putchar()區別開來。
②使用本函數前必須包含文件"stdio.h"。
③getchar()函數只能接收一個字符,輸入的數字也按字符處理,而且輸入的空格、回車都將作為字符讀入,當輸入多個字符時也只能接收一個字符。因此,在用getchar()函數連續輸入兩個字符時要注意回車符和空格符。
例如:
char ch1,ch2;
ch1=getchar();
ch2=getchar();
當從鍵盤輸入:A12并按【Enter】鍵,則變量ch1的值是'A',變量 ch2的值是'1'。
當從鍵盤輸入:A 12并按【Enter】鍵,則變量ch1的值是'A',變量 ch2的值是空格符。
當從鍵盤輸入:A↙ /*↙并按【Enter】鍵*/
則變量ch1的值是'A',變量 ch2的值是'\n'。
④給getchar()函數輸入字符時不需加單引號,輸入字符后必須按【Enter】鍵,字符才能送到內存。
⑤getchar()函數得到的字符可以賦給一個字符型變量或整型變量,也可以不賦給任何變量,可作為表達式的一部分。
例如:
putchar(getchar());
3.2.2 格式輸入/輸出函數
putchar()和getchar()只能輸出或輸入一個字符,當程序需要輸出或輸入多個數據時,就需要使用格式輸出函數和格式輸入函數了。
(1)格式輸出函數
①printf("要輸出的字符序列")
注意:“要輸出的字符序列”必須用英文的雙引號括起來,它的作用是在屏幕上原樣輸出“要輸出的字符序列”。
例如:
printf("I love china!!!");
在屏幕上將看到:I love china!!!。
②printf("輸出格式控制符",輸出列表項)
注意:“輸出格式控制符”必須用英文的雙引號括起來,它的作用是按照輸出格式來輸出后面的輸出列表項的值。
例如:
int x=3,y=4,*px=&x,*py=&y;
printf("%d,%d",x,y);
或寫成:
printf("%d,%d",*px,*py);
在屏幕上將會看到:3,5。
語句printf("%d,%d",x,y);的作用是:以%d的格式輸出變量x的值,以%d的格式輸出變量y的值,中間以逗號分隔。
“輸出格式控制符”可以是:
①格式符:即由%和格式字符組成,如%d,%f等。
②普通字符:如printf("a=%d,b=%d\n",a,b);中的“a=”“,”“b=”都是普通字符,普通字符原樣輸出。
③轉義字符:如printf("a=%d,b=%d\n",a,b);中的“\n”。其含義是“換行”。
C語言中常用的格式字符共有9種,如表3.1所示。
表3.1 printf()的格式說明

在格式說明中,在%和上述格式字符之間還可以插入表3.2所示的幾種附加字符(又稱修飾符)。
表3.2 printf()的附加格式說明符

printf()函數常用的格式符如下:
①d格式符用來輸出十進制整數。有以下用法:
●d→以整數的實際位數輸出。
例如:
printf("%d",2009);
輸出結果為:
2009
●%+d→以整數的實際位數輸出,輸出時正整數前帶正號“+”。
例如:
printf("%+d",2009);
輸出結果為:
+2009
●%md→輸出的整數占m列并右對齊。當m大于整數的寬度時,多余的位用空格填充;當m小于整數的寬度時,按整數的實際位數輸出。
例如:
printf("%8d",2009);
輸出結果為:
2009
●%-md→輸出的整數占m列并左對齊。當m大于整數的寬度時,多余的位用空格填充;當m小于整數的寬度時,按整數的實際位數輸出。
例如:
printf("%8d\n%-8d",2009,2009);
輸出結果為:
2009
2009
輸出格式字符串“%8d\n%-8d”的含義是:先輸出一個整型數據,占8個字符寬,右對齊,換行后,輸出第二個整型數據,也占8個字符寬,左對齊。
●%ld或%Ld→輸出長整型數據,按實際位數輸出。
●%hd→輸出短整型數據,按實際位數輸出。
●%mld或%mLd→輸出長整型數據占m列并右對齊。當m大于整數的寬度時,多余的位用空格填充;當m小于整數的寬度時,按整數的實際位數輸出。
●%-mld或%-mLd→輸出長整型數據占m列并左對齊。當m大于整數的寬度時,多余的位用空格填充;當m小于整數的寬度時,按整數的實際位數輸出。
例如:
long x=123456;
printf("%8ld\n%-8ld",x,x);
輸出結果為:
123456
123456
●%0md→輸出的整數占m列并右對齊。當m大于整數的寬度時,多余的位用0填充;當m小于整數的寬度時,按整數的實際位數輸出。
例如:
printf("%8d",2009);
輸出結果為:
00002009
注意:沒有%-0md格式控制符。
②o格式符用來輸出八進制整數,其用法同d格式符,用時把d格式符改為o格式符即可。
例如:
short int n=-1;
printf("%ho",n);
輸出結果為:
177777
可以看到,八進制形式輸出的整數是不考慮符號的。
③x或X格式符用來輸出十六進制數,其用法同d格式符,用時把d格式符改為x或X格式符即可。
例如:
short int n=-1;
printf("%hx ",n);
printf("%hX",n);
輸出結果為:
ffff FFFF
可以看到,十六進制形式輸出的整數也是不考慮符號的。
④u格式符用來輸出無符號型的十進制整數,其用法同d格式符,用時把d格式符改為u格式符即可。
例如:
short int n=-1;
printf("%hd,%hu ",n,n);
輸出結果為:
-1,65535
從有符號的角度看,它表示的是-1;從無符號數的角度看,它表示的是65535。
⑤c格式符用來輸出一個字符。有以下用法:
●%c→輸出一個字符。
●%mc→輸出的字符占m列并右對齊,多余的位用空格填充。
●%-mc→輸出的字符占m列并左對齊,多余的位用空格填充。
例如:
printf("%4c\n%-4c",'A','A');
輸出結果為:
A
A
⑥s格式符用來輸出一個字符串。有以下用法:
●%s→以字符串的實際長度輸出一個字符串。
printf("%s","china");
輸出結果為:
china
●%ms→輸出的字符串占m列并右對齊。當m大于字符串的實際長度時,多余的位用空格填充;當m小于字符串的實際長度時,按字符串的實際長度輸出。
●%-ms→輸出的字符串占m列并左對齊。當m大于字符串的實際長度時,多余的位用空格填充;當m小于字符串的實際長度時,按字符串的實際長度輸出。
例如:
printf("%8s\n%-8s","china","china");
輸出結果為:
china
china
●%m.ns→在m列的位置上輸出一個字符串的前n個字符,并右對齊。m>n時,多余的位數用空格填充;m<n時,輸出實際長度的字符串。
●%-m.ns→在m列的位置上輸出一個字符串的前n個字符,并左對齊。m>n時,多余的位數用空格填充;m<n時,輸出實際長度的字符串。
例如:
printf("%8.2s\n%-8.2s","china","china");
輸出結果為:
ch
ch
⑦f格式符用來輸出實數(包括單精度、雙精度),以小數形式輸出。有以下用法:
●%f→用于輸出單精度小數,也可輸出雙精度小數,輸出時實數的整數部分全部輸出,小數部分保留6位,在有效數據范圍內的小數部分要進行四舍五入。
例如:
printf("%f",12.123456789);
輸出結果為:
12.123457
●%lf或%Lf→用于輸出雙精度小數,輸出時實數的整數部分全部輸出,小數部分保留6位,在有效數據范圍內的小數部分要進行四舍五入。
例如:
double x=12.123456789;
printf("%lf",x);
或寫成:
printf("%f",x);
輸出結果為:
12.123457
●%m.nf→在m列的位置上輸出一個實數保留n位小數,并右對齊,系統自動對在有效數據范圍內的小數部分進行四舍五入。當m大于實數總寬度時,多余的位數用空格填充;當m小于實數總寬度時,實數的整數部分按實際寬度輸出。
●%-m.nf→在m列的位置上輸出一個實數保留n位小數,并左對齊,系統自動對在有效數據范圍內的小數部分進行四舍五入。當m大于實數總寬度時,多余的位數用空格填充;當m小于實數總寬度時,實數的整數部分按實際寬度輸出。
例如:
printf("%8.2f\n%-8.2f",12.123456789,12.123456789);
輸出結果為:
12.12
12.12
●%.nf→實數的整數部分按實際寬度輸出,保留n位小數,系統自動對在有效數據范圍內的小數部分進行四舍五入。
例如:
printf("%.2f",12.123456789);
輸出結果為:
12.12
⑧e格式符用來以指數形式輸出一個實數,用法同f格式符,用時把f格式符換成e格式符即可。
例如:
printf("%e",12.123456789);
輸出結果為:
1.212346e+001
⑨g格式符用來輸出實數,系統根據實數的大小,自動選f格式符或e格式符輸出,輸出時選擇占寬度較小的一種格式輸出,且不輸出無意義的0。
【例3.4】 輸出函數應用舉例。
#include<stdio.h>
void main()
{ int a=27;
char ch='A';
float b=12.3456;
double c=234.123456;
printf("%4d%-4o%4x\n",a,a,a);
printf("%-4c%4c\n",ch,ch);
printf("b=%10.2f,b=%-10.2f\n",b,b);
printf("b=%10.2e,b=%-10.2e\n",b,b);
printf("c=%lf,c=%10.2lf\n",c,c);
printf("%s,%5.2s","Hello!!!","Hello!!!");
}
程序運行結果是:
2733 1b
A A
b= 12.35,b=12.35
b=1.23e+001,b=1.23e+001
c=234.123456,c= 234.12
Hello!!!, HePress any key to continue
使用printf()函數要注意以下幾個方面:
①數據類型應與格式說明符匹配,否則將會出現錯誤。
②int型數據也可以用%u格式輸出;反之,一個unsigned型數據也可以用%d、%o、%x格式輸出。
例如:
short int a=-1;
unsigned short b=65534;
printf("%hu,%hd\n",a,b);
程序運行結果是:
65535,-2
③除了X、E、G、L可以大寫外,其他格式符必須小寫,如%f不能寫成%F。
④如果需要輸出“%”,則應在格式符內連續使用兩個%。例如:
printf("%5.2f%%",1/3.0*100)
輸出結果為:
33.33%
(2)格式輸入函數
格式輸入函數scanf()用于從鍵盤輸入數據,該輸入數據按指定的輸入格式賦給相應的輸入項。
其一般格式為:
scanf("輸入格式控制符",輸入項地址表列);
注意:“輸入格式控制符”必須用英文的雙引號括起來,它的作用是按照輸入格式從鍵盤輸入若干類型的數據給后面的輸入項。
例如:
int a,b;
scanf("a=%d,b=%d",&a,&b); /*&a和 &b分別表示變量a和b的地址*/
運行時從鍵盤輸入:a=3,b=5按【Enter】鍵,則變量a和b的值分別是3和5。
“輸入格式控制符”可以是:
①格式符:即由%和格式字符組成,如%d,%f等。
②普通字符:如scanf("a=%d,b=%d\n",a,b);中的“a=”“,”“b=”都是普通字符,輸入時要照原樣輸入。
表3.3列出了scanf()函數常用的格式字符。
表3.3 scanf()函數常用的格式字符

在格式說明中,在%和上述格式字符之間還可以插入表3.4所示的幾種附加格式字符(又稱修飾符)。
表3.4 scanf()的附加格式字符

使用scanf()函數要注意以下幾個方面:
①地址表列要用地址運算符“&”取變量的地址或用指針變量。例如:
int a,b,*pa=&a,*pb=&b;
scanf("%d%d",&a,&b);
或寫成:
scanf("%d%d",pa,pb);
&a、&b、pa、pb表示把輸入的數據送到系統為變量a和b分配的內存中。下面的寫法是錯誤的。
scanf("%d%d",a,b);
或寫成:
scanf("%d%d",*pa,*pb);
②“輸入格式控制符”中的普通字符一定要照原樣輸入。例如:
scanf("a=%d,b=%d",&a,&b);
輸入時一定要把普通字符“a=”“,”“b=”照原樣輸入,否則會出現數據讀入錯誤。
正確的輸入格式是:a=3,b=5按【Enter】鍵。
如果“輸入格式控制符”中沒有普通字符,則輸入時應以一個或多個空格、【Tab】 鍵或【Enter】鍵來分隔。例如:
scanf("%d%d",&a,&b);
正確的輸入格式是:3 5↙
3 5↙
3↙
5↙
“↙”代表【Enter】鍵。
③可以指定輸入數據的寬度,系統會自動按它截取所需的數據。例如:
int a;
float b;
scanf("%2d%3f",&a,&b);
輸入:123456↙
系統自動把12賦給a,把345.0賦給變量b。此方法也可用于字符型數據。例如:
scanf("%2c%3c",&c1,&c2);
輸入:abcdefg↙
由于字符型變量只能存放一個字符,因此,系統將'a'賦給c1,'c'賦給c2。
④需要連續輸入多個字符時,字符之間不用分隔,而且空格、回車等均作為有效字符輸入,例如:
scanf("%c%c",&c1,&c2);
輸入:AB↙
系統把字符'A'賦給c1,把字符'B'賦給c2。
輸入:A B↙
系統把字符'A'賦給c1,把空格符賦給c2。
⑤如果%后面有一個'*',則表示本項輸入不賦給任何變量。例如:
scanf("%d,%*d,%d",&a,&b);
輸入:12,34,56↙
系統將12賦給a,56賦給b。
⑥輸入數據時不能規定精度。例如:
scanf("%6.2f",&a);
上述與輸入語句是不合法的。
⑦輸入double型數據時,一定要在f、e之前加字母l或L。例如:
double a;
scanf("%lf",&a);
⑧%d、%c、%f在一起進行混合輸入時,要注意輸入的格式。例如:
scanf("%d%c%f",&x,&y,&z);
輸入:12A23.6↙
系統把12賦給x,把字符'A'賦給y,把23.6賦給z。
輸入:12 A 23.6↙
系統把12賦給x,把空格符賦給y,z的值為隨機數。
⑨輸入數據時,遇到以下情況認為數據輸入結束。
●到空格、回車或【Tab】鍵。
●指定的寬度結束。如“%2d”,只取2位。
●遇到非法輸入。例如:
scanf("%d",&a);
輸入:123Q↙
系統只將123賦給a。