1. 程式人生 > >C Primer Plus (第五版)中文版——第 4 章 字串和格式化輸入輸出

C Primer Plus (第五版)中文版——第 4 章 字串和格式化輸入輸出

4.1  前導程式

#include <stdio.h>
#include <string.h>		        /*提供strlen() 函式原型*/
#define PRAISE "You are my sunshine!!!"
int main(void)
{
	char name[20];		        /*name是一個有20個字元的陣列,用於儲存名字*/
	int age;		        /*年齡*/
	int letters;		        /*名字字元數*/
	
	printf("Hi! What\'s your name?\n");
	scanf_s("%s", name, 20);	/*使用者輸入名字*/
	printf("Well, %s, How old are you?\n",name);
	scanf_s("%d", &age);		/*使用者輸入年齡*/
	letters = strlen(name);		/*名字長度*/
	printf("%s,you are %d years old and your name have %d letters.\n", name, age, letters);
	printf("%s, %s\n", name, PRAISE);
	return 0;
}

該程式主要的新特性如下:

  • 使用一個數組(array)來存放一個字串。該陣列是記憶體中一串連續的20個位元組,其中每個位元組都可存放一個字元值
  • 使用了 %s 轉換說明符來處理字串的輸入和輸出,且在 scanf_s() 中,age 使用了 & 字首而 name沒有使用
  • 使用 C 函式 strlen() 函式來獲取字串的長度

4.2  字串簡介

字串(character string)是一個或多個字元的序列。如:

"Hello, Mr.Gold!"

雙引號不是字串的一部分,它們只是通知編譯器其中包含了一個字串。

4.2.1  char 陣列型別和空字元

C 將字串儲存在 char 陣列中,字串中的字元存放在相鄰的儲存單元中,每個字元佔用一個單位,每個單元是1個位元組;而陣列由相鄰儲存單元組成。C 的字串儲存時通常以空字元 \0 結束,因此陣列的單元數至少要比儲存的字元數多1。

char name[20];

name 後面的方括號說明它是一個數組,方括號內的數字20指出陣列中元素的數目,char 標識每個元素的型別。

4.2.2  使用字串

printf("%s, %s\n", name, PRAISE);

%s 告訴 printf() 函式要列印一個字串,%s 出現兩次是因為該程式要列印兩個字串:一個被儲存在 name 陣列中,另一個由PRAISE 來代表。

scanf_s("%s", name, 20);	/*使用者輸入名字*/

scanf_s() 開始讀取輸入以後,會在遇到的第一個空白字元(空格、製表符或換行)處停止讀取。

4.2.3  strlen() 函式

letters = strlen(name);		/*名字長度*/

 strlen() 函式以字元為單位給出字串的長度。

4.3  常量和 C 前處理器

①前處理器允許定義常量:

#define PI 3.14         /*PI 只是3.1415926的別名,在編譯期間用3.1415926去取代PI的值*/

4.3.1  const 修飾符

②使用 const 關鍵字把一個變數宣告轉換成常量宣告:

const int MONTH = 12;   /*將 MONTH 定義成變數,但告訴編譯器它的值是固定不變的。若在程式中試圖去修改其值,編譯時會報錯*/

 ③列舉功能定義符號常量:

enum Sex{MALE,FEMALE}   /*列舉常量,值是從0開始遞增,即 MALE=0,FEMALE=1*/

4.3.2  系統定義的明顯常量

C 標頭檔案 limits.h 和 float.h 分別提供有關整數型別和浮點型別的大小限制的詳細資訊。每個檔案定義了一系列明顯常量。

4.4  研究和利用 printf() 和 scanf()

printf() 和 scanf() 能夠實現使用者與程式的互動。它們被稱為 I/O 函式。

4.4.1  printf() 函式

請求 printf() 列印變數的指令取決於變數的型別。轉換說明符指定了如何把資料轉換成可顯示的形式。

4.4.2  使用 printf()

printf() 的使用格式:

printf(Control-string, item1, item2, ...);

控制字串(Control-string)是一個描述專案如何列印的字串。包含兩種形式的資訊:

  • 實際要列印的字元
  • 轉換說明

引數列表(item)使用變數名、常量和表示式。

printf() 的返回值是它所列印的字元的數目。

4.4.3  printf() 的轉換說明修飾符

4.4.5  使用 scanf()

scanf() 函式可以讀取各種格式的資料。同 printf() 一樣,scanf() 使用字串和引數列表。控制字串指出輸入將被轉換成的格式,引數列表使用指向變數的指標。scanf() 函式使用空白字元(空格、製表符或換行)來決定怎樣把輸入分成幾個欄位,它依次把轉換說明符與欄位匹配,並跳過它們之間的空白字元。唯一的例外是 %c,即使下一字元是空白字元,它也會讀取那個字元。

scanf() 的返回值是它所成功讀入的專案的個數。

4.4.6  printf() 和 scanf() 的 * 修飾符

printf() 的 * 修飾符:假定您不想事先指定欄位寬度,而是希望由程式來指定該值,那麼您可以在欄位寬度部分使用 * 代替數字來達到目的,同時您也必須使用一個引數來告訴程式欄位寬度應該是什麼。例如:

#include <stdio.h>
int main(void)
{
	unsigned width, precision;		/*宣告欄位寬度、精度*/
	double weight = 139.5;
	scanf_s("%d %d", &width, &precision);	/*指定欄位寬度、精度*/
	printf("weight = %*.*f\n", width, precision, weight);
	return 0;
}

scanf() 的 * 修飾符:將 * 放在 % 和說明符字母之間時,它使函式跳過相應的輸入專案。例如:

#include <stdio.h>
int main(void)
{
	int num;
	scanf_s("%*d %*d %d", &num);	/*跳過兩個整數,並把第三個整數賦給 num*/
	printf("num = %d\n", num);
	return 0;
}

4.8  程式設計練習