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