首页 » C语言解惑 » C语言解惑全文在线阅读

《C语言解惑》8.3 对库函数的作用理解不对

关灯直达底部

【例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。  

结论:必须正确理解库函数的原型。