【例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 。
结论:必须正确理解库函数的原型。