【例8.4】下面程序中將姓和名分別輸出在兩行,改正這個錯誤。
#include <stdio.h> #include <string.h> int main ( ) { char first_name[100] ; char last_name[100] ; char full_name[100] ; printf (\"First name : \" ); fgets (first_name ,sizeof (first_name ),stdin ); printf (\"Last name : \" ); fgets (last_name ,sizeof (last_name ),stdin ); strcpy (full_name , \" \" ); strcpy (full_name ,first_name ); strcat (full_name ,last_name ); printf (\"Full name : %s\" ,full_name ); return 0 ; }
【解答】下面是程序的運行示範:
First name : Wang Last name : Guoying Full_name : Wang Guoying
庫函數fgets在讀取字符時,會自動在尾部加入「n」。用strcat函數連接兩個字符串時,中間就多了一個換行符。解決的辦法就是將「n」換成空格。用strlen函數求出「n」的位置,這個位置的數組下標就是字符串長度-1。下面的程序將這個換行符換成空格。
#include <stdio.h> #include <string.h> int main ( ) { char first_name[100] ; char last_name[100] ; char full_name[100] ; int i=0 ; printf (\"First name : \" ); fgets (first_name ,sizeof (first_name ),stdin ); printf (\"Last name : \" ); fgets (last_name ,sizeof (last_name ),stdin ); strcpy (full_name , \" \" ); strcpy (full_name ,first_name ); i=strlen (first_name )-1 ; strcat (full_name ,last_name ); full_name[i]=\' \' ; printf (\"Full name : %s\" ,full_name ); return 0 ; }
運行示範如下:
First name : Wang Last name : Guoying Full_name : Wang Guoying
當然,也可以先處理換行符,即把換行符改為空格,然後再連接。
// 先處理換行符再連接字符串的程序 #include <stdio.h> #include <string.h> int main ( ) { char first_name[100] ; char last_name[100] ; char full_name[100] ; int i=0 ; printf (\"First name : \" ); fgets (first_name ,sizeof (first_name ),stdin ); printf (\"Last name : \" ); fgets (last_name ,sizeof (last_name ),stdin ); strcpy (full_name , \" \" ); strcpy (full_name ,first_name ); i=strlen (first_name )-1 ; full_name[i]=\' \' ; // 先處理換行符再連接字符串 strcat (full_name ,last_name ); printf (\"Full name : %s\" ,full_name ); return 0 ; }
【例8.5】分析下面程序中存在的錯誤。
#include <stdio.h> #include <string.h> int main ( void ) { char string[80] ; strcpy ( string , \"Hello world\0\" ); return 0 ; }
【解答】庫函數strcpy的原型為
char *strcpy ( char *strDestination , const char *strSource );
它將strSource指向的字符串(包含結束標誌)拷貝到strDestination指向的字符數組中。所以程序中多了結束符號「\0」。當然結果是一樣的,但說明程序編寫者對該函數的理解不夠。於此類似的還有strcat函數。它的函數原型為
char *strcat ( char *strDestination , const char *strSource );
它將strSource指向的字符串連接到strDestination指向的字符數組的後面,連接規則為:假定原來的數組有足夠的空間存儲連接後的字符串,被連接字符串覆蓋原字符串最後的空白終止符,用自己的結束符作為新字符串的結束符,例8.6說明了它的用法。
【例8.6】下面程序很簡單,雖然編譯給出錯誤信息,也能產生執行文件,但運行時出現錯誤。找出原因並修改運行程序。
#include <stdio.h> #include <string.h> const char PATH=\"d :/user/my\" ; char *full_name ( char ); int main ( ) { printf (\"Full name is : %sn\" ,full_name (\"data\" )); return 0 ; } char *full_name (const char name ) { char file_name[100] ; strcpy (file_name ,PATH ); strcat (file_name ,\'/\' ); strcat (file_name ,name ); return (file_name ); }
【解答】這個程序不長,問題也不少。const定義的是字符,但確賦給字符串。正確的是定義為
const char PATH=\"d :/user/my\" ;
雖然也可以使用如下的
#define PATH \"d :/user/my\"
宏定義方式,但推薦使用const。
函數聲明與定義不符合,定義使用const,聲明也必須相同。即
char *full_name (const char );
對庫函數strcat的使用不對,\'/\'是字符,strcat要求的是字符串。應改為
strcat (file_name ,\"/\" );
full_name函數里定義的普通字符數組file_name在結束運行時就失去作用,必須將它定義為靜態數組。下面是修改後的程序。
#include <stdio.h> #include <string.h> const char PATH=\"d :/user/my\" ; char *full_name (const char ); int main ( ) { printf (\"Full name is : %sn\" ,full_name (\"data\" )); return 0 ; } char *full_name (const char name ) { static char file_name[100] ; strcpy (file_name ,PATH ); strcat (file_name ,\"/\" ); strcat (file_name ,name ); return (file_name ); }
程序運行結果為
Full name is : d :/user/my/data
【例8.7】分析下面程序中存在的錯誤。
#include <stdio.h> #include <string.h> void main ( void ) { char string[80] ; char str2=\"strcat !\" ; strcpy ( string , \"Hello world from \" ); strcat ( string , \"strcpy \" ); strcat ( string , \"and \" ); strcat ( string , str2 ); printf (\" 字符串%s 的長度為%d 。n\" ,string ,strlen (string )+1 ); strcpy ( string , str2 ); printf (\" 字符串%s 的長度為%d 。n\" ,string ,strlen (string )+1 ); return ; }
【解答】strlen的函數原型為
size_t strlen ( const char *string );
size_t是unsigned integer,即strlen函數返回字串的長度(字符串的個數),這個長度不包含字符串的結束標誌\'\0\',也就是不是存儲字符串的長度。將兩個輸出語句中的「+1」去掉即可。例如:
printf (\" 字符串%s 的長度為%d 。n\" ,string ,strlen (string ));
修改後的運行結果如下。
字符串Hello world from strcpy and strcat !的長度為35 。 字符串strcat !的長度為7 。
結論:必須正確理解庫函數的原型。