天天看點

C語言程式設計.5.字元串和格式化輸入輸出

作者:西虹傑出青年

同樣以一個簡單程式開始:

#include <stdio.h>

#include <string.h>// 提供strlen()函數的原型

#define DENSITY 62.4// 人體密度(機關: 磅/立方英尺)

int main()

{

float weight, volume;

int size, letters;

char name[40]; // name是一個可容納40個字元的數組

printf("Hi! What's your first name?\n");

scanf("%s", name);

printf("%s, what's your weight in pounds?\n", name);

scanf("%f", &weight);

size = sizeof name;

letters = strlen(name);

volume = weight / DENSITY;

printf("Well, %s, your volume is %2.2f cubic feet.\n",

name, volume);

printf("Also, your first name has %d letters,\n",

letters);

printf("and we have %d bytes to store it.\n", size);

return 0;

}

運作talkback.c程式, 輸入結果如下:

Christine

Christine, what's your weight in pounds?

154

Well, Christine, your volume is 2.47 cubic feet.

Also, your first name has 9 letters,

and we have 40 bytes to store it

該程式包含以下新特性:使用數組來存儲字元串。在程式中,使用者輸入的名稱将被存儲在一個數組中,該數組占用40個連續的位元組記憶體空間,每個位元組儲存一個字元值。

用C函數strlen()擷取字元串的長度。

一、字元串使用

#include <stdio.h>

#define PRAISE "You are an extraordinary being."

int main(void)

{

char name[40];

printf("What's your name? ");

scanf("%s", name);

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

return 0;

}

%s告訴printf()列印一個字元串。 %s出現了兩次, 因為程式要列印兩個字元串: 一個儲存在name數組中; 一個由PRAISE來表示。 運作praise1.c,其輸出如下所示:

What's your name? Angela Plains

Hello, Angela.You are an extraordinary being.

注意(這很重要) , scanf()隻讀取了Angela Plains中的Angela, 它在遇到第1個空白(空格、 制表符或換行符) 時就不再讀取輸入。 是以, scanf()在讀到Angela和Plains之間的空格時就停止了。 一般而言, 根據%s轉換說明, scanf()隻會讀取字元串中的一個單詞, 而不是一整句。 C語言還有其他的輸入函數(如, fgets()) , 用于讀取一般字元串。 後面将再介紹這些函數。

二、strlen()函數

#include <stdio.h>

#include <string.h> /* 提供strlen()函數的原型 */

#define PRAISE "You are an extraordinary being."

int main(void)

{

char name[40];

printf("What's your name? ");

scanf("%s", name);

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

printf("Your name of %zd letters occupies %zd memory cells.\n",

strlen(name), sizeof name);

printf("The phrase of praise has %zd letters ",

strlen(PRAISE));

printf("and occupies %zd memory cells.\n", sizeof PRAISE);

return 0;

}

#include <string.h>:string.h頭檔案包含多個與字元串相關的函數原型, 包括strlen()。

一般而言, C 把函數庫中相關的函數歸為一類, 并為每類函數提供一個頭檔案。 例如, printf()和scanf()都隸屬标準輸入和輸出函數, 使用stdio.h頭檔案。 string.h頭檔案中包含了strlen()函數和其他一些與字元串相關的函數 。

運作該程式, 其互動輸出如下:

What's your name? Serendipity Chance

Hello, Serendipity.You are an extraordinary being.

Your name of 11 letters occupies 40 memory cells.

The phrase of praise has 31 letters and occupies 32 memory cells.

三、#define指令

如何建立符号常量? 方法之一是聲明一個變量, 然後将該變量設定為所需的常量。 可以這樣寫:

float taxrate;

taxrate = 0.015;

這樣做提供了一個符号名, 但是taxrate是一個變量, 程式可能會無意間改變它的值。 C語言還提供了一個更好的方案——C預處理器。預處理器也可用來定義常量。 隻需在程式頂部添加下面一行:

#define TAXRATE 0.015

編譯程式時, 程式中所有的TAXRATE都會被替換成0.015。 這一過程被稱為編譯時替換 。

四、const限定符

聲明如下:

const int MONTHS = 12; // MONTHS在程式中不可更改, 值為12

這使得MONTHS成為一個隻讀值。 const用起來比#define更靈活。

五、使用scanf()函數

C庫中包含多個輸入函數,其中最通用的是scanf(),因為它可以讀取不同格式的資料。從鍵盤輸入的内容都是文本,因為鍵盤隻能生成文本字元,包括字母、數字和标點符号。比如要輸入整數2014,就需要逐個鍵入字元’2’、‘0’、‘1’、‘4’。如果我們想将這些字元作為數值而不是字元串存儲起來,程式就必須将這些字元逐個轉換為對應的數值,而這正是scanf()函數所做的工作。scanf()函數可以将輸入的字元串轉換為整數、浮點數、字元或字元串。

#include <stdio.h>

int main(void)

{

intage; // 變量

float assets; // 變量

char pet[30]; // 字元數組, 用于儲存字元串

printf("Enter your age, assets, and favorite pet.\n");

scanf("%d %f", &age, &assets); // 這裡要使用&

scanf("%s", pet); // 字元數組不使用&

printf("%d $%.2f %s\n", age, assets, pet);

return 0;

}

下面是該程式與使用者互動的示例:

Enter your age, assets, and favorite pet.

38

92360.88 llama

38 $92360.88 llama

浮點轉換說明要求scanf()識别小數點、 e記數法(指數記數法) 和新增的p記數法(十六進制指數記數法) 。

除了%c, 其他轉換說明都會自動跳過待輸入值前面所有的空白。 是以, scanf("%d%d", &n, &m)與scanf("%d %d", &n, &m)的行為相同。 對于%c, 在格式字元串中添加一個空格字元會有所不同。 例如, 如果把%c放在格式字元串中的空格前面, scanf()便會跳過空格, 從第1個非空白字元開始讀取。 也就是說, scanf("%c", &ch)從輸入中的第1個字元開始讀取, 而scanf(" %c", &ch)則從第1個非空白字元開始讀取。

scanf()函數傳回成功讀取的項數。 如果沒有讀取任何項, 且需要讀取一個數字而使用者卻輸入一個非數值字元串, scanf()便傳回0。 當scanf()檢測到“檔案結尾”時, 會傳回EOF(EOF是stdio.h中定義的特殊值, 通常用#define指令把EOF定義為-1) 。

繼續閱讀